[llvm] [InstCombine] Fold `umax(X, C) + -C` into `usub.sat(X, C)` (PR #118195)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 30 22:23:55 PST 2024
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/118195
Alive2: https://alive2.llvm.org/ce/z/oSWe5S
Closes https://github.com/llvm/llvm-project/issues/118155
>From 6e8cebe50c136113d230e6a243425e677a761536 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sun, 1 Dec 2024 14:11:24 +0800
Subject: [PATCH 1/2] [InstCombine] Add pre-commit tests. NFC.
---
.../InstCombine/saturating-add-sub.ll | 37 +++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
index 9236d96f59a55b..e75f4674f22eb0 100644
--- a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
+++ b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
@@ -2316,3 +2316,40 @@ 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: [[UMAX:%.*]] = call i8 @llvm.umax.i8(i8 [[A:%.*]], i8 10)
+; CHECK-NEXT: [[SEL:%.*]] = add i8 [[UMAX]], -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)
>From 60d830e24a123f8d380cb29ac156d8336e3ce41a Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sun, 1 Dec 2024 14:22:00 +0800
Subject: [PATCH 2/2] [InstCombine] Fold `umax(X, C) + -C` into `usub.sat(X,
C)`
---
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 6 ++++++
llvm/test/Transforms/InstCombine/saturating-add-sub.ll | 3 +--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 6fe96935818531..63725e4ca8113e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -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()) {
diff --git a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
index e75f4674f22eb0..d043f5b7ad116d 100644
--- a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
+++ b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
@@ -2319,8 +2319,7 @@ define i32 @uadd_sat_via_add_swapped_cmp_select_nonstrict(i32 %x, i32 %y) {
define i8 @fold_add_umax_to_usub(i8 %a) {
; CHECK-LABEL: @fold_add_umax_to_usub(
-; CHECK-NEXT: [[UMAX:%.*]] = call i8 @llvm.umax.i8(i8 [[A:%.*]], i8 10)
-; CHECK-NEXT: [[SEL:%.*]] = add i8 [[UMAX]], -10
+; 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)
More information about the llvm-commits
mailing list