]> granicus.if.org Git - clang/commitdiff
implement rdar://7432000 - signed negate should codegen as NSW.
authorChris Lattner <sabre@nondot.org>
Sat, 26 Jun 2010 20:27:24 +0000 (20:27 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 26 Jun 2010 20:27:24 +0000 (20:27 +0000)
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

lib/CodeGen/CGExprScalar.cpp
test/CodeGen/builtins-ppc-altivec.c
test/CodeGen/exprs.c
test/CodeGenCXX/pointers-to-data-members.cpp

index a46105e19684713834e9a47128e87b130f39cbe7..4372279175e6705cadd3163eaf315947b8a33681 100644 (file)
@@ -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");
 }
 
index b40cf5bed600f6a7143fd5f95a4cd9f733fbba06..1ffb05905afcfb4d042cfcedf2b8ac5c5f83e484 100644 (file)
@@ -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>
index d82cbf48d30a19eb26966f14ffbdb3d09e98618f..a90ae58dc3f7faf8e0eafacc5b202a1ea05f81b4 100644 (file)
@@ -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;
+}
index e527c72d49573b3d82fd2b22f15806ffb7cf2ed0..70308c6abc5f9bd2219aaa007e2aee420e3e6550 100644 (file)
@@ -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<int A::*>(pc);
 }