MaxNumRangeExtensions);
}
-static ConstantRange getConstantRange(const ValueLatticeElement &LV, Type *Ty,
- bool UndefAllowed = true) {
- assert(Ty->isIntOrIntVectorTy() && "Should be int or int vector");
- if (LV.isConstantRange(UndefAllowed))
- return LV.getConstantRange();
- return ConstantRange::getFull(Ty->getScalarSizeInBits());
-}
-
namespace llvm {
bool SCCPSolver::isConstant(const ValueLatticeElement &LV) {
return true;
}
-/// Try to use \p Inst's value range from \p Solver to infer the NUW flag.
-static bool refineInstruction(SCCPSolver &Solver, Instruction &Inst) {
- if (Inst.getOpcode() != Instruction::Add ||
- SCCPSolver::isConstant(Solver.getLatticeValueFor(&Inst)))
- return false;
-
- Value *OpA = Inst.getOperand(0);
- Value *OpB = Inst.getOperand(1);
- auto RangeA = getConstantRange(Solver.getLatticeValueFor(OpA), OpA->getType(),
- /*UndefAllowed=*/false);
- auto RangeB = getConstantRange(Solver.getLatticeValueFor(OpB), OpB->getType(),
- /*UndefAllowed=*/false);
- if (!Inst.hasNoUnsignedWrap()) {
- auto NUWRange = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, RangeB, OverflowingBinaryOperator::NoUnsignedWrap);
- if (NUWRange.contains(RangeA)) {
- Inst.setHasNoUnsignedWrap();
- return true;
- }
- }
-
- return false;
-}
-
/// Try to replace signed instructions with their unsigned equivalent.
static bool replaceSignedInst(SCCPSolver &Solver,
SmallPtrSetImpl<Value *> &InsertedValues,
for (Instruction &Inst : make_early_inc_range(BB)) {
if (Inst.getType()->isVoidTy())
continue;
- MadeChanges |= refineInstruction(*this, Inst);
- }
-
- for (Instruction &Inst : make_early_inc_range(BB)) {
- if (Inst.getType()->isVoidTy())
- continue;
-
if (tryToReplaceWithConstant(&Inst)) {
if (canRemoveInstruction(&Inst))
Inst.eraseFromParent();
bool isStructLatticeConstant(Function *F, StructType *STy);
Constant *getConstant(const ValueLatticeElement &LV) const;
+ ConstantRange getConstantRange(const ValueLatticeElement &LV, Type *Ty) const;
SmallPtrSetImpl<Function *> &getArgumentTrackedFunctions() {
return TrackingIncomingArguments;
return nullptr;
}
+ConstantRange
+SCCPInstVisitor::getConstantRange(const ValueLatticeElement &LV,
+ Type *Ty) const {
+ assert(Ty->isIntOrIntVectorTy() && "Should be int or int vector");
+ if (LV.isConstantRange())
+ return LV.getConstantRange();
+ return ConstantRange::getFull(Ty->getScalarSizeInBits());
+}
+
void SCCPInstVisitor::markArgInFuncSpecialization(
Function *F, const SmallVectorImpl<ArgInfo> &Args) {
assert(!Args.empty() && "Specialization without arguments");
; CHECK-LABEL: @range_from_lshr(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_SHR:%.*]] = lshr i8 [[A:%.*]], 1
-; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A_SHR]], 1
-; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[A_SHR]], -128
+; CHECK-NEXT: [[ADD_1:%.*]] = add i8 [[A_SHR]], 1
+; CHECK-NEXT: [[ADD_2:%.*]] = add i8 [[A_SHR]], -128
; CHECK-NEXT: [[ADD_3:%.*]] = add i8 [[A_SHR]], -127
; CHECK-NEXT: [[ADD_4:%.*]] = add i8 [[A_SHR]], -1
; CHECK-NEXT: [[RES_1:%.*]] = xor i8 [[ADD_1]], [[ADD_2]]
; CHECK-LABEL: @a_and_15_add_1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_AND:%.*]] = and i8 [[A:%.*]], 15
-; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A_AND]], 1
+; CHECK-NEXT: [[ADD_1:%.*]] = add i8 [[A_AND]], 1
; CHECK-NEXT: ret i8 [[ADD_1]]
;
entry:
; CHECK-NEXT: [[AND:%.*]] = and i1 [[SGT]], [[SLT]]
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
-; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], 1
+; CHECK-NEXT: [[ADD_1:%.*]] = add i8 [[A]], 1
; CHECK-NEXT: [[ADD_2:%.*]] = add i8 [[A]], -1
-; CHECK-NEXT: [[ADD_3:%.*]] = add nuw i8 [[A]], -91
+; CHECK-NEXT: [[ADD_3:%.*]] = add i8 [[A]], -91
; CHECK-NEXT: [[ADD_4:%.*]] = add i8 [[A]], -90
; CHECK-NEXT: [[RES_1:%.*]] = xor i8 [[ADD_1]], [[ADD_2]]
; CHECK-NEXT: [[RES_2:%.*]] = xor i8 [[RES_1]], [[ADD_3]]
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[SEXT:%.*]] = zext i8 [[A]] to i16
-; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i16 [[SEXT]], 1
-; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i16 [[SEXT]], -128
+; CHECK-NEXT: [[ADD_1:%.*]] = add i16 [[SEXT]], 1
+; CHECK-NEXT: [[ADD_2:%.*]] = add i16 [[SEXT]], -128
; CHECK-NEXT: [[ADD_3:%.*]] = add i16 [[SEXT]], -127
; CHECK-NEXT: [[RES_1:%.*]] = xor i16 [[ADD_1]], [[ADD_2]]
; CHECK-NEXT: [[RES_2:%.*]] = xor i16 [[RES_1]], [[ADD_3]]
define void @add_constexpr(i32 %a) {
; CHECK-LABEL: @add_constexpr(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i32 0, [[A:%.*]]
+; CHECK-NEXT: [[ADD_1:%.*]] = add i32 0, [[A:%.*]]
; CHECK-NEXT: call void @use.i32(i32 [[ADD_1]])
; CHECK-NEXT: [[ADD_2:%.*]] = add i32 20, [[A]]
; CHECK-NEXT: call void @use.i32(i32 [[ADD_2]])
define void @val_undef_eq() {
; CHECK-LABEL: @val_undef_eq(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A:%.*]] = add nuw i32 undef, 0
+; CHECK-NEXT: [[A:%.*]] = add i32 undef, 0
; CHECK-NEXT: [[BC_1:%.*]] = icmp eq i32 [[A]], 10
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
define void @val_undef_range() {
; CHECK-LABEL: @val_undef_range(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A:%.*]] = add nuw i32 undef, 0
+; CHECK-NEXT: [[A:%.*]] = add i32 undef, 0
; CHECK-NEXT: [[BC_1:%.*]] = icmp ult i32 [[A]], 127
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
; CHECK-LABEL: @f1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_255:%.*]] = and i32 [[A:%.*]], 255
-; CHECK-NEXT: [[A_2:%.*]] = add nuw i32 [[A_255]], 20
+; CHECK-NEXT: [[A_2:%.*]] = add i32 [[A_255]], 20
; CHECK-NEXT: [[BC:%.*]] = icmp ugt i32 [[B:%.*]], [[A_2]]
; CHECK-NEXT: br i1 [[BC]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
; CHECK-LABEL: @f8_nested_conds(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_255:%.*]] = and i32 [[A:%.*]], 255
-; CHECK-NEXT: [[A_2:%.*]] = add nuw i32 [[A_255]], 20
+; CHECK-NEXT: [[A_2:%.*]] = add i32 [[A_255]], 20
; CHECK-NEXT: [[BC_1:%.*]] = icmp ugt i32 [[B:%.*]], [[A_2]]
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
; CHECK-NEXT: [[INC27]] = add nsw i32 [[I_0]], 1
; CHECK-NEXT: br label [[FOR_COND]]
; CHECK: for.body14:
-; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[J_0]], 1
+; CHECK-NEXT: [[INC]] = add nsw i32 [[J_0]], 1
; CHECK-NEXT: br label [[FOR_COND11]]
;
entry:
; CHECK-LABEL: @caller1(
; CHECK-NEXT: [[C1:%.*]] = call i32 @callee(i32 10), !range [[RNG0:![0-9]+]]
; CHECK-NEXT: [[C2:%.*]] = call i32 @callee(i32 20), !range [[RNG0]]
-; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[C1]], [[C2]]
+; CHECK-NEXT: [[A:%.*]] = add i32 [[C1]], [[C2]]
; CHECK-NEXT: ret i32 [[A]]
;
%c1 = call i32 @callee(i32 10)
; CHECK-NEXT: [[CMP4:%.*]] = icmp ugt i32 [[X]], 300
; CHECK-NEXT: [[RES1:%.*]] = select i1 [[CMP]], i32 1, i32 2
; CHECK-NEXT: [[RES4:%.*]] = select i1 [[CMP4]], i32 3, i32 4
-; CHECK-NEXT: [[RES6:%.*]] = add nuw i32 [[RES1]], 3
-; CHECK-NEXT: [[RES7:%.*]] = add nuw i32 5, [[RES4]]
-; CHECK-NEXT: [[RES:%.*]] = add nuw i32 [[RES6]], 5
+; CHECK-NEXT: [[RES6:%.*]] = add i32 [[RES1]], 3
+; CHECK-NEXT: [[RES7:%.*]] = add i32 5, [[RES4]]
+; CHECK-NEXT: [[RES:%.*]] = add i32 [[RES6]], 5
; CHECK-NEXT: ret i32 [[RES]]
;
entry:
; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @f1(i32 47, i32 999)
; CHECK-NEXT: [[CALL3:%.*]] = tail call i32 @f2(i32 47)
; CHECK-NEXT: [[CALL4:%.*]] = tail call i32 @f2(i32 301)
-; CHECK-NEXT: [[RES_1:%.*]] = add nuw nsw i32 12, [[CALL3]]
-; CHECK-NEXT: [[RES_2:%.*]] = add nuw nsw i32 [[RES_1]], [[CALL4]]
+; CHECK-NEXT: [[RES_1:%.*]] = add nsw i32 12, [[CALL3]]
+; CHECK-NEXT: [[RES_2:%.*]] = add nsw i32 [[RES_1]], [[CALL4]]
; CHECK-NEXT: ret i32 [[RES_2]]
;
entry:
; x + y = [110, 221)
define internal i1 @f.add(i32 %x, i32 %y) {
; CHECK-LABEL: @f.add(
-; CHECK-NEXT: [[A_1:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[A_1:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[A_1]], 219
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i32 [[A_1]], 111
; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[A_1]], 150
; CHECK-NEXT: [[C_6:%.*]] = icmp slt i32 [[A_1]], 150
-; CHECK-NEXT: [[RES_1:%.*]] = add nuw i1 false, [[C_2]]
-; CHECK-NEXT: [[RES_2:%.*]] = add nuw i1 [[RES_1]], false
+; CHECK-NEXT: [[RES_1:%.*]] = add i1 false, [[C_2]]
+; CHECK-NEXT: [[RES_2:%.*]] = add i1 [[RES_1]], false
; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]]
; CHECK-NEXT: [[RES_4:%.*]] = add i1 [[RES_3]], [[C_5]]
; CHECK-NEXT: [[RES_5:%.*]] = add i1 [[RES_4]], [[C_6]]
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i32 [[A_1]], -189
; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[A_1]], -150
; CHECK-NEXT: [[C_6:%.*]] = icmp slt i32 [[A_1]], -150
-; CHECK-NEXT: [[RES_1:%.*]] = add nuw i1 false, [[C_2]]
-; CHECK-NEXT: [[RES_2:%.*]] = add nuw i1 [[RES_1]], false
+; CHECK-NEXT: [[RES_1:%.*]] = add i1 false, [[C_2]]
+; CHECK-NEXT: [[RES_2:%.*]] = add i1 [[RES_1]], false
; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]]
; CHECK-NEXT: [[RES_4:%.*]] = add i1 [[RES_3]], [[C_5]]
; CHECK-NEXT: [[RES_5:%.*]] = add i1 [[RES_4]], [[C_6]]
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i32 [[A_1]], 1001
; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[A_1]], 1500
; CHECK-NEXT: [[C_6:%.*]] = icmp slt i32 [[A_1]], 1500
-; CHECK-NEXT: [[RES_1:%.*]] = add nuw i1 false, [[C_2]]
-; CHECK-NEXT: [[RES_2:%.*]] = add nuw i1 [[RES_1]], false
+; CHECK-NEXT: [[RES_1:%.*]] = add i1 false, [[C_2]]
+; CHECK-NEXT: [[RES_2:%.*]] = add i1 [[RES_1]], false
; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]]
; CHECK-NEXT: [[RES_4:%.*]] = add i1 [[RES_3]], [[C_5]]
; CHECK-NEXT: [[RES_5:%.*]] = add i1 [[RES_4]], [[C_6]]
; CHECK-NEXT: [[T_1:%.*]] = trunc i32 [[X:%.*]] to i16
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i16 [[T_1]], 299
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i16 [[T_1]], 101
-; CHECK-NEXT: [[RES_1:%.*]] = add nuw i1 false, [[C_2]]
-; CHECK-NEXT: [[RES_2:%.*]] = add nuw i1 [[RES_1]], false
+; CHECK-NEXT: [[RES_1:%.*]] = add i1 false, [[C_2]]
+; CHECK-NEXT: [[RES_2:%.*]] = add i1 [[RES_1]], false
; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]]
; CHECK-NEXT: [[T_2:%.*]] = trunc i32 [[X]] to i8
; CHECK-NEXT: [[C_5:%.*]] = icmp sgt i8 [[T_2]], 44
; CHECK-NEXT: [[T_1:%.*]] = zext i32 [[X:%.*]] to i64
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i64 [[T_1]], 299
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i64 [[T_1]], 101
-; CHECK-NEXT: [[RES_1:%.*]] = add nuw i1 false, [[C_2]]
-; CHECK-NEXT: [[RES_2:%.*]] = add nuw i1 [[RES_1]], false
+; CHECK-NEXT: [[RES_1:%.*]] = add i1 false, [[C_2]]
+; CHECK-NEXT: [[RES_2:%.*]] = add i1 [[RES_1]], false
; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]]
; CHECK-NEXT: [[T_2:%.*]] = zext i32 [[Y:%.*]] to i64
; CHECK-NEXT: [[C_5:%.*]] = icmp sgt i64 [[T_2]], 300
; CHECK-NEXT: [[C_8:%.*]] = icmp slt i64 [[T_2]], 1
; CHECK-NEXT: [[RES_4:%.*]] = add i1 [[RES_3]], [[C_5]]
; CHECK-NEXT: [[RES_5:%.*]] = add i1 [[RES_4]], [[C_6]]
-; CHECK-NEXT: [[RES_6:%.*]] = add nuw i1 [[RES_5]], false
+; CHECK-NEXT: [[RES_6:%.*]] = add i1 [[RES_5]], false
; CHECK-NEXT: [[RES_7:%.*]] = add i1 [[RES_6]], [[C_8]]
; CHECK-NEXT: ret i1 [[RES_7]]
;
; CHECK-NEXT: [[T_1:%.*]] = zext i32 [[X:%.*]] to i64
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i64 [[T_1]], 299
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i64 [[T_1]], 101
-; CHECK-NEXT: [[RES_1:%.*]] = add nuw i1 false, [[C_2]]
-; CHECK-NEXT: [[RES_2:%.*]] = add nuw i1 [[RES_1]], false
+; CHECK-NEXT: [[RES_1:%.*]] = add i1 false, [[C_2]]
+; CHECK-NEXT: [[RES_2:%.*]] = add i1 [[RES_1]], false
; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]]
; CHECK-NEXT: [[T_2:%.*]] = sext i32 [[Y:%.*]] to i64
; CHECK-NEXT: [[C_6:%.*]] = icmp sgt i64 [[T_2]], 899
; CHECK-NEXT: [[C_8:%.*]] = icmp slt i64 [[T_2]], -119
-; CHECK-NEXT: [[RES_4:%.*]] = add nuw i1 [[RES_3]], false
+; CHECK-NEXT: [[RES_4:%.*]] = add i1 [[RES_3]], false
; CHECK-NEXT: [[RES_5:%.*]] = add i1 [[RES_4]], [[C_6]]
-; CHECK-NEXT: [[RES_6:%.*]] = add nuw i1 [[RES_5]], false
+; CHECK-NEXT: [[RES_6:%.*]] = add i1 [[RES_5]], false
; CHECK-NEXT: [[RES_7:%.*]] = add i1 [[RES_6]], [[C_8]]
; CHECK-NEXT: ret i1 [[RES_7]]
;
; CHECK-NEXT: [[V_1:%.*]] = select i1 [[C_1]], i32 10, i32 100
; CHECK-NEXT: [[V_2:%.*]] = select i1 [[C_2]], i32 20, i32 200
; CHECK-NEXT: [[V_3:%.*]] = select i1 [[C_3]], i32 30, i32 300
-; CHECK-NEXT: [[R_1:%.*]] = add nuw i32 [[V_1]], [[V_2]]
-; CHECK-NEXT: [[R_2:%.*]] = add nuw i32 [[R_1]], [[V_3]]
-; CHECK-NEXT: [[R_3:%.*]] = add nuw i32 [[R_2]], 400
-; CHECK-NEXT: [[R_4:%.*]] = add nuw i32 [[R_3]], 50
-; CHECK-NEXT: [[R_5:%.*]] = add nuw i32 [[R_4]], 60
-; CHECK-NEXT: [[R_6:%.*]] = add nuw i32 [[R_4]], 700
+; CHECK-NEXT: [[R_1:%.*]] = add i32 [[V_1]], [[V_2]]
+; CHECK-NEXT: [[R_2:%.*]] = add i32 [[R_1]], [[V_3]]
+; CHECK-NEXT: [[R_3:%.*]] = add i32 [[R_2]], 400
+; CHECK-NEXT: [[R_4:%.*]] = add i32 [[R_3]], 50
+; CHECK-NEXT: [[R_5:%.*]] = add i32 [[R_4]], 60
+; CHECK-NEXT: [[R_6:%.*]] = add i32 [[R_4]], 700
; CHECK-NEXT: ret i32 [[R_6]]
;
; CHECK-NEXT: [[V_5:%.*]] = select i1 [[C_5]], i32 50, i32 500
; CHECK-NEXT: [[V_6:%.*]] = select i1 [[C_6]], i32 60, i32 600
; CHECK-NEXT: [[V_7:%.*]] = select i1 [[C_7]], i32 70, i32 700
-; CHECK-NEXT: [[R_1:%.*]] = add nuw i32 [[V_1]], [[V_2]]
-; CHECK-NEXT: [[R_2:%.*]] = add nuw i32 [[R_1]], [[V_3]]
-; CHECK-NEXT: [[R_3:%.*]] = add nuw i32 [[R_2]], [[V_4]]
-; CHECK-NEXT: [[R_4:%.*]] = add nuw i32 [[R_3]], [[V_5]]
-; CHECK-NEXT: [[R_5:%.*]] = add nuw i32 [[R_4]], [[V_6]]
-; CHECK-NEXT: [[R_6:%.*]] = add nuw i32 [[R_4]], [[V_7]]
+; CHECK-NEXT: [[R_1:%.*]] = add i32 [[V_1]], [[V_2]]
+; CHECK-NEXT: [[R_2:%.*]] = add i32 [[R_1]], [[V_3]]
+; CHECK-NEXT: [[R_3:%.*]] = add i32 [[R_2]], [[V_4]]
+; CHECK-NEXT: [[R_4:%.*]] = add i32 [[R_3]], [[V_5]]
+; CHECK-NEXT: [[R_5:%.*]] = add i32 [[R_4]], [[V_6]]
+; CHECK-NEXT: [[R_6:%.*]] = add i32 [[R_4]], [[V_7]]
; CHECK-NEXT: ret i32 [[R_6]]
;
; CHECK-NEXT: [[SEL_1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[Y]]
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[SEL_1]], 100
; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[SEL_1]], 50
-; CHECK-NEXT: [[RES_1:%.*]] = add nuw i1 false, [[C_2]]
+; CHECK-NEXT: [[RES_1:%.*]] = add i1 false, [[C_2]]
; CHECK-NEXT: [[RES_2:%.*]] = add i1 [[RES_1]], [[C_3]]
-; CHECK-NEXT: [[RES_3:%.*]] = add nuw i1 [[RES_2]], false
+; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], false
; CHECK-NEXT: ret i1 [[RES_3]]
;
%sel.1 = select i1 %cmp, i32 %x, i32 %y
;; value
define internal { i32, i32 } @foo(i32 %A, i32 %B) {
; CHECK-LABEL: @foo(
-; CHECK-NEXT: [[X:%.*]] = add nuw i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[Y:%.*]] = insertvalue { i32, i32 } undef, i32 [[A]], 0
; CHECK-NEXT: [[Z:%.*]] = insertvalue { i32, i32 } [[Y]], i32 [[X]], 1
; CHECK-NEXT: ret { i32, i32 } [[Z]]
; CHECK-NEXT: to label [[OK:%.*]] unwind label [[LPAD:%.*]]
; CHECK: OK:
; CHECK-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
-; CHECK-NEXT: [[Z:%.*]] = add nuw i32 [[X1]], [[X2]]
+; CHECK-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
; CHECK-NEXT: store i32 [[Z]], ptr [[W]], align 4
; CHECK-NEXT: br label [[RET:%.*]]
; CHECK: LPAD:
; CHECK-NEXT: [[B:%.*]] = extractvalue [[TMP0]] [[X]], 1
; CHECK-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]])
; CHECK-NEXT: [[D:%.*]] = extractvalue [[TMP0]] [[Y]], 1
-; CHECK-NEXT: [[N:%.*]] = add nuw i32 [[B]], [[D]]
+; CHECK-NEXT: [[N:%.*]] = add i32 [[B]], [[D]]
; CHECK-NEXT: ret [[TMP0]] [[X]]
;
%X = call %0 @foo(i1 %Q)
; SCCP-NEXT: br label [[EXIT]]
; SCCP: exit:
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ]
-; SCCP-NEXT: [[A:%.*]] = add nuw i32 [[P]], 1
+; SCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
; SCCP-NEXT: call void @use(i1 true)
; SCCP-NEXT: call void @use(i1 false)
; SCCP-NEXT: ret void
; IPSCCP-NEXT: br label [[EXIT]]
; IPSCCP: exit:
; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ]
-; IPSCCP-NEXT: [[A:%.*]] = add nuw i32 [[P]], 1
+; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
; IPSCCP-NEXT: call void @use(i1 true)
; IPSCCP-NEXT: call void @use(i1 false)
; IPSCCP-NEXT: ret void
; SCCP-NEXT: br label [[EXIT]]
; SCCP: exit:
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ]
-; SCCP-NEXT: [[A:%.*]] = add nuw i32 [[P]], 1
+; SCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
; SCCP-NEXT: call void @use(i1 true)
; SCCP-NEXT: call void @use(i1 false)
; SCCP-NEXT: ret void
; IPSCCP-NEXT: br label [[EXIT]]
; IPSCCP: exit:
; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ]
-; IPSCCP-NEXT: [[A:%.*]] = add nuw i32 [[P]], 1
+; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
; IPSCCP-NEXT: call void @use(i1 true)
; IPSCCP-NEXT: call void @use(i1 false)
; IPSCCP-NEXT: ret void
; SCCP-NEXT: br label [[EXIT]]
; SCCP: exit:
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ]
-; SCCP-NEXT: [[A:%.*]] = add nuw i32 [[P]], 1
+; SCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
; SCCP-NEXT: call void @use(i1 true)
; SCCP-NEXT: call void @use(i1 false)
; SCCP-NEXT: ret void
; IPSCCP-NEXT: br label [[EXIT]]
; IPSCCP: exit:
; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ]
-; IPSCCP-NEXT: [[A:%.*]] = add nuw i32 [[P]], 1
+; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
; IPSCCP-NEXT: call void @use(i1 true)
; IPSCCP-NEXT: call void @use(i1 false)
; IPSCCP-NEXT: ret void
; SCCP-NEXT: br label [[EXIT]]
; SCCP: exit:
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ]
-; SCCP-NEXT: [[A:%.*]] = add nuw i32 [[P]], 1
+; SCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
; SCCP-NEXT: call void @use(i1 true)
; SCCP-NEXT: call void @use(i1 false)
; SCCP-NEXT: br label [[EXIT_1:%.*]]
; IPSCCP-NEXT: br label [[EXIT]]
; IPSCCP: exit:
; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ]
-; IPSCCP-NEXT: [[A:%.*]] = add nuw i32 [[P]], 1
+; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
; IPSCCP-NEXT: call void @use(i1 true)
; IPSCCP-NEXT: call void @use(i1 false)
; IPSCCP-NEXT: br label [[EXIT_1:%.*]]
; IPSCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
; IPSCCP: loop.body:
; IPSCCP-NEXT: call void @use(i1 true)
-; IPSCCP-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; IPSCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
; IPSCCP-NEXT: br label [[LOOP_HEADER]]
; IPSCCP: exit:
; IPSCCP-NEXT: ret void