[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