Skip to content

Commit

Permalink
[InstCombine] Fold umax(X, C) + -C into usub.sat(X, C) (llvm#118195)
Browse files Browse the repository at this point in the history
  • Loading branch information
dtcxzyw authored and TIFitis committed Dec 8, 2024
1 parent a7c0833 commit 7c93bea
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
6 changes: 6 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,12 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
}
}

// umax(X, C) + -C --> usub.sat(X, C)
if (match(Op0, m_OneUse(m_UMax(m_Value(X), m_SpecificInt(-*C)))))
return replaceInstUsesWith(
Add, Builder.CreateBinaryIntrinsic(
Intrinsic::usub_sat, X, ConstantInt::get(Add.getType(), -*C)));

// Fold (add (zext (add X, -1)), 1) -> (zext X) if X is non-zero.
// TODO: There's a general form for any constant on the outer add.
if (C->isOne()) {
Expand Down
36 changes: 36 additions & 0 deletions llvm/test/Transforms/InstCombine/saturating-add-sub.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2316,3 +2316,39 @@ define i32 @uadd_sat_via_add_swapped_cmp_select_nonstrict(i32 %x, i32 %y) {
%r = select i1 %c, i32 %a, i32 -1
ret i32 %r
}

define i8 @fold_add_umax_to_usub(i8 %a) {
; CHECK-LABEL: @fold_add_umax_to_usub(
; CHECK-NEXT: [[SEL:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 10)
; CHECK-NEXT: ret i8 [[SEL]]
;
%umax = call i8 @llvm.umax.i8(i8 %a, i8 10)
%sel = add i8 %umax, -10
ret i8 %sel
}

define i8 @fold_add_umax_to_usub_incorrect_rhs(i8 %a) {
; CHECK-LABEL: @fold_add_umax_to_usub_incorrect_rhs(
; CHECK-NEXT: [[UMAX:%.*]] = call i8 @llvm.umax.i8(i8 [[A:%.*]], i8 10)
; CHECK-NEXT: [[SEL:%.*]] = add i8 [[UMAX]], -11
; CHECK-NEXT: ret i8 [[SEL]]
;
%umax = call i8 @llvm.umax.i8(i8 %a, i8 10)
%sel = add i8 %umax, -11
ret i8 %sel
}

define i8 @fold_add_umax_to_usub_multiuse(i8 %a) {
; CHECK-LABEL: @fold_add_umax_to_usub_multiuse(
; CHECK-NEXT: [[UMAX:%.*]] = call i8 @llvm.umax.i8(i8 [[A:%.*]], i8 10)
; CHECK-NEXT: call void @usei8(i8 [[UMAX]])
; CHECK-NEXT: [[SEL:%.*]] = add i8 [[UMAX]], -10
; CHECK-NEXT: ret i8 [[SEL]]
;
%umax = call i8 @llvm.umax.i8(i8 %a, i8 10)
call void @usei8(i8 %umax)
%sel = add i8 %umax, -10
ret i8 %sel
}

declare void @usei8(i8)

0 comments on commit 7c93bea

Please sign in to comment.