From: Chris Lattner Date: Sat, 26 Jun 2010 20:27:24 +0000 (+0000) Subject: implement rdar://7432000 - signed negate should codegen as NSW. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e70ffd631179c15d358838464425e3464cf05a98;p=clang implement rdar://7432000 - signed negate should codegen as NSW. While I'm in there, adjust pointer to member adjustments as well. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106955 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index a46105e196..4372279175 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -997,13 +997,13 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { std::swap(DerivedDecl, BaseDecl); if (llvm::Constant *Adj = - CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, - CE->getBasePath())) { + CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, CE->getBasePath())){ if (CE->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer) - Src = Builder.CreateSub(Src, Adj, "adj"); + Src = Builder.CreateNSWSub(Src, Adj, "adj"); else - Src = Builder.CreateAdd(Src, Adj, "adj"); + Src = Builder.CreateNSWAdd(Src, Adj, "adj"); } + return Src; } @@ -1117,6 +1117,11 @@ Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { Value *Op = Visit(E->getSubExpr()); if (Op->getType()->isFPOrFPVectorTy()) return Builder.CreateFNeg(Op, "neg"); + + // Signed integer overflow is undefined behavior. + if (E->getType()->isSignedIntegerType()) + return Builder.CreateNSWNeg(Op, "neg"); + return Builder.CreateNeg(Op, "neg"); } diff --git a/test/CodeGen/builtins-ppc-altivec.c b/test/CodeGen/builtins-ppc-altivec.c index b40cf5bed6..1ffb05905a 100644 --- a/test/CodeGen/builtins-ppc-altivec.c +++ b/test/CodeGen/builtins-ppc-altivec.c @@ -43,13 +43,13 @@ int main () int res_i; /* vec_abs */ - vsc = vec_abs(vsc); // CHECK: sub <16 x i8> zeroinitializer + vsc = vec_abs(vsc); // CHECK: sub nsw <16 x i8> zeroinitializer // CHECK: @llvm.ppc.altivec.vmaxsb - vs = vec_abs(vs); // CHECK: sub <8 x i16> zeroinitializer + vs = vec_abs(vs); // CHECK: sub nsw <8 x i16> zeroinitializer // CHECK: @llvm.ppc.altivec.vmaxsh - vi = vec_abs(vi); // CHECK: sub <4 x i32> zeroinitializer + vi = vec_abs(vi); // CHECK: sub nsw <4 x i32> zeroinitializer // CHECK: @llvm.ppc.altivec.vmaxsw vf = vec_abs(vf); // CHECK: and <4 x i32> diff --git a/test/CodeGen/exprs.c b/test/CodeGen/exprs.c index d82cbf48d3..a90ae58dc3 100644 --- a/test/CodeGen/exprs.c +++ b/test/CodeGen/exprs.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s // PR1895 // sizeof function @@ -119,3 +119,16 @@ void f9(struct S *x) { void f10() { __builtin_sin(0); } + +// Tests for signed integer overflow stuff. +// rdar://7432000 +void f11() { + // CHECK: define void @f11 + extern volatile int f11G, a, b; + // CHECK: add nsw i32 + f11G = a + b; + // CHECK: sub nsw i32 + f11G = a - b; + // CHECK: sub nsw i32 0, + f11G = -a; +} diff --git a/test/CodeGenCXX/pointers-to-data-members.cpp b/test/CodeGenCXX/pointers-to-data-members.cpp index e527c72d49..70308c6abc 100644 --- a/test/CodeGenCXX/pointers-to-data-members.cpp +++ b/test/CodeGenCXX/pointers-to-data-members.cpp @@ -68,11 +68,11 @@ void f() { // CHECK: store i64 -1, i64* @_ZN5Casts2paE pa = 0; - // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 4 + // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add nsw i64 {{.*}}, 4 // CHECK: store i64 [[ADJ]], i64* @_ZN5Casts2pcE pc = pa; - // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub i64 {{.*}}, 4 + // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub nsw i64 {{.*}}, 4 // CHECK: store i64 [[ADJ]], i64* @_ZN5Casts2paE pa = static_cast(pc); }