[cfe-commits] r126718 - in /cfe/trunk: include/clang/Basic/LangOptions.h lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprScalar.cpp test/CodeGen/integer-overflow.c

Chris Lattner sabre at nondot.org
Mon Feb 28 16:03:49 PST 2011


Author: lattner
Date: Mon Feb 28 18:03:48 2011
New Revision: 126718

URL: http://llvm.org/viewvc/llvm-project?rev=126718&view=rev
Log:
-fwrapv should turn off the inbounds markers from geps used for pointer
arithmetic.  This is part of PR9256, it would be great if someone else
wired up -fno-strict-overflow in the driver to -fwrapv.

Modified:
    cfe/trunk/include/clang/Basic/LangOptions.h
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/test/CodeGen/integer-overflow.c

Modified: cfe/trunk/include/clang/Basic/LangOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.h?rev=126718&r1=126717&r2=126718&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.h (original)
+++ cfe/trunk/include/clang/Basic/LangOptions.h Mon Feb 28 18:03:48 2011
@@ -239,6 +239,10 @@
   void setSignedOverflowBehavior(SignedOverflowBehaviorTy V) {
     SignedOverflowBehavior = (unsigned)V;
   }
+
+  bool isSignedOverflowDefined() const {
+    return getSignedOverflowBehavior() == SOB_Defined;
+  }
 };
 
 /// Floating point control options

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=126718&r1=126717&r2=126718&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Feb 28 18:03:48 2011
@@ -1425,7 +1425,10 @@
     llvm::Value *Base = EmitScalarExpr(E->getBase());
 
     Address = EmitCastToVoidPtr(Base);
-    Address = Builder.CreateInBoundsGEP(Address, Idx, "arrayidx");
+    if (getContext().getLangOptions().isSignedOverflowDefined())
+      Address = Builder.CreateGEP(Address, Idx, "arrayidx");
+    else
+      Address = Builder.CreateInBoundsGEP(Address, Idx, "arrayidx");
     Address = Builder.CreateBitCast(Address, Base->getType());
   } else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){
     // Indexing over an interface, as in "NSString *P; P[4];"
@@ -1451,11 +1454,17 @@
     llvm::Value *Zero = llvm::ConstantInt::get(Int32Ty, 0);
     llvm::Value *Args[] = { Zero, Idx };
     
-    Address = Builder.CreateInBoundsGEP(ArrayPtr, Args, Args+2, "arrayidx");
+    if (getContext().getLangOptions().isSignedOverflowDefined())
+      Address = Builder.CreateGEP(ArrayPtr, Args, Args+2, "arrayidx");
+    else
+      Address = Builder.CreateInBoundsGEP(ArrayPtr, Args, Args+2, "arrayidx");
   } else {
     // The base must be a pointer, which is not an aggregate.  Emit it.
     llvm::Value *Base = EmitScalarExpr(E->getBase());
-    Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx");
+    if (getContext().getLangOptions().isSignedOverflowDefined())
+      Address = Builder.CreateGEP(Base, Idx, "arrayidx");
+    else
+      Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx");
   }
 
   QualType T = E->getBase()->getType()->getPointeeType();

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=126718&r1=126717&r2=126718&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Mon Feb 28 18:03:48 2011
@@ -1295,7 +1295,10 @@
         CGF.GetVLASize(CGF.getContext().getAsVariableArrayType(type));
       value = CGF.EmitCastToVoidPtr(value);
       if (!isInc) vlaSize = Builder.CreateNSWNeg(vlaSize, "vla.negsize");
-      value = Builder.CreateInBoundsGEP(value, vlaSize, "vla.inc");
+      if (CGF.getContext().getLangOptions().isSignedOverflowDefined())
+        value = Builder.CreateGEP(value, vlaSize, "vla.inc");
+      else
+        value = Builder.CreateInBoundsGEP(value, vlaSize, "vla.inc");
       value = Builder.CreateBitCast(value, input->getType());
     
     // Arithmetic on function pointers (!) is just +-1.
@@ -1303,13 +1306,19 @@
       llvm::Value *amt = llvm::ConstantInt::get(CGF.Int32Ty, amount);
 
       value = CGF.EmitCastToVoidPtr(value);
-      value = Builder.CreateInBoundsGEP(value, amt, "incdec.funcptr");
+      if (CGF.getContext().getLangOptions().isSignedOverflowDefined())
+        value = Builder.CreateGEP(value, amt, "incdec.funcptr");
+      else
+        value = Builder.CreateInBoundsGEP(value, amt, "incdec.funcptr");
       value = Builder.CreateBitCast(value, input->getType());
 
     // For everything else, we can just do a simple increment.
     } else {
       llvm::Value *amt = llvm::ConstantInt::get(CGF.Int32Ty, amount);
-      value = Builder.CreateInBoundsGEP(value, amt, "incdec.ptr");
+      if (CGF.getContext().getLangOptions().isSignedOverflowDefined())
+        value = Builder.CreateGEP(value, amt, "incdec.ptr");
+      else
+        value = Builder.CreateInBoundsGEP(value, amt, "incdec.ptr");
     }
 
   // Vector increment/decrement.
@@ -1357,7 +1366,10 @@
     llvm::Value *sizeValue =
       llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity());
 
-    value = Builder.CreateInBoundsGEP(value, sizeValue, "incdec.objptr");
+    if (CGF.getContext().getLangOptions().isSignedOverflowDefined())
+      value = Builder.CreateGEP(value, sizeValue, "incdec.objptr");
+    else
+      value = Builder.CreateInBoundsGEP(value, sizeValue, "incdec.objptr");
     value = Builder.CreateBitCast(value, input->getType());
   }
   
@@ -1889,6 +1901,8 @@
     return Builder.CreateBitCast(Res, Ptr->getType());
   }
 
+  if (CGF.getContext().getLangOptions().isSignedOverflowDefined())
+    return Builder.CreateGEP(Ptr, Idx, "add.ptr");
   return Builder.CreateInBoundsGEP(Ptr, Idx, "add.ptr");
 }
 
@@ -1964,38 +1978,39 @@
       return Builder.CreateBitCast(Res, Ops.LHS->getType());
     }
 
+    if (CGF.getContext().getLangOptions().isSignedOverflowDefined())
+      return Builder.CreateGEP(Ops.LHS, Idx, "sub.ptr");
     return Builder.CreateInBoundsGEP(Ops.LHS, Idx, "sub.ptr");
-  } else {
-    // pointer - pointer
-    Value *LHS = Ops.LHS;
-    Value *RHS = Ops.RHS;
+  }
+  
+  // pointer - pointer
+  Value *LHS = Ops.LHS;
+  Value *RHS = Ops.RHS;
 
-    CharUnits ElementSize;
+  CharUnits ElementSize;
 
-    // Handle GCC extension for pointer arithmetic on void* and function pointer
-    // types.
-    if (LHSElementType->isVoidType() || LHSElementType->isFunctionType()) {
-      ElementSize = CharUnits::One();
-    } else {
-      ElementSize = CGF.getContext().getTypeSizeInChars(LHSElementType);
-    }
+  // Handle GCC extension for pointer arithmetic on void* and function pointer
+  // types.
+  if (LHSElementType->isVoidType() || LHSElementType->isFunctionType())
+    ElementSize = CharUnits::One();
+  else
+    ElementSize = CGF.getContext().getTypeSizeInChars(LHSElementType);
 
-    const llvm::Type *ResultType = ConvertType(Ops.Ty);
-    LHS = Builder.CreatePtrToInt(LHS, ResultType, "sub.ptr.lhs.cast");
-    RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
-    Value *BytesBetween = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
-
-    // Optimize out the shift for element size of 1.
-    if (ElementSize.isOne())
-      return BytesBetween;
-
-    // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since
-    // pointer difference in C is only defined in the case where both operands
-    // are pointing to elements of an array.
-    Value *BytesPerElt = 
-        llvm::ConstantInt::get(ResultType, ElementSize.getQuantity());
-    return Builder.CreateExactSDiv(BytesBetween, BytesPerElt, "sub.ptr.div");
-  }
+  const llvm::Type *ResultType = ConvertType(Ops.Ty);
+  LHS = Builder.CreatePtrToInt(LHS, ResultType, "sub.ptr.lhs.cast");
+  RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
+  Value *BytesBetween = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
+
+  // Optimize out the shift for element size of 1.
+  if (ElementSize.isOne())
+    return BytesBetween;
+
+  // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since
+  // pointer difference in C is only defined in the case where both operands
+  // are pointing to elements of an array.
+  Value *BytesPerElt = 
+      llvm::ConstantInt::get(ResultType, ElementSize.getQuantity());
+  return Builder.CreateExactSDiv(BytesBetween, BytesPerElt, "sub.ptr.div");
 }
 
 Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {

Modified: cfe/trunk/test/CodeGen/integer-overflow.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/integer-overflow.c?rev=126718&r1=126717&r2=126718&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/integer-overflow.c (original)
+++ cfe/trunk/test/CodeGen/integer-overflow.c Mon Feb 28 18:03:48 2011
@@ -49,4 +49,12 @@
   // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 -1)
   // TRAPV_HANDLER: foo(
   --a;
+  
+  
+  // -fwrapv should turn off inbounds for GEP's, PR9256
+  extern int* P;
+  ++P;
+  // DEFAULT: getelementptr inbounds i32*
+  // WRAPV: getelementptr i32*
+  // TRAPV: getelementptr inbounds i32*
 }





More information about the cfe-commits mailing list