static bool refineInstruction(SCCPSolver &Solver,
const SmallPtrSetImpl<Value *> &InsertedValues,
Instruction &Inst) {
- if (Inst.getOpcode() != Instruction::Add)
+ if (!isa<OverflowingBinaryOperator>(Inst))
return false;
auto GetRange = [&Solver, &InsertedValues](Value *Op) {
bool Changed = false;
if (!Inst.hasNoUnsignedWrap()) {
auto NUWRange = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, RangeB, OverflowingBinaryOperator::NoUnsignedWrap);
+ Instruction::BinaryOps(Inst.getOpcode()), RangeB,
+ OverflowingBinaryOperator::NoUnsignedWrap);
if (NUWRange.contains(RangeA)) {
Inst.setHasNoUnsignedWrap();
Changed = true;
}
if (!Inst.hasNoSignedWrap()) {
auto NSWRange = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, RangeB, OverflowingBinaryOperator::NoSignedWrap);
+ Instruction::BinaryOps(Inst.getOpcode()), RangeB, OverflowingBinaryOperator::NoSignedWrap);
if (NSWRange.contains(RangeA)) {
Inst.setHasNoSignedWrap();
Changed = true;
; CHECK: if.then:
; CHECK-NEXT: br label [[RETURN:%.*]]
; CHECK: if.else:
-; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[I]], 1
+; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[I]], 1
; CHECK-NEXT: [[CALL:%.*]] = call i32 @recursive_f(i32 [[SUB]])
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[I]], [[CALL]]
; CHECK-NEXT: br label [[RETURN]]
; x - y = [-190, -79)
define internal i1 @f.sub(i32 %x, i32 %y) {
; CHECK-LABEL: @f.sub(
-; CHECK-NEXT: [[A_1:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[A_1:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[A_1]], -81
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i32 [[A_1]], -189
; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[A_1]], -150
; x * y = [1000, 4001)
define internal i1 @f.mul(i32 %x, i32 %y) {
; CHECK-LABEL: @f.mul(
-; CHECK-NEXT: [[A_1:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[A_1:%.*]] = mul nuw nsw i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[A_1]], 3999
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i32 [[A_1]], 1001
; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[A_1]], 1500
; CHECK-LABEL: @range_from_lshr(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_SHR:%.*]] = lshr i8 [[A:%.*]], 1
-; CHECK-NEXT: [[SUB_1:%.*]] = sub i8 [[A_SHR]], 1
+; CHECK-NEXT: [[SUB_1:%.*]] = sub nsw i8 [[A_SHR]], 1
; CHECK-NEXT: [[SUB_2:%.*]] = sub i8 [[A_SHR]], -128
; CHECK-NEXT: [[SUB_3:%.*]] = sub i8 [[A_SHR]], -127
; CHECK-NEXT: [[SUB_4:%.*]] = sub i8 [[A_SHR]], -1
; CHECK-LABEL: @sub_zero(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SUB_1:%.*]] = sub i8 0, [[A:%.*]]
-; CHECK-NEXT: [[SUB_2:%.*]] = sub i8 -1, [[A]]
+; CHECK-NEXT: [[SUB_2:%.*]] = sub nuw nsw i8 -1, [[A]]
; CHECK-NEXT: [[SUB_3:%.*]] = sub i8 1, [[A]]
; CHECK-NEXT: [[SUB_4:%.*]] = sub i8 [[A]], -1
; CHECK-NEXT: [[RES_1:%.*]] = xor i8 [[SUB_1]], [[SUB_2]]
; CHECK-LABEL: @shift_undef_64(
; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 4
; CHECK-NEXT: store i64 -1, ptr [[P]], align 4
-; CHECK-NEXT: [[R3:%.*]] = shl i64 -1, 4294967298
+; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i64 -1, 4294967298
; CHECK-NEXT: store i64 [[R3]], ptr [[P]], align 4
; CHECK-NEXT: ret void
;
; CHECK-LABEL: @shift_undef_65(
; CHECK-NEXT: store i65 0, ptr [[P:%.*]], align 4
; CHECK-NEXT: store i65 0, ptr [[P]], align 4
-; CHECK-NEXT: [[R3:%.*]] = shl i65 1, -18446744073709551615
+; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i65 1, -18446744073709551615
; CHECK-NEXT: store i65 [[R3]], ptr [[P]], align 4
; CHECK-NEXT: ret void
;
; CHECK-LABEL: @shift_undef_256(
; CHECK-NEXT: store i256 0, ptr [[P:%.*]], align 4
; CHECK-NEXT: store i256 0, ptr [[P]], align 4
-; CHECK-NEXT: [[R3:%.*]] = shl i256 1, 18446744073709551619
+; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i256 1, 18446744073709551619
; CHECK-NEXT: store i256 [[R3]], ptr [[P]], align 4
; CHECK-NEXT: ret void
;
; CHECK-LABEL: @shift_undef_511(
; CHECK-NEXT: store i511 0, ptr [[P:%.*]], align 4
; CHECK-NEXT: store i511 -1, ptr [[P]], align 4
-; CHECK-NEXT: [[R3:%.*]] = shl i511 -3, 1208925819614629174706180
+; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i511 -3, 1208925819614629174706180
; CHECK-NEXT: store i511 [[R3]], ptr [[P]], align 4
; CHECK-NEXT: ret void
;
; SCCP: bb4:
; SCCP-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], 3
; SCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3
-; SCCP-NEXT: [[TMP7:%.*]] = sub i64 3, [[TMP6]]
-; SCCP-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 1
+; SCCP-NEXT: [[TMP7:%.*]] = sub nuw nsw i64 3, [[TMP6]]
+; SCCP-NEXT: [[TMP8:%.*]] = shl nuw nsw i64 [[TMP7]], 1
; SCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
; SCCP-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64
; SCCP-NEXT: br label [[BB11:%.*]]
; IPSCCP: bb4:
; IPSCCP-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], 3
; IPSCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3
-; IPSCCP-NEXT: [[TMP7:%.*]] = sub i64 3, [[TMP6]]
-; IPSCCP-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 1
+; IPSCCP-NEXT: [[TMP7:%.*]] = sub nuw nsw i64 3, [[TMP6]]
+; IPSCCP-NEXT: [[TMP8:%.*]] = shl nuw nsw i64 [[TMP7]], 1
; IPSCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
; IPSCCP-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64
; IPSCCP-NEXT: br label [[BB11:%.*]]