[llvm] [InstCombine] Fold umax(nuw_mul(x, C0), x + 1) into (x == 0 ? 1 : nuw_mul(x, C0)) (PR #123468)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 18 20:11:09 PST 2025
https://github.com/Ruhung updated https://github.com/llvm/llvm-project/pull/123468
>From 6c4aa1d0a607be6b5c0c9e475950d2d7c2ad22dd Mon Sep 17 00:00:00 2001
From: Ruhung <jhlee at pllab.cs.nthu.edu.tw>
Date: Sun, 19 Jan 2025 02:42:51 +0800
Subject: [PATCH 1/2] [InstCombine] Pre-commit tests
---
.../InstCombine/add-shl-mul-umax.ll | 358 ++++++++++++++++++
1 file changed, 358 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll
diff --git a/llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll b/llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll
new file mode 100644
index 00000000000000..eb4ff7f290665e
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll
@@ -0,0 +1,358 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+; When C0 is neither 0 nor 1:
+; umax(nuw_mul(x, C0), x + 1) is optimized to:
+; x == 0 ? 1 : nuw_mul(x, C0)
+; When C0 is not 0:
+; umax(nuw_shl(x, C0), x + 1) is optimized to:
+; x == 0 ? 1 : nuw_shl(x, C0)
+
+; Positive Test Cases for `shl`
+
+define i64 @test_shl_by_2(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_by_2(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[X]], 2
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %shl = shl nuw i64 %x, 2
+ %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_shl_by_5(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_by_5(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[X]], 5
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %shl = shl nuw i64 %x, 5
+ %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_shl_with_nsw(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_with_nsw(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i64 [[X]], 2
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[SHL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %shl = shl nuw nsw i64 %x, 2
+ %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+ ret i64 %max
+}
+
+; Commuted Test Cases for `shl`
+
+define i64 @test_shl_umax_commuted(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_umax_commuted(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[X]], 2
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[X1]], i64 [[SHL]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %shl = shl nuw i64 %x, 2
+ %max = call i64 @llvm.umax.i64(i64 %x1, i64 %shl)
+ ret i64 %max
+}
+
+; Negative Test Cases for `shl`
+
+define i64 @test_shl_by_zero(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_by_zero(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[X]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %shl = shl nuw i64 %x, 0
+ %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_shl_add_by_2(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_add_by_2(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 2
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[X]], 2
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[SHL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 2
+ %shl = shl nuw i64 %x, 2
+ %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_shl_without_nuw(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_without_nuw(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X]], 2
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[SHL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %shl = shl i64 %x, 2
+ %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_shl_umin(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_umin(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[X]], 2
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umin.i64(i64 [[SHL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %shl = shl nuw i64 %x, 2
+ %max = call i64 @llvm.umin.i64(i64 %shl, i64 %x1)
+ ret i64 %max
+}
+
+; Multi-use Test Cases for `shl`
+declare void @use(i64)
+
+define i64 @test_shl_multi_use_add(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_multi_use_add(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: call void @use(i64 [[X1]])
+; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[X]], 3
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ call void @use(i64 %x1)
+ %shl = shl nuw i64 %x, 3
+ %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_shl_multi_use_shl(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_multi_use_shl(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[X]], 2
+; CHECK-NEXT: call void @use(i64 [[SHL]])
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[SHL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %shl = shl nuw i64 %x, 2
+ call void @use(i64 %shl)
+ %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_shl_multi_use_max(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_multi_use_max(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[X]], 3
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT: call void @use(i64 [[MAX]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %shl = shl nuw i64 %x, 3
+ %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+ call void @use(i64 %max)
+ ret i64 %max
+}
+
+; Positive Test Cases for `mul`
+
+define i64 @test_mul_by_3(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_by_3(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %mul = mul nuw i64 %x, 3
+ %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_mul_by_5(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_by_5(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 5
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %mul = mul nuw i64 %x, 5
+ %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_mul_with_nsw(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_with_nsw(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i64 [[X]], 3
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %mul = mul nuw nsw i64 %x, 3
+ %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+ ret i64 %max
+}
+
+; Commuted Test Cases for `mul`
+
+define i64 @test_mul_max_commuted(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_max_commuted(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[X1]], i64 [[MUL]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %mul = mul nuw i64 %x, 3
+ %max = call i64 @llvm.umax.i64(i64 %x1, i64 %mul)
+ ret i64 %max
+}
+
+; Negative Test Cases for `mul`
+
+define i64 @test_mul_by_zero(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_by_zero(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: ret i64 [[X1]]
+;
+ %x1 = add i64 %x, 1
+ %mul = mul nuw i64 %x, 0
+ %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_mul_by_1(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_by_1(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[X]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %mul = mul nuw i64 %x, 1
+ %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_mul_add_by_2(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_add_by_2(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 2
+; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 2
+ %mul = mul nuw i64 %x, 3
+ %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_mul_without_nuw(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_without_nuw(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[X]], 3
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %mul = mul i64 %x, 3
+ %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_mul_umin(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_umin(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umin.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %mul = mul nuw i64 %x, 3
+ %max = call i64 @llvm.umin.i64(i64 %mul, i64 %x1)
+ ret i64 %max
+}
+
+; Multi-use Test Cases for `mul`
+
+define i64 @test_mul_multi_use_add(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_multi_use_add(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: call void @use(i64 [[X1]])
+; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[X]], 3
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ call void @use(i64 %x1)
+ %mul = mul nuw i64 %x, 3
+ %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_mul_multi_use_mul(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_multi_use_mul(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3
+; CHECK-NEXT: call void @use(i64 [[MUL]])
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %mul = mul nuw i64 %x, 3
+ call void @use(i64 %mul)
+ %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+ ret i64 %max
+}
+
+define i64 @test_mul_multi_use_max(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_multi_use_max(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[X]], 3
+; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT: call void @use(i64 [[MAX]])
+; CHECK-NEXT: ret i64 [[MAX]]
+;
+ %x1 = add i64 %x, 1
+ %mul = mul nuw i64 %x, 3
+ %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+ call void @use(i64 %max)
+ ret i64 %max
+}
+
>From 11d8808d2a5cd8488e06168aa9a5fd9b1d96abaf Mon Sep 17 00:00:00 2001
From: Ruhung <jhlee at pllab.cs.nthu.edu.tw>
Date: Sun, 19 Jan 2025 03:01:59 +0800
Subject: [PATCH 2/2] [InstCombine] Fold umax(nuw_mul(x, C0), x + 1) into (x ==
0 ? 1 : nuw_mul(x, C0))
---
.../InstCombine/InstCombineCalls.cpp | 27 +++++++++++
.../InstCombine/add-shl-mul-umax.ll | 48 +++++++++----------
2 files changed, 51 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index c55c40c88bc845..175db284d24677 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1847,6 +1847,33 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
return CastInst::Create(Instruction::ZExt, NarrowMaxMin, II->getType());
}
}
+ // If C0 is not 0:
+ // umax(nuw_shl(x, C0), x + 1) -> x == 0 ? 1 : nuw_shl(x, C0)
+ // If C0 is not 0 or 1:
+ // umax(nuw_mul(x, C0), x + 1) -> x == 0 ? 1 : nuw_mul(x, C0)
+ auto foldMaxMulShift = [&](Value *A, Value *B) -> Instruction * {
+ const APInt *C;
+ Value *X;
+ if (!(match(A, m_NUWShl(m_Value(X), m_APInt(C)))) &&
+ !(match(A, m_NUWMul(m_Value(X), m_APInt(C))) && !C->isOne()))
+ return nullptr;
+ if (C->isZero())
+ return nullptr;
+ if (!match(B, m_OneUse(m_Add(m_Specific(X), m_One()))))
+ return nullptr;
+
+ Value *Cmp = Builder.CreateICmpEQ(X, ConstantInt::get(X->getType(), 0));
+ Value *NewSelect =
+ Builder.CreateSelect(Cmp, ConstantInt::get(X->getType(), 1), A);
+ return replaceInstUsesWith(*II, NewSelect);
+ };
+
+ if (IID == Intrinsic::umax) {
+ if (Instruction *I = foldMaxMulShift(I0, I1))
+ return I;
+ if (Instruction *I = foldMaxMulShift(I1, I0))
+ return I;
+ }
// If both operands of unsigned min/max are sign-extended, it is still ok
// to narrow the operation.
[[fallthrough]];
diff --git a/llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll b/llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll
index eb4ff7f290665e..0db9880ee6a292 100644
--- a/llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll
+++ b/llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll
@@ -14,9 +14,9 @@
define i64 @test_shl_by_2(i64 %x) {
; CHECK-LABEL: define i64 @test_shl_by_2(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[X]], 2
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[TMP2]]
; CHECK-NEXT: ret i64 [[MAX]]
;
%x1 = add i64 %x, 1
@@ -28,9 +28,9 @@ define i64 @test_shl_by_2(i64 %x) {
define i64 @test_shl_by_5(i64 %x) {
; CHECK-LABEL: define i64 @test_shl_by_5(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[X]], 5
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[TMP2]]
; CHECK-NEXT: ret i64 [[MAX]]
;
%x1 = add i64 %x, 1
@@ -42,9 +42,9 @@ define i64 @test_shl_by_5(i64 %x) {
define i64 @test_shl_with_nsw(i64 %x) {
; CHECK-LABEL: define i64 @test_shl_with_nsw(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i64 [[X]], 2
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[SHL]], i64 [[X1]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[SHL]]
; CHECK-NEXT: ret i64 [[MAX]]
;
%x1 = add i64 %x, 1
@@ -58,9 +58,9 @@ define i64 @test_shl_with_nsw(i64 %x) {
define i64 @test_shl_umax_commuted(i64 %x) {
; CHECK-LABEL: define i64 @test_shl_umax_commuted(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[X]], 2
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[X1]], i64 [[SHL]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[SHL]]
; CHECK-NEXT: ret i64 [[MAX]]
;
%x1 = add i64 %x, 1
@@ -148,10 +148,10 @@ define i64 @test_shl_multi_use_add(i64 %x) {
define i64 @test_shl_multi_use_shl(i64 %x) {
; CHECK-LABEL: define i64 @test_shl_multi_use_shl(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[X]], 2
; CHECK-NEXT: call void @use(i64 [[SHL]])
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[SHL]], i64 [[X1]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[SHL]]
; CHECK-NEXT: ret i64 [[MAX]]
;
%x1 = add i64 %x, 1
@@ -164,9 +164,9 @@ define i64 @test_shl_multi_use_shl(i64 %x) {
define i64 @test_shl_multi_use_max(i64 %x) {
; CHECK-LABEL: define i64 @test_shl_multi_use_max(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[X]], 3
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[TMP2]]
; CHECK-NEXT: call void @use(i64 [[MAX]])
; CHECK-NEXT: ret i64 [[MAX]]
;
@@ -182,9 +182,9 @@ define i64 @test_shl_multi_use_max(i64 %x) {
define i64 @test_mul_by_3(i64 %x) {
; CHECK-LABEL: define i64 @test_mul_by_3(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[MUL]]
; CHECK-NEXT: ret i64 [[MAX]]
;
%x1 = add i64 %x, 1
@@ -196,9 +196,9 @@ define i64 @test_mul_by_3(i64 %x) {
define i64 @test_mul_by_5(i64 %x) {
; CHECK-LABEL: define i64 @test_mul_by_5(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 5
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[MUL]]
; CHECK-NEXT: ret i64 [[MAX]]
;
%x1 = add i64 %x, 1
@@ -210,9 +210,9 @@ define i64 @test_mul_by_5(i64 %x) {
define i64 @test_mul_with_nsw(i64 %x) {
; CHECK-LABEL: define i64 @test_mul_with_nsw(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i64 [[X]], 3
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[MUL]]
; CHECK-NEXT: ret i64 [[MAX]]
;
%x1 = add i64 %x, 1
@@ -226,9 +226,9 @@ define i64 @test_mul_with_nsw(i64 %x) {
define i64 @test_mul_max_commuted(i64 %x) {
; CHECK-LABEL: define i64 @test_mul_max_commuted(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[X1]], i64 [[MUL]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[MUL]]
; CHECK-NEXT: ret i64 [[MAX]]
;
%x1 = add i64 %x, 1
@@ -327,10 +327,10 @@ define i64 @test_mul_multi_use_add(i64 %x) {
define i64 @test_mul_multi_use_mul(i64 %x) {
; CHECK-LABEL: define i64 @test_mul_multi_use_mul(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3
; CHECK-NEXT: call void @use(i64 [[MUL]])
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[MUL]]
; CHECK-NEXT: ret i64 [[MAX]]
;
%x1 = add i64 %x, 1
@@ -343,9 +343,9 @@ define i64 @test_mul_multi_use_mul(i64 %x) {
define i64 @test_mul_multi_use_max(i64 %x) {
; CHECK-LABEL: define i64 @test_mul_multi_use_max(
; CHECK-SAME: i64 [[X:%.*]]) {
-; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1
; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[X]], 3
-; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[TMP2]]
; CHECK-NEXT: call void @use(i64 [[MAX]])
; CHECK-NEXT: ret i64 [[MAX]]
;
More information about the llvm-commits
mailing list