If the SafeWrap operation is a subtract, we negated the constant
to treat the subtract as an addition. The sext was based on the
operation being addition. So we really need to do (neg (sext (neg C)))
when promoting the constant. This is equivalent to (sext C) for
every value of C except the min signed value. For min signed value
we need to do (zext C) instead.
Fixes PR55490.
Differential Revision: https://reviews.llvm.org/D125653
continue;
if (auto *Const = dyn_cast<ConstantInt>(Op)) {
- Constant *NewConst = (SafeWrap.contains(I) && i == 1)
+ // For subtract, we don't need to sext the constant. We only put it in
+ // SafeWrap because SafeWrap.size() is used elsewhere.
+ Constant *NewConst = (SafeWrap.contains(I) && i == 1 &&
+ I->getOpcode() != Instruction::Sub)
? ConstantExpr::getSExt(Const, ExtTy)
: ConstantExpr::getZExt(Const, ExtTy);
I->setOperand(i, NewConst);
%3 = select i1 %2, i32 1, i32 0
ret i32 %3
}
+
+define i1 @pr55490() {
+; CHECK-LABEL: @pr55490(
+; CHECK-NEXT: [[TMP1:%.*]] = sub i32 10, 8
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = sub i4 -6, -8
+ %2 = icmp ult i4 %1, 3
+ ret i1 %2
+}