Skip to content

Commit 84e67d3

Browse files
committed
[InstCombine] Preserve range information for Op0 - umin(X, Op0) --> usub.sat(Op0, X)
1 parent e03de24 commit 84e67d3

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2857,9 +2857,20 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
28572857
I, Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {X, Op1}));
28582858

28592859
// Op0 - umin(X, Op0) --> usub.sat(Op0, X)
2860-
if (match(Op1, m_OneUse(m_c_UMin(m_Value(X), m_Specific(Op0)))))
2861-
return replaceInstUsesWith(
2862-
I, Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {Op0, X}));
2860+
if (match(Op1, m_OneUse(m_c_UMin(m_Value(X), m_Specific(Op0))))) {
2861+
Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {Op0, X});
2862+
if (auto *USubCall = dyn_cast<CallInst>(USub)) {
2863+
// Preserve range information implied by the nsw flag.
2864+
const APInt *C;
2865+
if (I.hasNoSignedWrap() && match(X, m_NonNegative(C))) {
2866+
ConstantRange CR = ConstantRange::makeExactNoWrapRegion(
2867+
Instruction::Sub, *C, OverflowingBinaryOperator::NoSignedWrap);
2868+
USubCall->addParamAttr(
2869+
0, Attribute::get(I.getContext(), Attribute::Range, CR));
2870+
}
2871+
}
2872+
return replaceInstUsesWith(I, USub);
2873+
}
28632874

28642875
// Op0 - umax(X, Op0) --> 0 - usub.sat(X, Op0)
28652876
if (match(Op1, m_OneUse(m_c_UMax(m_Value(X), m_Specific(Op0))))) {

llvm/test/Transforms/InstCombine/sub-minmax.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ define i8 @umin_sub_op0_use(i8 %x, i8 %y) {
666666
define i8 @umin_nsw_sub_op1_rhs_nneg_constant(i8 %y) {
667667
; CHECK-LABEL: define {{[^@]+}}@umin_nsw_sub_op1_rhs_nneg_constant
668668
; CHECK-SAME: (i8 [[Y:%.*]]) {
669-
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[Y]], i8 13)
669+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.usub.sat.i8(i8 range(i8 -115, -128) [[Y]], i8 13)
670670
; CHECK-NEXT: ret i8 [[R]]
671671
;
672672
%u = call i8 @llvm.umin.i8(i8 %y, i8 13)

0 commit comments

Comments
 (0)