PR9350: increment/decrement of char (and anything else narrower than int)

can't overflow due to promotion rules; emit a wrapping add for those cases.

llvm-svn: 126816
This commit is contained in:
Eli Friedman 2011-03-02 01:49:12 +00:00
parent 68faa2dbbe
commit 846ded2e53
2 changed files with 12 additions and 4 deletions

View File

@ -1278,10 +1278,12 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
if (type->isSignedIntegerType())
// 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.
if (type->isSignedIntegerType() &&
value->getType()->getPrimitiveSizeInBits() >=
CGF.CGM.IntTy->getBitWidth())
value = EmitAddConsiderOverflowBehavior(E, value, amt, isInc);
// Unsigned integer inc is always two's complement.
else
value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");

View File

@ -50,11 +50,17 @@ void test1() {
// 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*
// PR9350: char increment never overflows.
extern volatile signed char PR9350;
// DEFAULT: add i8 {{.*}}, 1
// WRAPV: add i8 {{.*}}, 1
// TRAPV: add i8 {{.*}}, 1
++PR9350;
}