Skip to content

Commit 2a88d00

Browse files
committed
[InstCombine] fold sub-of-umax to 0-usubsat
Op0 - umax(X, Op0) --> 0 - usub.sat(X, Op1) I'm not sure if this is really an improvement in IR because we probably have better recognition/analysis for min/max, but this lines up with the fold we do for the icmp+select idiom and removes another diff from D98152. This is similar to the previous fold in the code that was added with: 83c2fb9 baa6a85 https://alive2.llvm.org/ce/z/5MrVB9
1 parent de12ca3 commit 2a88d00

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,6 +2175,12 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
21752175
return replaceInstUsesWith(
21762176
I, Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {X, Op1}));
21772177

2178+
// Op0 - umax(X, Op0) --> 0 - usub.sat(X, Op1)
2179+
if (match(Op1, m_OneUse(m_c_UMax(m_Value(X), m_Specific(Op0))))) {
2180+
Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {X, Op0});
2181+
return BinaryOperator::CreateNeg(USub);
2182+
}
2183+
21782184
// C - ctpop(X) => ctpop(~X) if C is bitwidth
21792185
if (match(Op0, m_SpecificInt(Ty->getScalarSizeInBits())) &&
21802186
match(Op1, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(m_Value(X)))))

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,8 @@ define i8 @umax_sub_op0_use(i8 %x, i8 %y) {
534534

535535
define i8 @umax_sub_op1(i8 %x, i8 %y) {
536536
; CHECK-LABEL: @umax_sub_op1(
537-
; CHECK-NEXT: [[U:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
538-
; CHECK-NEXT: [[R:%.*]] = sub i8 [[Y]], [[U]]
537+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
538+
; CHECK-NEXT: [[R:%.*]] = sub i8 0, [[TMP1]]
539539
; CHECK-NEXT: ret i8 [[R]]
540540
;
541541
%u = call i8 @llvm.umax.i8(i8 %x, i8 %y)
@@ -545,8 +545,8 @@ define i8 @umax_sub_op1(i8 %x, i8 %y) {
545545

546546
define <2 x i8> @umax_sub_op1_vec_commute(<2 x i8> %x, <2 x i8> %y) {
547547
; CHECK-LABEL: @umax_sub_op1_vec_commute(
548-
; CHECK-NEXT: [[U:%.*]] = call <2 x i8> @llvm.umax.v2i8(<2 x i8> [[Y:%.*]], <2 x i8> [[X:%.*]])
549-
; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[Y]], [[U]]
548+
; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]])
549+
; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
550550
; CHECK-NEXT: ret <2 x i8> [[R]]
551551
;
552552
%u = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %y, <2 x i8> %x)

0 commit comments

Comments
 (0)