Hi rsmith,
Make sure signed overflow in "x--" is checked with
llvm.ssub.with.overflow intrinsic and is reported as:
"-2147483648 - 1 cannot be represented in type 'int'"
instead of:
"-2147483648 + -1 cannot be represented in type 'int'"
, like we do for unsigned overflow.
http://reviews.llvm.org/D8236
Files:
lib/CodeGen/CGExprScalar.cpp
test/CodeGen/integer-overflow.c
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -349,10 +349,9 @@
return EmitScalarPrePostIncDec(E, LV, true, true);
}
- llvm::Value *EmitAddConsiderOverflowBehavior(const UnaryOperator *E,
- llvm::Value *InVal,
- llvm::Value *NextVal,
- bool IsInc);
+ llvm::Value *EmitIncDecConsiderOverflowBehavior(const UnaryOperator *E,
+ llvm::Value *InVal,
+ bool IsInc);
llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
bool isInc, bool isPre);
@@ -1571,26 +1570,32 @@
// Unary Operators
//===----------------------------------------------------------------------===//
-llvm::Value *ScalarExprEmitter::
-EmitAddConsiderOverflowBehavior(const UnaryOperator *E,
- llvm::Value *InVal,
- llvm::Value *NextVal, bool IsInc) {
+static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E,
+ llvm::Value *InVal, bool IsInc) {
+ BinOpInfo BinOp;
+ BinOp.LHS = InVal;
+ BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1, false);
+ BinOp.Ty = E->getType();
+ BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
+ BinOp.FPContractable = false;
+ BinOp.E = E;
+ return BinOp;
+}
+
+llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
+ const UnaryOperator *E, llvm::Value *InVal, bool IsInc) {
+ llvm::Value *Amount =
+ llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, true);
+ StringRef Name = IsInc ? "inc" : "dec";
switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
case LangOptions::SOB_Defined:
- return Builder.CreateAdd(InVal, NextVal, IsInc ? "inc" : "dec");
+ return Builder.CreateAdd(InVal, Amount, Name);
case LangOptions::SOB_Undefined:
if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
- return Builder.CreateNSWAdd(InVal, NextVal, IsInc ? "inc" : "dec");
+ return Builder.CreateNSWAdd(InVal, Amount, Name);
// Fall through.
case LangOptions::SOB_Trapping:
- BinOpInfo BinOp;
- BinOp.LHS = InVal;
- BinOp.RHS = NextVal;
- BinOp.Ty = E->getType();
- BinOp.Opcode = BO_Add;
- BinOp.FPContractable = false;
- BinOp.E = E;
- return EmitOverflowCheckedBinOp(BinOp);
+ return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, InVal, IsInc));
}
llvm_unreachable("Unknown SignedOverflowBehaviorTy");
}
@@ -1668,27 +1673,20 @@
// Most common case by far: integer increment.
} else if (type->isIntegerType()) {
-
- llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
-
// Note that signed integer inc/dec with width less than int can't
// overflow because of promotion rules; we're just eliding a few steps here.
bool CanOverflow = value->getType()->getIntegerBitWidth() >=
CGF.IntTy->getIntegerBitWidth();
if (CanOverflow && type->isSignedIntegerOrEnumerationType()) {
- value = EmitAddConsiderOverflowBehavior(E, value, amt, isInc);
+ value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
} else if (CanOverflow && type->isUnsignedIntegerType() &&
CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) {
- BinOpInfo BinOp;
- BinOp.LHS = value;
- BinOp.RHS = llvm::ConstantInt::get(value->getType(), 1, false);
- BinOp.Ty = E->getType();
- BinOp.Opcode = isInc ? BO_Add : BO_Sub;
- BinOp.FPContractable = false;
- BinOp.E = E;
- value = EmitOverflowCheckedBinOp(BinOp);
- } else
+ value =
+ EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, value, isInc));
+ } else {
+ llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
+ }
// Next most common: pointer increment.
} else if (const PointerType *ptr = type->getAs<PointerType>()) {
Index: test/CodeGen/integer-overflow.c
===================================================================
--- test/CodeGen/integer-overflow.c
+++ test/CodeGen/integer-overflow.c
@@ -52,8 +52,8 @@
// DEFAULT: add nsw i32 {{.*}}, -1
// WRAPV: add i32 {{.*}}, -1
- // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 -1)
- // CATCH_UB: llvm.sadd.with.overflow.i32({{.*}}, i32 -1)
+ // TRAPV: llvm.ssub.with.overflow.i32({{.*}}, i32 1)
+ // CATCH_UB: llvm.ssub.with.overflow.i32({{.*}}, i32 1)
// TRAPV_HANDLER: foo(
--a;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits