Index: cfe/trunk/lib/CodeGen/CGExprScalar.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp +++ cfe/trunk/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); @@ -1610,26 +1609,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"); } @@ -1707,27 +1712,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()) { Index: cfe/trunk/test/CodeGen/integer-overflow.c =================================================================== --- cfe/trunk/test/CodeGen/integer-overflow.c +++ cfe/trunk/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;