From 3ea75f4f4aad38cbef547467265ca3d67c5245a6 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Thu, 13 Mar 2025 11:55:01 +0800 Subject: [PATCH 01/15] [InstCombine] Add pre-commit tests --- .../Transforms/InstCombine/shift-uminmax.ll | 240 ++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 llvm/test/Transforms/InstCombine/shift-uminmax.ll diff --git a/llvm/test/Transforms/InstCombine/shift-uminmax.ll b/llvm/test/Transforms/InstCombine/shift-uminmax.ll new file mode 100644 index 0000000000000..9e61f2f054867 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/shift-uminmax.ll @@ -0,0 +1,240 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +; For the following patterns: +; umax(nuw_shl(C0, x), nuw_shl(C0, y)) -> nuw_shl(C0, umax(x, y)) +; umin(nuw_shl(C0, x), nuw_shl(C0, y)) -> nuw_shl(C0, umin(x, y)) + +define i32 @test_umax_shl_const1(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umax_shl_const1( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 1, %x + %shl_y = shl nuw i32 1, %y + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @test_umin_shl_const1(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umin_shl_const1( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 1, %x + %shl_y = shl nuw i32 1, %y + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + +define i32 @test_umax_shl_const5(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umax_shl_const5( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 5, %x + %shl_y = shl nuw i32 5, %y + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @test_umin_shl_const5(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umin_shl_const5( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 5, %x + %shl_y = shl nuw i32 5, %y + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + +declare void @use(i8) + +define i32 @test_umax_shl_const1_multi_use(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umax_shl_const1_multi_use( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: call void @use(i32 [[SHL_X]]) +; CHECK-NEXT: call void @use(i32 [[SHL_Y]]) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 1, %x + %shl_y = shl nuw i32 1, %y + call void @use(i32 %shl_x) + call void @use(i32 %shl_y) + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @test_umin_shl_const1_multi_use(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umin_shl_const1_multi_use( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: call void @use(i32 [[SHL_X]]) +; CHECK-NEXT: call void @use(i32 [[SHL_Y]]) +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 1, %x + %shl_y = shl nuw i32 1, %y + call void @use(i32 %shl_x) + call void @use(i32 %shl_y) + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + +define i32 @test_umax_shl_const1_commuted(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umax_shl_const1_commuted( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 1, %x + %shl_y = shl nuw i32 1, %y + %max = call i32 @llvm.umax.i32(i32 %shl_y, i32 %shl_x) + ret i32 %max +} + +define i32 @test_umin_shl_const1_commuted(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umin_shl_const1_commuted( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 1, %x + %shl_y = shl nuw i32 1, %y + %min = call i32 @llvm.umin.i32(i32 %shl_y, i32 %shl_x) + ret i32 %min +} + +define <2 x i32> @test_umax_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_splat( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MAX]] +; + %shl_x = shl nuw <2 x i32> , %x + %shl_y = shl nuw <2 x i32> , %y + %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %max +} + +define <2 x i32> @test_umin_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector_splat( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MIN]] +; + %shl_x = shl nuw <2 x i32> , %x + %shl_y = shl nuw <2 x i32> , %y + %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %min +} + +define <2 x i32> @test_umax_shl_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_non_splat( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MAX]] +; + %shl_x = shl nuw <2 x i32> , %x + %shl_y = shl nuw <2 x i32> , %y + %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %max +} + +define <2 x i32> @test_umin_shl_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector_non_splat( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MIN]] +; + %shl_x = shl nuw <2 x i32> , %x + %shl_y = shl nuw <2 x i32> , %y + %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %min +} + +define i32 @test_umax_shl_different_base(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umax_shl_different_base( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 2, [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 1, %x + %shl_y = shl nuw i32 2, %y + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @test_umin_shl_different_base(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umin_shl_different_base( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 2, [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 1, %x + %shl_y = shl nuw i32 2, %y + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + +define i32 @test_umax_shl_no_nuw_flag(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umax_shl_no_nuw_flag( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl i32 2, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl i32 2, [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl i32 2, %x + %shl_y = shl i32 2, %y + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @test_umin_shl_no_nuw_flag(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umin_shl_no_nuw_flag( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl i32 2, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl i32 2, [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl i32 2, %x + %shl_y = shl i32 2, %y + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} From a11d23df4220cb181ac9a3aef181895d67b6fed9 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Thu, 13 Mar 2025 12:05:29 +0800 Subject: [PATCH 02/15] [InstCombine] Fold ` umax(nuw_shl(C0, x), nuw_shl(C0, y)) -> nuw_shl(C0, umax(x, y))` and `umin(nuw_shl(C0, x), nuw_shl(C0, y)) -> nuw_shl(C0, umin(x, y))` --- .../InstCombine/InstCombineCalls.cpp | 13 ++++++ .../Transforms/InstCombine/shift-uminmax.ll | 40 ++++++++----------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 63f2fd0a733ce..a36f01c98b900 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1887,6 +1887,19 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { if (Instruction *I = foldMaxMulShift(I1, I0)) return I; } + + // umax(nuw_shl(C0, x), nuw_shl(C0, y)) -> nuw_shl(C0, umax(x, y)) + // umin(nuw_shl(C0, x), nuw_shl(C0, y)) -> nuw_shl(C0, umin(x, y)) + const APInt *C1, *C2; + if (match(I0, m_OneUse(m_NUWShl(m_APInt(C1), m_Value()))) && + match(I1, m_OneUse(m_NUWShl(m_APInt(C2), m_Value()))) && *C1 == *C2) { + Value *X = cast(I0)->getOperand(1); + Value *Y = cast(I1)->getOperand(1); + Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y); + return BinaryOperator::CreateNUWShl(ConstantInt::get(I0->getType(), *C1), + MaxMin); + } + // 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/shift-uminmax.ll b/llvm/test/Transforms/InstCombine/shift-uminmax.ll index 9e61f2f054867..14c600579999d 100644 --- a/llvm/test/Transforms/InstCombine/shift-uminmax.ll +++ b/llvm/test/Transforms/InstCombine/shift-uminmax.ll @@ -8,9 +8,8 @@ define i32 @test_umax_shl_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umax_shl_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 1, [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 1, %x @@ -22,9 +21,8 @@ define i32 @test_umax_shl_const1(i32 %x, i32 %y) { define i32 @test_umin_shl_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umin_shl_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 1, [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 1, %x @@ -36,9 +34,8 @@ define i32 @test_umin_shl_const1(i32 %x, i32 %y) { define i32 @test_umax_shl_const5(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umax_shl_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 5, [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 5, %x @@ -50,9 +47,8 @@ define i32 @test_umax_shl_const5(i32 %x, i32 %y) { define i32 @test_umin_shl_const5(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umin_shl_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 5, [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 5, %x @@ -102,9 +98,8 @@ define i32 @test_umin_shl_const1_multi_use(i32 %x, i32 %y) { define i32 @test_umax_shl_const1_commuted(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umax_shl_const1_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 1, [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 1, %x @@ -116,9 +111,8 @@ define i32 @test_umax_shl_const1_commuted(i32 %x, i32 %y) { define i32 @test_umin_shl_const1_commuted(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umin_shl_const1_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 1, [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 1, %x @@ -130,9 +124,8 @@ define i32 @test_umin_shl_const1_commuted(i32 %x, i32 %y) { define <2 x i32> @test_umax_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> , %x @@ -144,9 +137,8 @@ define <2 x i32> @test_umax_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { define <2 x i32> @test_umin_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> , %x From ed5a722376609b619f08aa87e325ec9ae2c46527 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Thu, 13 Mar 2025 15:11:02 +0800 Subject: [PATCH 03/15] adjust test for variables as base --- .../Transforms/InstCombine/shift-uminmax.ll | 200 +++++++++++++----- 1 file changed, 146 insertions(+), 54 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/shift-uminmax.ll b/llvm/test/Transforms/InstCombine/shift-uminmax.ll index 14c600579999d..cfec5cd606dbf 100644 --- a/llvm/test/Transforms/InstCombine/shift-uminmax.ll +++ b/llvm/test/Transforms/InstCombine/shift-uminmax.ll @@ -2,14 +2,43 @@ ; RUN: opt < %s -passes=instcombine -S | FileCheck %s ; For the following patterns: -; umax(nuw_shl(C0, x), nuw_shl(C0, y)) -> nuw_shl(C0, umax(x, y)) -; umin(nuw_shl(C0, x), nuw_shl(C0, y)) -> nuw_shl(C0, umin(x, y)) +; umax(nuw_shl(base, x), nuw_shl(base, y)) -> nuw_shl(base, umax(x, y)) +; umin(nuw_shl(base, x), nuw_shl(base, y)) -> nuw_shl(base, umin(x, y)) + +define i32 @test_umax_shl(i32 %base, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umax_shl( +; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 %base, %x + %shl_y = shl nuw i32 %base, %y + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @test_umin_shl(i32 %base, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umin_shl( +; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 %base, %x + %shl_y = shl nuw i32 %base, %y + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} define i32 @test_umax_shl_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umax_shl_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 1, [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 1, %x @@ -21,8 +50,9 @@ define i32 @test_umax_shl_const1(i32 %x, i32 %y) { define i32 @test_umin_shl_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umin_shl_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 1, [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 1, %x @@ -34,8 +64,9 @@ define i32 @test_umin_shl_const1(i32 %x, i32 %y) { define i32 @test_umax_shl_const5(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umax_shl_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 5, [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 5, %x @@ -47,8 +78,9 @@ define i32 @test_umax_shl_const5(i32 %x, i32 %y) { define i32 @test_umin_shl_const5(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umin_shl_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 5, [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 5, %x @@ -59,73 +91,104 @@ define i32 @test_umin_shl_const5(i32 %x, i32 %y) { declare void @use(i8) -define i32 @test_umax_shl_const1_multi_use(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umax_shl_const1_multi_use( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +define i32 @test_umax_shl_multi_use(i32 %base, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umax_shl_multi_use( +; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] ; CHECK-NEXT: call void @use(i32 [[SHL_X]]) ; CHECK-NEXT: call void @use(i32 [[SHL_Y]]) ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; - %shl_x = shl nuw i32 1, %x - %shl_y = shl nuw i32 1, %y + %shl_x = shl nuw i32 %base, %x + %shl_y = shl nuw i32 %base, %y call void @use(i32 %shl_x) call void @use(i32 %shl_y) %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) ret i32 %max } -define i32 @test_umin_shl_const1_multi_use(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umin_shl_const1_multi_use( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +define i32 @test_umin_shl_multi_use(i32 %base, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umin_shl_multi_use( +; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] ; CHECK-NEXT: call void @use(i32 [[SHL_X]]) ; CHECK-NEXT: call void @use(i32 [[SHL_Y]]) ; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; - %shl_x = shl nuw i32 1, %x - %shl_y = shl nuw i32 1, %y + %shl_x = shl nuw i32 %base, %x + %shl_y = shl nuw i32 %base, %y call void @use(i32 %shl_x) call void @use(i32 %shl_y) %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) ret i32 %min } -define i32 @test_umax_shl_const1_commuted(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umax_shl_const1_commuted( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 [[X]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 1, [[TMP1]] +define i32 @test_umax_shl_commuted(i32 %base, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umax_shl_commuted( +; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) ; CHECK-NEXT: ret i32 [[MAX]] ; - %shl_x = shl nuw i32 1, %x - %shl_y = shl nuw i32 1, %y + %shl_x = shl nuw i32 %base, %x + %shl_y = shl nuw i32 %base, %y %max = call i32 @llvm.umax.i32(i32 %shl_y, i32 %shl_x) ret i32 %max } -define i32 @test_umin_shl_const1_commuted(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umin_shl_const1_commuted( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[Y]], i32 [[X]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 1, [[TMP1]] +define i32 @test_umin_shl_commuted(i32 %base, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umin_shl_commuted( +; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) ; CHECK-NEXT: ret i32 [[MIN]] ; - %shl_x = shl nuw i32 1, %x - %shl_y = shl nuw i32 1, %y + %shl_x = shl nuw i32 %base, %x + %shl_y = shl nuw i32 %base, %y %min = call i32 @llvm.umin.i32(i32 %shl_y, i32 %shl_x) ret i32 %min } +define <2 x i32> @test_umax_shl_vector(<2 x i32> %base, <2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector( +; CHECK-SAME: <2 x i32> [[BASE:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[BASE]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[BASE]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MAX]] +; + %shl_x = shl nuw <2 x i32> %base, %x + %shl_y = shl nuw <2 x i32> %base, %y + %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %max +} + +define <2 x i32> @test_umin_shl_vector(<2 x i32> %base, <2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector( +; CHECK-SAME: <2 x i32> [[BASE:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[BASE]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[BASE]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MIN]] +; + %shl_x = shl nuw <2 x i32> %base, %x + %shl_y = shl nuw <2 x i32> %base, %y + %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %min +} + define <2 x i32> @test_umax_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> , %x @@ -137,8 +200,9 @@ define <2 x i32> @test_umax_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { define <2 x i32> @test_umin_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> , %x @@ -147,6 +211,34 @@ define <2 x i32> @test_umin_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { ret <2 x i32> %min } +define <2 x i32> @test_umax_shl_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_splat_poison( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MAX]] +; + %shl_x = shl nuw <2 x i32> , %x + %shl_y = shl nuw <2 x i32> , %y + %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %max +} + +define <2 x i32> @test_umin_shl_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector_splat_poison( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MIN]] +; + %shl_x = shl nuw <2 x i32> , %x + %shl_y = shl nuw <2 x i32> , %y + %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %min +} + define <2 x i32> @test_umax_shl_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_non_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { @@ -175,30 +267,30 @@ define <2 x i32> @test_umin_shl_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { ret <2 x i32> %min } -define i32 @test_umax_shl_different_base(i32 %x, i32 %y) { +define i32 @test_umax_shl_different_base(i32 %base1, i32 %base2, i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umax_shl_different_base( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 2, [[Y]] +; CHECK-SAME: i32 [[BASE1:%.*]], i32 [[BASE2:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE1]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE2]], [[Y]] ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; - %shl_x = shl nuw i32 1, %x - %shl_y = shl nuw i32 2, %y + %shl_x = shl nuw i32 %base1, %x + %shl_y = shl nuw i32 %base2, %y %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) ret i32 %max } -define i32 @test_umin_shl_different_base(i32 %x, i32 %y) { +define i32 @test_umin_shl_different_base(i32 %base1, i32 %base2, i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umin_shl_different_base( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 2, [[Y]] +; CHECK-SAME: i32 [[BASE1:%.*]], i32 [[BASE2:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE1]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE2]], [[Y]] ; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; - %shl_x = shl nuw i32 1, %x - %shl_y = shl nuw i32 2, %y + %shl_x = shl nuw i32 %base1, %x + %shl_y = shl nuw i32 %base2, %y %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) ret i32 %min } From e09c615dead93dd606ee54d658168877e7488ec2 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Thu, 13 Mar 2025 15:15:10 +0800 Subject: [PATCH 04/15] adjust transformation for variables as base --- .../InstCombine/InstCombineCalls.cpp | 18 ++--- .../Transforms/InstCombine/shift-uminmax.ll | 80 ++++++++----------- 2 files changed, 40 insertions(+), 58 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index a36f01c98b900..5a7eb848199e6 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1888,16 +1888,14 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { return I; } - // umax(nuw_shl(C0, x), nuw_shl(C0, y)) -> nuw_shl(C0, umax(x, y)) - // umin(nuw_shl(C0, x), nuw_shl(C0, y)) -> nuw_shl(C0, umin(x, y)) - const APInt *C1, *C2; - if (match(I0, m_OneUse(m_NUWShl(m_APInt(C1), m_Value()))) && - match(I1, m_OneUse(m_NUWShl(m_APInt(C2), m_Value()))) && *C1 == *C2) { - Value *X = cast(I0)->getOperand(1); - Value *Y = cast(I1)->getOperand(1); - Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y); - return BinaryOperator::CreateNUWShl(ConstantInt::get(I0->getType(), *C1), - MaxMin); + // umax(nuw_shl(base, x), nuw_shl(base, y)) -> nuw_shl(base, umax(x, y)) + // umin(nuw_shl(base, x), nuw_shl(base, y)) -> nuw_shl(base, umin(x, y)) + Value *Base; + Value *Shamt1, *Shamt2; + if (match(I0, m_OneUse(m_NUWShl(m_Value(Base), m_Value(Shamt1)))) && + match(I1, m_OneUse(m_NUWShl(m_Deferred(Base), m_Value(Shamt2))))) { + Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, Shamt1, Shamt2); + return BinaryOperator::CreateNUWShl(Base, MaxMin); } // If both operands of unsigned min/max are sign-extended, it is still ok diff --git a/llvm/test/Transforms/InstCombine/shift-uminmax.ll b/llvm/test/Transforms/InstCombine/shift-uminmax.ll index cfec5cd606dbf..1aecbc1a3edfd 100644 --- a/llvm/test/Transforms/InstCombine/shift-uminmax.ll +++ b/llvm/test/Transforms/InstCombine/shift-uminmax.ll @@ -8,9 +8,8 @@ define i32 @test_umax_shl(i32 %base, i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umax_shl( ; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[BASE]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %base, %x @@ -22,9 +21,8 @@ define i32 @test_umax_shl(i32 %base, i32 %x, i32 %y) { define i32 @test_umin_shl(i32 %base, i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umin_shl( ; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[BASE]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %base, %x @@ -36,9 +34,8 @@ define i32 @test_umin_shl(i32 %base, i32 %x, i32 %y) { define i32 @test_umax_shl_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umax_shl_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 1, [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 1, %x @@ -50,9 +47,8 @@ define i32 @test_umax_shl_const1(i32 %x, i32 %y) { define i32 @test_umin_shl_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umin_shl_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 1, [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 1, %x @@ -64,9 +60,8 @@ define i32 @test_umin_shl_const1(i32 %x, i32 %y) { define i32 @test_umax_shl_const5(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umax_shl_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 5, [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 5, %x @@ -78,9 +73,8 @@ define i32 @test_umax_shl_const5(i32 %x, i32 %y) { define i32 @test_umin_shl_const5(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umin_shl_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 5, [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 5, %x @@ -130,9 +124,8 @@ define i32 @test_umin_shl_multi_use(i32 %base, i32 %x, i32 %y) { define i32 @test_umax_shl_commuted(i32 %base, i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umax_shl_commuted( ; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[BASE]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %base, %x @@ -144,9 +137,8 @@ define i32 @test_umax_shl_commuted(i32 %base, i32 %x, i32 %y) { define i32 @test_umin_shl_commuted(i32 %base, i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umin_shl_commuted( ; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[BASE]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %base, %x @@ -158,9 +150,8 @@ define i32 @test_umin_shl_commuted(i32 %base, i32 %x, i32 %y) { define <2 x i32> @test_umax_shl_vector(<2 x i32> %base, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector( ; CHECK-SAME: <2 x i32> [[BASE:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[BASE]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[BASE]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[BASE]], [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> %base, %x @@ -172,9 +163,8 @@ define <2 x i32> @test_umax_shl_vector(<2 x i32> %base, <2 x i32> %x, <2 x i32> define <2 x i32> @test_umin_shl_vector(<2 x i32> %base, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector( ; CHECK-SAME: <2 x i32> [[BASE:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[BASE]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[BASE]], [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[BASE]], [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> %base, %x @@ -186,9 +176,8 @@ define <2 x i32> @test_umin_shl_vector(<2 x i32> %base, <2 x i32> %x, <2 x i32> define <2 x i32> @test_umax_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> , %x @@ -200,9 +189,8 @@ define <2 x i32> @test_umax_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { define <2 x i32> @test_umin_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> , %x @@ -214,9 +202,8 @@ define <2 x i32> @test_umin_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { define <2 x i32> @test_umax_shl_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_splat_poison( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> , [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> , %x @@ -228,9 +215,8 @@ define <2 x i32> @test_umax_shl_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) define <2 x i32> @test_umin_shl_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector_splat_poison( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> , [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> , %x @@ -242,9 +228,8 @@ define <2 x i32> @test_umin_shl_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) define <2 x i32> @test_umax_shl_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_non_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> , [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> , %x @@ -256,9 +241,8 @@ define <2 x i32> @test_umax_shl_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { define <2 x i32> @test_umin_shl_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector_non_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> , [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> , %x From ff81d9b3307532600d9c74d445103206992a0a51 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Thu, 13 Mar 2025 16:48:49 +0800 Subject: [PATCH 05/15] update affected testcase --- llvm/test/Transforms/InstCombine/div-shift.ll | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/div-shift.ll b/llvm/test/Transforms/InstCombine/div-shift.ll index af83f37011ba0..fd857b983a788 100644 --- a/llvm/test/Transforms/InstCombine/div-shift.ll +++ b/llvm/test/Transforms/InstCombine/div-shift.ll @@ -144,11 +144,9 @@ define i8 @udiv_umin_(i8 %x, i8 %y, i8 %z) { ; Negative test, extra use define i8 @udiv_umin_extra_use(i8 %x, i8 %y, i8 %z) { ; CHECK-LABEL: @udiv_umin_extra_use( -; CHECK-NEXT: [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]] -; CHECK-NEXT: [[Z2:%.*]] = shl nuw i8 1, [[Z:%.*]] -; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[Z:%.*]]) +; CHECK-NEXT: [[M:%.*]] = shl nuw i8 1, [[TMP1]] ; CHECK-NEXT: call void @use(i8 [[M]]) -; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[M]], i1 true) ; CHECK-NEXT: [[D:%.*]] = lshr i8 [[X:%.*]], [[TMP1]] ; CHECK-NEXT: ret i8 [[D]] ; From 77d3461a9969826f6ae0ac94f985dad8379200d6 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Thu, 13 Mar 2025 16:53:36 +0800 Subject: [PATCH 06/15] add nsw flag testcase --- .../Transforms/InstCombine/shift-uminmax.ll | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/llvm/test/Transforms/InstCombine/shift-uminmax.ll b/llvm/test/Transforms/InstCombine/shift-uminmax.ll index 1aecbc1a3edfd..e90b7121dfb8a 100644 --- a/llvm/test/Transforms/InstCombine/shift-uminmax.ll +++ b/llvm/test/Transforms/InstCombine/shift-uminmax.ll @@ -306,3 +306,31 @@ define i32 @test_umin_shl_no_nuw_flag(i32 %x, i32 %y) { %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) ret i32 %min } + +define i32 @test_umax_shl_preserve_nsw(i32 %base, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umax_shl_preserve_nsw( +; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[BASE]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[BASE]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw nsw i32 %base, %x + %shl_y = shl nuw nsw i32 %base, %y + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @test_umin_shl_preserve_nsw(i32 %base, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @test_umin_shl_preserve_nsw( +; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[BASE]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[BASE]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw nsw i32 %base, %x + %shl_y = shl nuw nsw i32 %base, %y + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} From 27e0a48eaace911e899d36f3a911bc4481b5670d Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Thu, 13 Mar 2025 17:03:38 +0800 Subject: [PATCH 07/15] preserve nsw flag --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 6 +++++- llvm/test/Transforms/InstCombine/shift-uminmax.ll | 10 ++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 5a7eb848199e6..1bb797bbf07b0 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1895,7 +1895,11 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { if (match(I0, m_OneUse(m_NUWShl(m_Value(Base), m_Value(Shamt1)))) && match(I1, m_OneUse(m_NUWShl(m_Deferred(Base), m_Value(Shamt2))))) { Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, Shamt1, Shamt2); - return BinaryOperator::CreateNUWShl(Base, MaxMin); + auto *NewShl = BinaryOperator::CreateNUWShl(Base, MaxMin); + if (cast(I0)->hasNoSignedWrap() && + cast(I1)->hasNoSignedWrap()) + NewShl->setHasNoSignedWrap(); + return NewShl; } // If both operands of unsigned min/max are sign-extended, it is still ok diff --git a/llvm/test/Transforms/InstCombine/shift-uminmax.ll b/llvm/test/Transforms/InstCombine/shift-uminmax.ll index e90b7121dfb8a..be2c7a1b5b136 100644 --- a/llvm/test/Transforms/InstCombine/shift-uminmax.ll +++ b/llvm/test/Transforms/InstCombine/shift-uminmax.ll @@ -310,9 +310,8 @@ define i32 @test_umin_shl_no_nuw_flag(i32 %x, i32 %y) { define i32 @test_umax_shl_preserve_nsw(i32 %base, i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umax_shl_preserve_nsw( ; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[BASE]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[BASE]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw nsw i32 [[BASE]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw nsw i32 %base, %x @@ -324,9 +323,8 @@ define i32 @test_umax_shl_preserve_nsw(i32 %base, i32 %x, i32 %y) { define i32 @test_umin_shl_preserve_nsw(i32 %base, i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @test_umin_shl_preserve_nsw( ; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[BASE]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[BASE]], [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw nsw i32 [[BASE]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw nsw i32 %base, %x From 29309360452accfadcbd922756413d0bda5981ac Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Thu, 13 Mar 2025 17:26:39 +0800 Subject: [PATCH 08/15] add test for cases where rhs of shl are equal --- .../Transforms/InstCombine/shift-uminmax.ll | 627 ++++++++++++++---- 1 file changed, 496 insertions(+), 131 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/shift-uminmax.ll b/llvm/test/Transforms/InstCombine/shift-uminmax.ll index be2c7a1b5b136..8d812f07fcc8b 100644 --- a/llvm/test/Transforms/InstCombine/shift-uminmax.ll +++ b/llvm/test/Transforms/InstCombine/shift-uminmax.ll @@ -2,40 +2,73 @@ ; RUN: opt < %s -passes=instcombine -S | FileCheck %s ; For the following patterns: -; umax(nuw_shl(base, x), nuw_shl(base, y)) -> nuw_shl(base, umax(x, y)) -; umin(nuw_shl(base, x), nuw_shl(base, y)) -> nuw_shl(base, umin(x, y)) - -define i32 @test_umax_shl(i32 %base, i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umax_shl( -; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[BASE]], [[TMP1]] +; umax(nuw_shl(z, x), nuw_shl(z, y)) -> nuw_shl(z, umax(x, y)) +; umin(nuw_shl(z, x), nuw_shl(z, y)) -> nuw_shl(z, umin(x, y)) +; umax(nuw_shl(x, z), nuw_shl(y, z)) -> nuw_shl(umax(x, y), z) +; umin(nuw_shl(x, z), nuw_shl(y, z)) -> nuw_shl(umin(x, y), z) + +define i32 @umax_shl_common_lhs(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umax_shl_common_lhs( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 %z, %x + %shl_y = shl nuw i32 %z, %y + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @umax_shl_common_rhs(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umax_shl_common_rhs( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; - %shl_x = shl nuw i32 %base, %x - %shl_y = shl nuw i32 %base, %y + %shl_x = shl nuw i32 %x, %z + %shl_y = shl nuw i32 %y, %z %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) ret i32 %max } -define i32 @test_umin_shl(i32 %base, i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umin_shl( -; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[BASE]], [[TMP1]] +define i32 @umin_shl_common_lhs(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umin_shl_common_lhs( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 %z, %x + %shl_y = shl nuw i32 %z, %y + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + +define i32 @umin_shl_common_rhs(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umin_shl_common_rhs( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; - %shl_x = shl nuw i32 %base, %x - %shl_y = shl nuw i32 %base, %y + %shl_x = shl nuw i32 %x, %z + %shl_y = shl nuw i32 %y, %z %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) ret i32 %min } -define i32 @test_umax_shl_const1(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umax_shl_const1( +define i32 @umax_shl_common_lhs_const1(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umax_shl_common_lhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 1, [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 1, %x @@ -44,11 +77,26 @@ define i32 @test_umax_shl_const1(i32 %x, i32 %y) { ret i32 %max } -define i32 @test_umin_shl_const1(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umin_shl_const1( +define i32 @umax_shl_common_rhs_const1(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umax_shl_common_rhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 1, [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 1 +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 1 +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 %x, 1 + %shl_y = shl nuw i32 %y, 1 + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @umin_shl_common_lhs_const1(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umin_shl_common_lhs_const1( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 1, %x @@ -57,11 +105,26 @@ define i32 @test_umin_shl_const1(i32 %x, i32 %y) { ret i32 %min } -define i32 @test_umax_shl_const5(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umax_shl_const5( +define i32 @umin_shl_common_rhs_const1(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umin_shl_common_rhs_const1( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 1 +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 1 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 %x, 1 + %shl_y = shl nuw i32 %y, 1 + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + +define i32 @umax_shl_common_lhs_const5(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umax_shl_common_lhs_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 5, [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 5, %x @@ -70,11 +133,26 @@ define i32 @test_umax_shl_const5(i32 %x, i32 %y) { ret i32 %max } -define i32 @test_umin_shl_const5(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umin_shl_const5( +define i32 @umax_shl_common_rhs_const5(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umax_shl_common_rhs_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 5, [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 5 +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 5 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 %x, 5 + %shl_y = shl nuw i32 %y, 5 + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + +define i32 @umin_shl_common_lhs_const5(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umin_shl_common_lhs_const5( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 5, %x @@ -83,101 +161,213 @@ define i32 @test_umin_shl_const5(i32 %x, i32 %y) { ret i32 %min } +define i32 @umin_shl_common_rhs_const5(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umin_shl_common_rhs_const5( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 5 +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 5 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 %x, 5 + %shl_y = shl nuw i32 %y, 5 + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + declare void @use(i8) -define i32 @test_umax_shl_multi_use(i32 %base, i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umax_shl_multi_use( -; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] +define i32 @umax_shl_common_lhs_multi_use(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umax_shl_common_lhs_multi_use( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] +; CHECK-NEXT: call void @use(i32 [[SHL_X]]) +; CHECK-NEXT: call void @use(i32 [[SHL_Y]]) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 %z, %x + %shl_y = shl nuw i32 %z, %y + call void @use(i32 %shl_x) + call void @use(i32 %shl_y) + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @umax_shl_common_rhs_multi_use(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umax_shl_common_rhs_multi_use( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] ; CHECK-NEXT: call void @use(i32 [[SHL_X]]) ; CHECK-NEXT: call void @use(i32 [[SHL_Y]]) ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; - %shl_x = shl nuw i32 %base, %x - %shl_y = shl nuw i32 %base, %y + %shl_x = shl nuw i32 %x, %z + %shl_y = shl nuw i32 %y, %z call void @use(i32 %shl_x) call void @use(i32 %shl_y) %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) ret i32 %max } -define i32 @test_umin_shl_multi_use(i32 %base, i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umin_shl_multi_use( -; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE]], [[Y]] +define i32 @umin_shl_common_lhs_multi_use(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umin_shl_common_lhs_multi_use( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] ; CHECK-NEXT: call void @use(i32 [[SHL_X]]) ; CHECK-NEXT: call void @use(i32 [[SHL_Y]]) ; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; - %shl_x = shl nuw i32 %base, %x - %shl_y = shl nuw i32 %base, %y + %shl_x = shl nuw i32 %z, %x + %shl_y = shl nuw i32 %z, %y call void @use(i32 %shl_x) call void @use(i32 %shl_y) %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) ret i32 %min } -define i32 @test_umax_shl_commuted(i32 %base, i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umax_shl_commuted( -; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 [[X]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[BASE]], [[TMP1]] +define i32 @umin_shl_common_rhs_multi_use(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umin_shl_common_rhs_multi_use( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] +; CHECK-NEXT: call void @use(i32 [[SHL_X]]) +; CHECK-NEXT: call void @use(i32 [[SHL_Y]]) +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 %x, %z + %shl_y = shl nuw i32 %y, %z + call void @use(i32 %shl_x) + call void @use(i32 %shl_y) + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + +define i32 @umax_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umax_shl_common_lhs_commuted( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 %z, %x + %shl_y = shl nuw i32 %z, %y + %max = call i32 @llvm.umax.i32(i32 %shl_y, i32 %shl_x) + ret i32 %max +} + +define i32 @umax_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umax_shl_common_rhs_commuted( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) ; CHECK-NEXT: ret i32 [[MAX]] ; - %shl_x = shl nuw i32 %base, %x - %shl_y = shl nuw i32 %base, %y + %shl_x = shl nuw i32 %x, %z + %shl_y = shl nuw i32 %y, %z %max = call i32 @llvm.umax.i32(i32 %shl_y, i32 %shl_x) ret i32 %max } -define i32 @test_umin_shl_commuted(i32 %base, i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umin_shl_commuted( -; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[Y]], i32 [[X]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[BASE]], [[TMP1]] +define i32 @umin_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umin_shl_common_lhs_commuted( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) ; CHECK-NEXT: ret i32 [[MIN]] ; - %shl_x = shl nuw i32 %base, %x - %shl_y = shl nuw i32 %base, %y + %shl_x = shl nuw i32 %z, %x + %shl_y = shl nuw i32 %z, %y %min = call i32 @llvm.umin.i32(i32 %shl_y, i32 %shl_x) ret i32 %min } -define <2 x i32> @test_umax_shl_vector(<2 x i32> %base, <2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector( -; CHECK-SAME: <2 x i32> [[BASE:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[BASE]], [[TMP1]] +define i32 @umin_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umin_shl_common_rhs_commuted( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 %x, %z + %shl_y = shl nuw i32 %y, %z + %min = call i32 @llvm.umin.i32(i32 %shl_y, i32 %shl_x) + ret i32 %min +} + +define <2 x i32> @umax_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector( +; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Z]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; - %shl_x = shl nuw <2 x i32> %base, %x - %shl_y = shl nuw <2 x i32> %base, %y + %shl_x = shl nuw <2 x i32> %z, %x + %shl_y = shl nuw <2 x i32> %z, %y %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) ret <2 x i32> %max } -define <2 x i32> @test_umin_shl_vector(<2 x i32> %base, <2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector( -; CHECK-SAME: <2 x i32> [[BASE:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[BASE]], [[TMP1]] +define <2 x i32> @umax_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector( +; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], [[Z]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MAX]] +; + %shl_x = shl nuw <2 x i32> %x, %z + %shl_y = shl nuw <2 x i32> %y, %z + %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %max +} + + +define <2 x i32> @umin_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector( +; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Z]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MIN]] +; + %shl_x = shl nuw <2 x i32> %z, %x + %shl_y = shl nuw <2 x i32> %z, %y + %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %min +} + +define <2 x i32> @umin_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector( +; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], [[Z]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; - %shl_x = shl nuw <2 x i32> %base, %x - %shl_y = shl nuw <2 x i32> %base, %y + %shl_x = shl nuw <2 x i32> %x, %z + %shl_y = shl nuw <2 x i32> %y, %z %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) ret <2 x i32> %min } -define <2 x i32> @test_umax_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_splat( +define <2 x i32> @umax_shl_common_lhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> , %x @@ -186,11 +376,26 @@ define <2 x i32> @test_umax_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { ret <2 x i32> %max } -define <2 x i32> @test_umin_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector_splat( +define <2 x i32> @umax_shl_common_rhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector_splat( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MAX]] +; + %shl_x = shl nuw <2 x i32> %x, + %shl_y = shl nuw <2 x i32> %y, + %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %max +} + +define <2 x i32> @umin_shl_common_lhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> , %x @@ -199,11 +404,26 @@ define <2 x i32> @test_umin_shl_vector_splat(<2 x i32> %x, <2 x i32> %y) { ret <2 x i32> %min } -define <2 x i32> @test_umax_shl_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_splat_poison( +define <2 x i32> @umin_shl_common_rhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector_splat( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MIN]] +; + %shl_x = shl nuw <2 x i32> %x, + %shl_y = shl nuw <2 x i32> %y, + %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %min +} + +define <2 x i32> @umax_shl_common_lhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector_splat_poison( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> , [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> , %x @@ -212,11 +432,26 @@ define <2 x i32> @test_umax_shl_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) ret <2 x i32> %max } -define <2 x i32> @test_umin_shl_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector_splat_poison( +define <2 x i32> @umax_shl_common_rhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector_splat_poison( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> , [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MAX]] +; + %shl_x = shl nuw <2 x i32> %x, + %shl_y = shl nuw <2 x i32> %y, + %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %max +} + +define <2 x i32> @umin_shl_common_lhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector_splat_poison( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> , %x @@ -225,11 +460,26 @@ define <2 x i32> @test_umin_shl_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) ret <2 x i32> %min } -define <2 x i32> @test_umax_shl_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @test_umax_shl_vector_non_splat( +define <2 x i32> @umin_shl_common_rhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector_splat_poison( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MIN]] +; + %shl_x = shl nuw <2 x i32> %x, + %shl_y = shl nuw <2 x i32> %y, + %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %min +} + +define <2 x i32> @umax_shl_common_lhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector_non_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> , [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> , %x @@ -238,11 +488,26 @@ define <2 x i32> @test_umax_shl_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { ret <2 x i32> %max } -define <2 x i32> @test_umin_shl_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @test_umin_shl_vector_non_splat( +define <2 x i32> @umax_shl_common_rhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector_non_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> , [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MAX]] +; + %shl_x = shl nuw <2 x i32> %x, + %shl_y = shl nuw <2 x i32> %y, + %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %max +} + +define <2 x i32> @umin_shl_common_lhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector_non_splat( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> , %x @@ -251,36 +516,78 @@ define <2 x i32> @test_umin_shl_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { ret <2 x i32> %min } -define i32 @test_umax_shl_different_base(i32 %base1, i32 %base2, i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umax_shl_different_base( -; CHECK-SAME: i32 [[BASE1:%.*]], i32 [[BASE2:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE1]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE2]], [[Y]] +define <2 x i32> @umin_shl_common_rhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector_non_splat( +; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: ret <2 x i32> [[MIN]] +; + %shl_x = shl nuw <2 x i32> %x, + %shl_y = shl nuw <2 x i32> %y, + %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) + ret <2 x i32> %min +} + +define i32 @umax_shl_different_lhs(i32 %z1, i32 %z2, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umax_shl_different_lhs( +; CHECK-SAME: i32 [[Z1:%.*]], i32 [[Z2:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z1]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z2]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 %z1, %x + %shl_y = shl nuw i32 %z2, %y + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @umax_shl_different_rhs(i32 %z1, i32 %z2, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umax_shl_different_rhs( +; CHECK-SAME: i32 [[Z1:%.*]], i32 [[Z2:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z1]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z2]] ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; - %shl_x = shl nuw i32 %base1, %x - %shl_y = shl nuw i32 %base2, %y + %shl_x = shl nuw i32 %x, %z1 + %shl_y = shl nuw i32 %y, %z2 %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) ret i32 %max } -define i32 @test_umin_shl_different_base(i32 %base1, i32 %base2, i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umin_shl_different_base( -; CHECK-SAME: i32 [[BASE1:%.*]], i32 [[BASE2:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[BASE1]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[BASE2]], [[Y]] +define i32 @umin_shl_different_lhs(i32 %z1, i32 %z2, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umin_shl_different_lhs( +; CHECK-SAME: i32 [[Z1:%.*]], i32 [[Z2:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z1]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z2]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 %z1, %x + %shl_y = shl nuw i32 %z2, %y + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + +define i32 @umin_shl_different_rhs(i32 %z1, i32 %z2, i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umin_shl_different_rhs( +; CHECK-SAME: i32 [[Z1:%.*]], i32 [[Z2:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z1]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z2]] ; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; - %shl_x = shl nuw i32 %base1, %x - %shl_y = shl nuw i32 %base2, %y + %shl_x = shl nuw i32 %x, %z1 + %shl_y = shl nuw i32 %y, %z2 %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) ret i32 %min } -define i32 @test_umax_shl_no_nuw_flag(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umax_shl_no_nuw_flag( +define i32 @umax_shl_common_lhs_no_nuw_flag(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umax_shl_common_lhs_no_nuw_flag( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[SHL_X:%.*]] = shl i32 2, [[X]] ; CHECK-NEXT: [[SHL_Y:%.*]] = shl i32 2, [[Y]] @@ -293,8 +600,22 @@ define i32 @test_umax_shl_no_nuw_flag(i32 %x, i32 %y) { ret i32 %max } -define i32 @test_umin_shl_no_nuw_flag(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umin_shl_no_nuw_flag( +define i32 @umax_shl_common_rhs_no_nuw_flag(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umax_shl_common_rhs_no_nuw_flag( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl i32 [[X]], 2 +; CHECK-NEXT: [[SHL_Y:%.*]] = shl i32 [[Y]], 2 +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl i32 %x, 2 + %shl_y = shl i32 %y, 2 + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @umin_shl_common_lhs_no_nuw_flag(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umin_shl_common_lhs_no_nuw_flag( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[SHL_X:%.*]] = shl i32 2, [[X]] ; CHECK-NEXT: [[SHL_Y:%.*]] = shl i32 2, [[Y]] @@ -307,28 +628,72 @@ define i32 @test_umin_shl_no_nuw_flag(i32 %x, i32 %y) { ret i32 %min } -define i32 @test_umax_shl_preserve_nsw(i32 %base, i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umax_shl_preserve_nsw( -; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw nsw i32 [[BASE]], [[TMP1]] +define i32 @umin_shl_common_rhs_no_nuw_flag(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @umin_shl_common_rhs_no_nuw_flag( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl i32 [[X]], 2 +; CHECK-NEXT: [[SHL_Y:%.*]] = shl i32 [[Y]], 2 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl i32 %x, 2 + %shl_y = shl i32 %y, 2 + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + +define i32 @umax_shl_common_lhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umax_shl_common_lhs_preserve_nsw( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[Z]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; - %shl_x = shl nuw nsw i32 %base, %x - %shl_y = shl nuw nsw i32 %base, %y + %shl_x = shl nuw nsw i32 %z, %x + %shl_y = shl nuw nsw i32 %z, %y %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) ret i32 %max } -define i32 @test_umin_shl_preserve_nsw(i32 %base, i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @test_umin_shl_preserve_nsw( -; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw nsw i32 [[BASE]], [[TMP1]] +define i32 @umax_shl_common_rhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umax_shl_common_rhs_preserve_nsw( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw nsw i32 %x, %z + %shl_y = shl nuw nsw i32 %y, %z + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @umin_shl_common_lhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umin_shl_common_lhs_preserve_nsw( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[Z]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw nsw i32 %z, %x + %shl_y = shl nuw nsw i32 %z, %y + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + +define i32 @umin_shl_common_rhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umin_shl_common_rhs_preserve_nsw( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; - %shl_x = shl nuw nsw i32 %base, %x - %shl_y = shl nuw nsw i32 %base, %y + %shl_x = shl nuw nsw i32 %x, %z + %shl_y = shl nuw nsw i32 %y, %z %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) ret i32 %min } From fe32b6fb6100ee26ade697a60cdf06c7086ce1ff Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Thu, 13 Mar 2025 21:43:08 +0800 Subject: [PATCH 09/15] support cases where rhs are equal --- .../InstCombine/InstCombineCalls.cpp | 25 ++- .../Transforms/InstCombine/shift-uminmax.ll | 180 +++++++----------- 2 files changed, 89 insertions(+), 116 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 1bb797bbf07b0..a81ce7ebae176 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1888,14 +1888,23 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { return I; } - // umax(nuw_shl(base, x), nuw_shl(base, y)) -> nuw_shl(base, umax(x, y)) - // umin(nuw_shl(base, x), nuw_shl(base, y)) -> nuw_shl(base, umin(x, y)) - Value *Base; - Value *Shamt1, *Shamt2; - if (match(I0, m_OneUse(m_NUWShl(m_Value(Base), m_Value(Shamt1)))) && - match(I1, m_OneUse(m_NUWShl(m_Deferred(Base), m_Value(Shamt2))))) { - Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, Shamt1, Shamt2); - auto *NewShl = BinaryOperator::CreateNUWShl(Base, MaxMin); + Value *CommonShlOperand; + BinaryOperator *NewShl = nullptr; + // umax(nuw_shl(z, x), nuw_shl(z, y)) -> nuw_shl(z, umax(x, y)) + // umin(nuw_shl(z, x), nuw_shl(z, y)) -> nuw_shl(z, umin(x, y)) + if (match(I0, m_OneUse(m_NUWShl(m_Value(CommonShlOperand), m_Value(X)))) && + match(I1, + m_OneUse(m_NUWShl(m_Deferred(CommonShlOperand), m_Value(Y))))) { + Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y); + NewShl = BinaryOperator::CreateNUWShl(CommonShlOperand, MaxMin); + } else if (match(I0, m_OneUse(m_NUWShl(m_Value(X), + m_Value(CommonShlOperand)))) && + match(I1, m_OneUse(m_NUWShl(m_Value(Y), + m_Deferred(CommonShlOperand))))) { + Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y); + NewShl = BinaryOperator::CreateNUWShl(MaxMin, CommonShlOperand); + } + if (NewShl) { if (cast(I0)->hasNoSignedWrap() && cast(I1)->hasNoSignedWrap()) NewShl->setHasNoSignedWrap(); diff --git a/llvm/test/Transforms/InstCombine/shift-uminmax.ll b/llvm/test/Transforms/InstCombine/shift-uminmax.ll index 8d812f07fcc8b..4a4c751e57081 100644 --- a/llvm/test/Transforms/InstCombine/shift-uminmax.ll +++ b/llvm/test/Transforms/InstCombine/shift-uminmax.ll @@ -10,9 +10,8 @@ define i32 @umax_shl_common_lhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[Z]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %z, %x @@ -24,9 +23,8 @@ define i32 @umax_shl_common_lhs(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_rhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[TMP1]], [[Z]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %x, %z @@ -38,9 +36,8 @@ define i32 @umax_shl_common_rhs(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_lhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_lhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[Z]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %z, %x @@ -52,9 +49,8 @@ define i32 @umin_shl_common_lhs(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_rhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_rhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], [[Z]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %x, %z @@ -66,9 +62,8 @@ define i32 @umin_shl_common_rhs(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_lhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 1, [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 1, %x @@ -80,9 +75,8 @@ define i32 @umax_shl_common_lhs_const1(i32 %x, i32 %y) { define i32 @umax_shl_common_rhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 1 -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 1 -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[TMP1]], 1 ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %x, 1 @@ -94,9 +88,8 @@ define i32 @umax_shl_common_rhs_const1(i32 %x, i32 %y) { define i32 @umin_shl_common_lhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umin_shl_common_lhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 1, [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 1, %x @@ -108,9 +101,8 @@ define i32 @umin_shl_common_lhs_const1(i32 %x, i32 %y) { define i32 @umin_shl_common_rhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umin_shl_common_rhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 1 -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 1 -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], 1 ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %x, 1 @@ -122,9 +114,8 @@ define i32 @umin_shl_common_rhs_const1(i32 %x, i32 %y) { define i32 @umax_shl_common_lhs_const5(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 5, [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 5, %x @@ -136,9 +127,8 @@ define i32 @umax_shl_common_lhs_const5(i32 %x, i32 %y) { define i32 @umax_shl_common_rhs_const5(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 5 -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 5 -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], 5 ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %x, 5 @@ -150,9 +140,8 @@ define i32 @umax_shl_common_rhs_const5(i32 %x, i32 %y) { define i32 @umin_shl_common_lhs_const5(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umin_shl_common_lhs_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 5, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 5, [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 5, [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 5, %x @@ -164,9 +153,8 @@ define i32 @umin_shl_common_lhs_const5(i32 %x, i32 %y) { define i32 @umin_shl_common_rhs_const5(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umin_shl_common_rhs_const5( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 5 -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 5 -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], 5 ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %x, 5 @@ -252,9 +240,8 @@ define i32 @umin_shl_common_rhs_multi_use(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[Z]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %z, %x @@ -266,9 +253,8 @@ define i32 @umax_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[TMP1]], [[Z]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %x, %z @@ -280,9 +266,8 @@ define i32 @umax_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_lhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[Z]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %z, %x @@ -294,9 +279,8 @@ define i32 @umin_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_rhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], [[Z]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %x, %z @@ -308,9 +292,8 @@ define i32 @umin_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { define <2 x i32> @umax_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Z]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[Z]], [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> %z, %x @@ -322,9 +305,8 @@ define <2 x i32> @umax_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i3 define <2 x i32> @umax_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], [[Z]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[TMP1]], [[Z]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> %x, %z @@ -337,9 +319,8 @@ define <2 x i32> @umax_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i3 define <2 x i32> @umin_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Z]], [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[Z]], [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> %z, %x @@ -351,9 +332,8 @@ define <2 x i32> @umin_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i3 define <2 x i32> @umin_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], [[Z]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[TMP1]], [[Z]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> %x, %z @@ -365,9 +345,8 @@ define <2 x i32> @umin_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i3 define <2 x i32> @umax_shl_common_lhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> , %x @@ -379,9 +358,8 @@ define <2 x i32> @umax_shl_common_lhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { define <2 x i32> @umax_shl_common_rhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[TMP1]], splat (i32 1) ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> %x, @@ -393,9 +371,8 @@ define <2 x i32> @umax_shl_common_rhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { define <2 x i32> @umin_shl_common_lhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> , %x @@ -407,9 +384,8 @@ define <2 x i32> @umin_shl_common_lhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { define <2 x i32> @umin_shl_common_rhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[TMP1]], splat (i32 1) ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> %x, @@ -421,9 +397,8 @@ define <2 x i32> @umin_shl_common_rhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { define <2 x i32> @umax_shl_common_lhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector_splat_poison( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> , [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> , %x @@ -435,9 +410,8 @@ define <2 x i32> @umax_shl_common_lhs_vector_splat_poison(<2 x i32> %x, <2 x i32 define <2 x i32> @umax_shl_common_rhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector_splat_poison( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[TMP1]], ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> %x, @@ -449,9 +423,8 @@ define <2 x i32> @umax_shl_common_rhs_vector_splat_poison(<2 x i32> %x, <2 x i32 define <2 x i32> @umin_shl_common_lhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector_splat_poison( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> , [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> , %x @@ -463,9 +436,8 @@ define <2 x i32> @umin_shl_common_lhs_vector_splat_poison(<2 x i32> %x, <2 x i32 define <2 x i32> @umin_shl_common_rhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector_splat_poison( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[TMP1]], ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> %x, @@ -477,9 +449,8 @@ define <2 x i32> @umin_shl_common_rhs_vector_splat_poison(<2 x i32> %x, <2 x i32 define <2 x i32> @umax_shl_common_lhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector_non_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> , [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> , %x @@ -491,9 +462,8 @@ define <2 x i32> @umax_shl_common_lhs_vector_non_splat(<2 x i32> %x, <2 x i32> % define <2 x i32> @umax_shl_common_rhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector_non_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[TMP1]], ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> %x, @@ -505,9 +475,8 @@ define <2 x i32> @umax_shl_common_rhs_vector_non_splat(<2 x i32> %x, <2 x i32> % define <2 x i32> @umin_shl_common_lhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector_non_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> , [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> , [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> , [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> , %x @@ -519,9 +488,8 @@ define <2 x i32> @umin_shl_common_lhs_vector_non_splat(<2 x i32> %x, <2 x i32> % define <2 x i32> @umin_shl_common_rhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector_non_splat( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[TMP1]], ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> %x, @@ -645,9 +613,8 @@ define i32 @umin_shl_common_rhs_no_nuw_flag(i32 %x, i32 %y) { define i32 @umax_shl_common_lhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs_preserve_nsw( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[Z]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw nsw i32 [[Z]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw nsw i32 %z, %x @@ -659,9 +626,8 @@ define i32 @umax_shl_common_lhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_rhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs_preserve_nsw( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[Y]], [[Z]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw nsw i32 [[TMP1]], [[Z]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw nsw i32 %x, %z @@ -673,9 +639,8 @@ define i32 @umax_shl_common_rhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_lhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_lhs_preserve_nsw( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[Z]], [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw nsw i32 [[Z]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw nsw i32 %z, %x @@ -687,9 +652,8 @@ define i32 @umin_shl_common_lhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_rhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_rhs_preserve_nsw( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[Y]], [[Z]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw nsw i32 [[TMP1]], [[Z]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw nsw i32 %x, %z From 080fc1d62f84f5938c039694c746a593deb0577b Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Fri, 14 Mar 2025 18:46:16 +0800 Subject: [PATCH 10/15] refactor into `foldIntrinsicUsingDistributiveLaws` --- .../InstCombine/InstCombineCalls.cpp | 64 ++++++++----------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index a81ce7ebae176..37c2015f59c12 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1554,7 +1554,11 @@ static bool leftDistributesOverRight(Instruction::BinaryOps LOp, bool HasNUW, switch (ROp) { case Intrinsic::umax: case Intrinsic::umin: - return HasNUW && LOp == Instruction::Add; + if (HasNUW && LOp == Instruction::Add) + return true; + if (HasNUW && LOp == Instruction::Shl) + return true; + return false; case Intrinsic::smax: case Intrinsic::smin: return HasNSW && LOp == Instruction::Add; @@ -1592,29 +1596,34 @@ foldIntrinsicUsingDistributiveLaws(IntrinsicInst *II, if (!leftDistributesOverRight(InnerOpcode, HasNUW, HasNSW, TopLevelOpcode)) return nullptr; - assert(II->isCommutative() && Op0->isCommutative() && - "Only inner and outer commutative op codes are supported."); - Value *A = Op0->getOperand(0); Value *B = Op0->getOperand(1); Value *C = Op1->getOperand(0); Value *D = Op1->getOperand(1); - // Attempts to swap variables such that A always equals C - if (A != C && A != D) - std::swap(A, B); - if (A == C || A == D) { - if (A != C) - std::swap(C, D); + // Attempts to swap variables such that A equals C or B equals D, + // if the inner operation is commutative. + if (Op0->isCommutative() && A != C && B != D && A == D) + std::swap(C, D); + + if (A != C && B != D) + return nullptr; + + BinaryOperator *NewBinop; + if (A == C) { Value *NewIntrinsic = Builder.CreateBinaryIntrinsic(TopLevelOpcode, B, D); - BinaryOperator *NewBinop = - cast(Builder.CreateBinOp(InnerOpcode, NewIntrinsic, A)); - NewBinop->setHasNoSignedWrap(HasNSW); - NewBinop->setHasNoUnsignedWrap(HasNUW); - return NewBinop; + NewBinop = + cast(Builder.CreateBinOp(InnerOpcode, A, NewIntrinsic)); + } else { // B == D + Value *NewIntrinsic = Builder.CreateBinaryIntrinsic(TopLevelOpcode, A, C); + NewBinop = + cast(Builder.CreateBinOp(InnerOpcode, NewIntrinsic, B)); } - return nullptr; + NewBinop->setHasNoUnsignedWrap(HasNUW); + NewBinop->setHasNoSignedWrap(HasNSW); + + return NewBinop; } /// CallInst simplification. This mostly only handles folding of intrinsic @@ -1888,29 +1897,6 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { return I; } - Value *CommonShlOperand; - BinaryOperator *NewShl = nullptr; - // umax(nuw_shl(z, x), nuw_shl(z, y)) -> nuw_shl(z, umax(x, y)) - // umin(nuw_shl(z, x), nuw_shl(z, y)) -> nuw_shl(z, umin(x, y)) - if (match(I0, m_OneUse(m_NUWShl(m_Value(CommonShlOperand), m_Value(X)))) && - match(I1, - m_OneUse(m_NUWShl(m_Deferred(CommonShlOperand), m_Value(Y))))) { - Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y); - NewShl = BinaryOperator::CreateNUWShl(CommonShlOperand, MaxMin); - } else if (match(I0, m_OneUse(m_NUWShl(m_Value(X), - m_Value(CommonShlOperand)))) && - match(I1, m_OneUse(m_NUWShl(m_Value(Y), - m_Deferred(CommonShlOperand))))) { - Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y); - NewShl = BinaryOperator::CreateNUWShl(MaxMin, CommonShlOperand); - } - if (NewShl) { - if (cast(I0)->hasNoSignedWrap() && - cast(I1)->hasNoSignedWrap()) - NewShl->setHasNoSignedWrap(); - return NewShl; - } - // If both operands of unsigned min/max are sign-extended, it is still ok // to narrow the operation. [[fallthrough]]; From 3133f1dd016b147c9bd86f228596940d3125e5b9 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Fri, 14 Mar 2025 20:14:41 +0800 Subject: [PATCH 11/15] update tests --- .../Transforms/InstCombine/shift-uminmax.ll | 392 ++++-------------- 1 file changed, 82 insertions(+), 310 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/shift-uminmax.ll b/llvm/test/Transforms/InstCombine/shift-uminmax.ll index 4a4c751e57081..5b8df460073f7 100644 --- a/llvm/test/Transforms/InstCombine/shift-uminmax.ll +++ b/llvm/test/Transforms/InstCombine/shift-uminmax.ll @@ -10,8 +10,9 @@ define i32 @umax_shl_common_lhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[Z]], [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %z, %x @@ -23,8 +24,9 @@ define i32 @umax_shl_common_lhs(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_rhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[TMP1]], [[Z]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %x, %z @@ -36,8 +38,9 @@ define i32 @umax_shl_common_rhs(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_lhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_lhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[Z]], [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %z, %x @@ -49,8 +52,9 @@ define i32 @umin_shl_common_lhs(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_rhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_rhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], [[Z]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %x, %z @@ -62,8 +66,9 @@ define i32 @umin_shl_common_rhs(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_lhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 1, [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 1, %x @@ -75,8 +80,9 @@ define i32 @umax_shl_common_lhs_const1(i32 %x, i32 %y) { define i32 @umax_shl_common_rhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[TMP1]], 1 +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 1 +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 1 +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %x, 1 @@ -88,8 +94,9 @@ define i32 @umax_shl_common_rhs_const1(i32 %x, i32 %y) { define i32 @umin_shl_common_lhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umin_shl_common_lhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 1, [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 1, %x @@ -101,8 +108,9 @@ define i32 @umin_shl_common_lhs_const1(i32 %x, i32 %y) { define i32 @umin_shl_common_rhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umin_shl_common_rhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], 1 +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 1 +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 1 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %x, 1 @@ -111,58 +119,6 @@ define i32 @umin_shl_common_rhs_const1(i32 %x, i32 %y) { ret i32 %min } -define i32 @umax_shl_common_lhs_const5(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @umax_shl_common_lhs_const5( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 5, [[TMP1]] -; CHECK-NEXT: ret i32 [[MAX]] -; - %shl_x = shl nuw i32 5, %x - %shl_y = shl nuw i32 5, %y - %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) - ret i32 %max -} - -define i32 @umax_shl_common_rhs_const5(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @umax_shl_common_rhs_const5( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], 5 -; CHECK-NEXT: ret i32 [[MIN]] -; - %shl_x = shl nuw i32 %x, 5 - %shl_y = shl nuw i32 %y, 5 - %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) - ret i32 %min -} - -define i32 @umin_shl_common_lhs_const5(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @umin_shl_common_lhs_const5( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 5, [[TMP1]] -; CHECK-NEXT: ret i32 [[MIN]] -; - %shl_x = shl nuw i32 5, %x - %shl_y = shl nuw i32 5, %y - %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) - ret i32 %min -} - -define i32 @umin_shl_common_rhs_const5(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @umin_shl_common_rhs_const5( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], 5 -; CHECK-NEXT: ret i32 [[MIN]] -; - %shl_x = shl nuw i32 %x, 5 - %shl_y = shl nuw i32 %y, 5 - %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) - ret i32 %min -} - declare void @use(i8) define i32 @umax_shl_common_lhs_multi_use(i32 %x, i32 %y, i32 %z) { @@ -240,8 +196,9 @@ define i32 @umin_shl_common_rhs_multi_use(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 [[X]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[Z]], [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %z, %x @@ -253,8 +210,9 @@ define i32 @umax_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 [[X]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[TMP1]], [[Z]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %x, %z @@ -266,8 +224,9 @@ define i32 @umax_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_lhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[Y]], i32 [[X]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[Z]], [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %z, %x @@ -279,8 +238,9 @@ define i32 @umin_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_rhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[Y]], i32 [[X]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], [[Z]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %x, %z @@ -292,8 +252,9 @@ define i32 @umin_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { define <2 x i32> @umax_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[Z]], [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Z]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> %z, %x @@ -305,8 +266,9 @@ define <2 x i32> @umax_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i3 define <2 x i32> @umax_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[TMP1]], [[Z]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], [[Z]] +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> %x, %z @@ -319,8 +281,9 @@ define <2 x i32> @umax_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i3 define <2 x i32> @umin_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[Z]], [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Z]], [[Y]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> %z, %x @@ -332,8 +295,9 @@ define <2 x i32> @umin_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i3 define <2 x i32> @umin_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[TMP1]], [[Z]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], [[Z]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], [[Z]] +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> %x, %z @@ -342,161 +306,7 @@ define <2 x i32> @umin_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i3 ret <2 x i32> %min } -define <2 x i32> @umax_shl_common_lhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector_splat( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] -; CHECK-NEXT: ret <2 x i32> [[MAX]] -; - %shl_x = shl nuw <2 x i32> , %x - %shl_y = shl nuw <2 x i32> , %y - %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %max -} - -define <2 x i32> @umax_shl_common_rhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector_splat( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[TMP1]], splat (i32 1) -; CHECK-NEXT: ret <2 x i32> [[MAX]] -; - %shl_x = shl nuw <2 x i32> %x, - %shl_y = shl nuw <2 x i32> %y, - %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %max -} - -define <2 x i32> @umin_shl_common_lhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector_splat( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> splat (i32 1), [[TMP1]] -; CHECK-NEXT: ret <2 x i32> [[MIN]] -; - %shl_x = shl nuw <2 x i32> , %x - %shl_y = shl nuw <2 x i32> , %y - %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %min -} - -define <2 x i32> @umin_shl_common_rhs_vector_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector_splat( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[TMP1]], splat (i32 1) -; CHECK-NEXT: ret <2 x i32> [[MIN]] -; - %shl_x = shl nuw <2 x i32> %x, - %shl_y = shl nuw <2 x i32> %y, - %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %min -} - -define <2 x i32> @umax_shl_common_lhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector_splat_poison( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> , [[TMP1]] -; CHECK-NEXT: ret <2 x i32> [[MAX]] -; - %shl_x = shl nuw <2 x i32> , %x - %shl_y = shl nuw <2 x i32> , %y - %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %max -} - -define <2 x i32> @umax_shl_common_rhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector_splat_poison( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[TMP1]], -; CHECK-NEXT: ret <2 x i32> [[MAX]] -; - %shl_x = shl nuw <2 x i32> %x, - %shl_y = shl nuw <2 x i32> %y, - %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %max -} - -define <2 x i32> @umin_shl_common_lhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector_splat_poison( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> , [[TMP1]] -; CHECK-NEXT: ret <2 x i32> [[MIN]] -; - %shl_x = shl nuw <2 x i32> , %x - %shl_y = shl nuw <2 x i32> , %y - %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %min -} - -define <2 x i32> @umin_shl_common_rhs_vector_splat_poison(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector_splat_poison( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[TMP1]], -; CHECK-NEXT: ret <2 x i32> [[MIN]] -; - %shl_x = shl nuw <2 x i32> %x, - %shl_y = shl nuw <2 x i32> %y, - %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %min -} - -define <2 x i32> @umax_shl_common_lhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector_non_splat( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> , [[TMP1]] -; CHECK-NEXT: ret <2 x i32> [[MAX]] -; - %shl_x = shl nuw <2 x i32> , %x - %shl_y = shl nuw <2 x i32> , %y - %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %max -} - -define <2 x i32> @umax_shl_common_rhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector_non_splat( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[TMP1]], -; CHECK-NEXT: ret <2 x i32> [[MAX]] -; - %shl_x = shl nuw <2 x i32> %x, - %shl_y = shl nuw <2 x i32> %y, - %max = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %max -} - -define <2 x i32> @umin_shl_common_lhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector_non_splat( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> , [[TMP1]] -; CHECK-NEXT: ret <2 x i32> [[MIN]] -; - %shl_x = shl nuw <2 x i32> , %x - %shl_y = shl nuw <2 x i32> , %y - %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %min -} - -define <2 x i32> @umin_shl_common_rhs_vector_non_splat(<2 x i32> %x, <2 x i32> %y) { -; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector_non_splat( -; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[TMP1]], -; CHECK-NEXT: ret <2 x i32> [[MIN]] -; - %shl_x = shl nuw <2 x i32> %x, - %shl_y = shl nuw <2 x i32> %y, - %min = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %shl_x, <2 x i32> %shl_y) - ret <2 x i32> %min -} +; Negative tests define i32 @umax_shl_different_lhs(i32 %z1, i32 %z2, i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_shl_different_lhs( @@ -554,6 +364,34 @@ define i32 @umin_shl_different_rhs(i32 %z1, i32 %z2, i32 %x, i32 %y) { ret i32 %min } +define i32 @umax_shl_does_not_commute(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umax_shl_does_not_commute( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Y]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MAX]] +; + %shl_x = shl nuw i32 %x, %y + %shl_y = shl nuw i32 %y, %z + %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) + ret i32 %max +} + +define i32 @umin_shl_does_not_commute(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: define i32 @umin_shl_does_not_commute( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Y]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: ret i32 [[MIN]] +; + %shl_x = shl nuw i32 %x, %y + %shl_y = shl nuw i32 %y, %z + %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) + ret i32 %min +} + define i32 @umax_shl_common_lhs_no_nuw_flag(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs_no_nuw_flag( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { @@ -571,50 +409,23 @@ define i32 @umax_shl_common_lhs_no_nuw_flag(i32 %x, i32 %y) { define i32 @umax_shl_common_rhs_no_nuw_flag(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs_no_nuw_flag( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl i32 [[X]], 2 +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 2 ; CHECK-NEXT: [[SHL_Y:%.*]] = shl i32 [[Y]], 2 ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; - %shl_x = shl i32 %x, 2 + %shl_x = shl nuw i32 %x, 2 %shl_y = shl i32 %y, 2 %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) ret i32 %max } -define i32 @umin_shl_common_lhs_no_nuw_flag(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @umin_shl_common_lhs_no_nuw_flag( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl i32 2, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl i32 2, [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) -; CHECK-NEXT: ret i32 [[MIN]] -; - %shl_x = shl i32 2, %x - %shl_y = shl i32 2, %y - %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) - ret i32 %min -} - -define i32 @umin_shl_common_rhs_no_nuw_flag(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @umin_shl_common_rhs_no_nuw_flag( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl i32 [[X]], 2 -; CHECK-NEXT: [[SHL_Y:%.*]] = shl i32 [[Y]], 2 -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) -; CHECK-NEXT: ret i32 [[MIN]] -; - %shl_x = shl i32 %x, 2 - %shl_y = shl i32 %y, 2 - %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) - ret i32 %min -} - define i32 @umax_shl_common_lhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs_preserve_nsw( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw nsw i32 [[Z]], [[TMP1]] +; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[Z]], [[X]] +; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[Z]], [[Y]] +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw nsw i32 %z, %x @@ -622,42 +433,3 @@ define i32 @umax_shl_common_lhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) ret i32 %max } - -define i32 @umax_shl_common_rhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { -; CHECK-LABEL: define i32 @umax_shl_common_rhs_preserve_nsw( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MAX:%.*]] = shl nuw nsw i32 [[TMP1]], [[Z]] -; CHECK-NEXT: ret i32 [[MAX]] -; - %shl_x = shl nuw nsw i32 %x, %z - %shl_y = shl nuw nsw i32 %y, %z - %max = call i32 @llvm.umax.i32(i32 %shl_x, i32 %shl_y) - ret i32 %max -} - -define i32 @umin_shl_common_lhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { -; CHECK-LABEL: define i32 @umin_shl_common_lhs_preserve_nsw( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw nsw i32 [[Z]], [[TMP1]] -; CHECK-NEXT: ret i32 [[MIN]] -; - %shl_x = shl nuw nsw i32 %z, %x - %shl_y = shl nuw nsw i32 %z, %y - %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) - ret i32 %min -} - -define i32 @umin_shl_common_rhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { -; CHECK-LABEL: define i32 @umin_shl_common_rhs_preserve_nsw( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) -; CHECK-NEXT: [[MIN:%.*]] = shl nuw nsw i32 [[TMP1]], [[Z]] -; CHECK-NEXT: ret i32 [[MIN]] -; - %shl_x = shl nuw nsw i32 %x, %z - %shl_y = shl nuw nsw i32 %y, %z - %min = call i32 @llvm.umin.i32(i32 %shl_x, i32 %shl_y) - ret i32 %min -} From 46f31fce038715430eb0d54f5c9319f88d461150 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Fri, 14 Mar 2025 20:17:19 +0800 Subject: [PATCH 12/15] codestyle --- .../InstCombine/InstCombineCalls.cpp | 7 +- .../Transforms/InstCombine/shift-uminmax.ll | 85 ++++++++----------- 2 files changed, 37 insertions(+), 55 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 37c2015f59c12..bbcee7f2700b6 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1606,18 +1606,17 @@ foldIntrinsicUsingDistributiveLaws(IntrinsicInst *II, if (Op0->isCommutative() && A != C && B != D && A == D) std::swap(C, D); - if (A != C && B != D) - return nullptr; - BinaryOperator *NewBinop; if (A == C) { Value *NewIntrinsic = Builder.CreateBinaryIntrinsic(TopLevelOpcode, B, D); NewBinop = cast(Builder.CreateBinOp(InnerOpcode, A, NewIntrinsic)); - } else { // B == D + } else if (B == D) { Value *NewIntrinsic = Builder.CreateBinaryIntrinsic(TopLevelOpcode, A, C); NewBinop = cast(Builder.CreateBinOp(InnerOpcode, NewIntrinsic, B)); + } else { + return nullptr; } NewBinop->setHasNoUnsignedWrap(HasNUW); diff --git a/llvm/test/Transforms/InstCombine/shift-uminmax.ll b/llvm/test/Transforms/InstCombine/shift-uminmax.ll index 5b8df460073f7..21f8ac9f34674 100644 --- a/llvm/test/Transforms/InstCombine/shift-uminmax.ll +++ b/llvm/test/Transforms/InstCombine/shift-uminmax.ll @@ -10,9 +10,8 @@ define i32 @umax_shl_common_lhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[Z]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %z, %x @@ -24,9 +23,8 @@ define i32 @umax_shl_common_lhs(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_rhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[TMP1]], [[Z]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %x, %z @@ -38,9 +36,8 @@ define i32 @umax_shl_common_rhs(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_lhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_lhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[Z]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %z, %x @@ -52,9 +49,8 @@ define i32 @umin_shl_common_lhs(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_rhs(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_rhs( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], [[Z]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %x, %z @@ -66,9 +62,8 @@ define i32 @umin_shl_common_rhs(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_lhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 1, [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 1, %x @@ -80,9 +75,8 @@ define i32 @umax_shl_common_lhs_const1(i32 %x, i32 %y) { define i32 @umax_shl_common_rhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 1 -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 1 -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[TMP1]], 1 ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %x, 1 @@ -94,9 +88,8 @@ define i32 @umax_shl_common_rhs_const1(i32 %x, i32 %y) { define i32 @umin_shl_common_lhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umin_shl_common_lhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 1, [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 1, [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 1, [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 1, %x @@ -108,9 +101,8 @@ define i32 @umin_shl_common_lhs_const1(i32 %x, i32 %y) { define i32 @umin_shl_common_rhs_const1(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umin_shl_common_rhs_const1( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], 1 -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], 1 -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], 1 ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %x, 1 @@ -196,9 +188,8 @@ define i32 @umin_shl_common_rhs_multi_use(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[Z]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %z, %x @@ -210,9 +201,8 @@ define i32 @umax_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { define i32 @umax_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_rhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw i32 [[TMP1]], [[Z]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw i32 %x, %z @@ -224,9 +214,8 @@ define i32 @umax_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_lhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Z]], [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[Z]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %z, %x @@ -238,9 +227,8 @@ define i32 @umin_shl_common_lhs_commuted(i32 %x, i32 %y, i32 %z) { define i32 @umin_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umin_shl_common_rhs_commuted( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw i32 [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw i32 [[Y]], [[Z]] -; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_Y]], i32 [[SHL_X]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[Y]], i32 [[X]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw i32 [[TMP1]], [[Z]] ; CHECK-NEXT: ret i32 [[MIN]] ; %shl_x = shl nuw i32 %x, %z @@ -252,9 +240,8 @@ define i32 @umin_shl_common_rhs_commuted(i32 %x, i32 %y, i32 %z) { define <2 x i32> @umax_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_lhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Z]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[Z]], [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> %z, %x @@ -266,9 +253,8 @@ define <2 x i32> @umax_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i3 define <2 x i32> @umax_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umax_shl_common_rhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], [[Z]] -; CHECK-NEXT: [[MAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw <2 x i32> [[TMP1]], [[Z]] ; CHECK-NEXT: ret <2 x i32> [[MAX]] ; %shl_x = shl nuw <2 x i32> %x, %z @@ -281,9 +267,8 @@ define <2 x i32> @umax_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i3 define <2 x i32> @umin_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_lhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Z]], [[Y]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[Z]], [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> %z, %x @@ -295,9 +280,8 @@ define <2 x i32> @umin_shl_common_lhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i3 define <2 x i32> @umin_shl_common_rhs_vector(<2 x i32> %z, <2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: define <2 x i32> @umin_shl_common_rhs_vector( ; CHECK-SAME: <2 x i32> [[Z:%.*]], <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw <2 x i32> [[X]], [[Z]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw <2 x i32> [[Y]], [[Z]] -; CHECK-NEXT: [[MIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[SHL_X]], <2 x i32> [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: [[MIN:%.*]] = shl nuw <2 x i32> [[TMP1]], [[Z]] ; CHECK-NEXT: ret <2 x i32> [[MIN]] ; %shl_x = shl nuw <2 x i32> %x, %z @@ -423,9 +407,8 @@ define i32 @umax_shl_common_rhs_no_nuw_flag(i32 %x, i32 %y) { define i32 @umax_shl_common_lhs_preserve_nsw(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: define i32 @umax_shl_common_lhs_preserve_nsw( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[Z]], [[X]] -; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[Z]], [[Y]] -; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]]) +; CHECK-NEXT: [[MAX:%.*]] = shl nuw nsw i32 [[Z]], [[TMP1]] ; CHECK-NEXT: ret i32 [[MAX]] ; %shl_x = shl nuw nsw i32 %z, %x From 6cbc76d054a0ed7c8570a8cf54231eab86c2b3c1 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Fri, 14 Mar 2025 20:35:20 +0800 Subject: [PATCH 13/15] fix intrinsic-distributive.ll commutative tests --- .../InstCombine/intrinsic-distributive.ll | 160 +++++++++--------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll b/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll index 2284e3f6c174b..a3504dd2d5edf 100644 --- a/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll +++ b/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll @@ -2,8 +2,8 @@ ; RUN: opt -S -passes=instcombine < %s 2>&1 | FileCheck %s -define i8 @umax_of_add_nuw(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umax_of_add_nuw( +define i8 @umax_of_add_nuw_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] @@ -15,11 +15,11 @@ define i8 @umax_of_add_nuw(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @umax_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umax_of_add_nuw_comm( +define i8 @umax_of_add_nuw_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw i8 %a, %b @@ -28,8 +28,8 @@ define i8 @umax_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @umax_of_add_nuw_nsw_lhs(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs( +define i8 @umax_of_add_nuw_nsw_lhs_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] @@ -41,11 +41,11 @@ define i8 @umax_of_add_nuw_nsw_lhs(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @umax_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs_comm( +define i8 @umax_of_add_nuw_nsw_lhs_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %a, %b @@ -54,8 +54,8 @@ define i8 @umax_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @umax_of_add_nuw_nsw_rhs(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs( +define i8 @umax_of_add_nuw_nsw_rhs_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] @@ -67,11 +67,11 @@ define i8 @umax_of_add_nuw_nsw_rhs(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @umax_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs_comm( +define i8 @umax_of_add_nuw_nsw_rhs_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw i8 %a, %b @@ -80,8 +80,8 @@ define i8 @umax_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @umax_of_add_nuw_nsw(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw( +define i8 @umax_of_add_nuw_nsw_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] @@ -93,11 +93,11 @@ define i8 @umax_of_add_nuw_nsw(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @umax_of_add_nuw_nsw_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_comm( +define i8 @umax_of_add_nuw_nsw_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %a, %b @@ -136,8 +136,8 @@ define i8 @umax_of_add(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @umin_of_add_nuw(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umin_of_add_nuw( +define i8 @umin_of_add_nuw_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] @@ -149,11 +149,11 @@ define i8 @umin_of_add_nuw(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @umin_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umin_of_add_nuw_comm( +define i8 @umin_of_add_nuw_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw i8 %a, %b @@ -162,8 +162,8 @@ define i8 @umin_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @umin_of_add_nuw_nsw_lhs(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs( +define i8 @umin_of_add_nuw_nsw_lhs_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] @@ -175,11 +175,11 @@ define i8 @umin_of_add_nuw_nsw_lhs(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @umin_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs_comm( +define i8 @umin_of_add_nuw_nsw_lhs_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %a, %b @@ -188,8 +188,8 @@ define i8 @umin_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @umin_of_add_nuw_nsw_rhs(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs( +define i8 @umin_of_add_nuw_nsw_rhs_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] @@ -201,11 +201,11 @@ define i8 @umin_of_add_nuw_nsw_rhs(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @umin_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs_comm( +define i8 @umin_of_add_nuw_nsw_rhs_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw i8 %a, %b @@ -214,8 +214,8 @@ define i8 @umin_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @umin_of_add_nuw_nsw(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw( +define i8 @umin_of_add_nuw_nsw_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] @@ -227,11 +227,11 @@ define i8 @umin_of_add_nuw_nsw(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @umin_of_add_nuw_nsw_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_comm( +define i8 @umin_of_add_nuw_nsw_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %a, %b @@ -285,8 +285,8 @@ define i8 @smax_of_add_nuw(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @smax_of_add_nsw(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smax_of_add_nsw( +define i8 @smax_of_add_nsw_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] @@ -298,11 +298,11 @@ define i8 @smax_of_add_nsw(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @smax_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smax_of_add_nsw_comm( +define i8 @smax_of_add_nsw_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw i8 %a, %b @@ -311,8 +311,8 @@ define i8 @smax_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @smax_of_add_nsw_nuw_lhs(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs( +define i8 @smax_of_add_nsw_nuw_lhs_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] @@ -324,11 +324,11 @@ define i8 @smax_of_add_nsw_nuw_lhs(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @smax_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs_comm( +define i8 @smax_of_add_nsw_nuw_lhs_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw nuw i8 %a, %b @@ -337,8 +337,8 @@ define i8 @smax_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @smax_of_add_nsw_nuw_rhs(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs( +define i8 @smax_of_add_nsw_nuw_rhs_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] @@ -350,11 +350,11 @@ define i8 @smax_of_add_nsw_nuw_rhs(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @smax_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs_comm( +define i8 @smax_of_add_nsw_nuw_rhs_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw i8 %a, %b @@ -363,8 +363,8 @@ define i8 @smax_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @smax_of_add_nsw_nuw(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw( +define i8 @smax_of_add_nsw_nuw_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] @@ -376,11 +376,11 @@ define i8 @smax_of_add_nsw_nuw(i8 %a, i8 %b, i8 %c) { ret i8 %max } -define i8 @smax_of_add_nsw_nuw_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_comm( +define i8 @smax_of_add_nsw_nuw_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw nuw i8 %a, %b @@ -419,8 +419,8 @@ define i8 @smin_of_add_nuw(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @smin_of_add_nsw(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smin_of_add_nsw( +define i8 @smin_of_add_nsw_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] @@ -432,11 +432,11 @@ define i8 @smin_of_add_nsw(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @smin_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smin_of_add_nsw_comm( +define i8 @smin_of_add_nsw_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw i8 %a, %b @@ -445,8 +445,8 @@ define i8 @smin_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @smin_of_add_nsw_nuw_lhs(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs( +define i8 @smin_of_add_nsw_nuw_lhs_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] @@ -458,11 +458,11 @@ define i8 @smin_of_add_nsw_nuw_lhs(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @smin_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs_comm( +define i8 @smin_of_add_nsw_nuw_lhs_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw nuw i8 %a, %b @@ -471,8 +471,8 @@ define i8 @smin_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @smin_of_add_nsw_nuw_rhs(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs( +define i8 @smin_of_add_nsw_nuw_rhs_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] @@ -484,11 +484,11 @@ define i8 @smin_of_add_nsw_nuw_rhs(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @smin_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs_comm( +define i8 @smin_of_add_nsw_nuw_rhs_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw i8 %a, %b @@ -497,8 +497,8 @@ define i8 @smin_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @smin_of_add_nsw_nuw(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw( +define i8 @smin_of_add_nsw_nuw_r(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) ; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] @@ -510,11 +510,11 @@ define i8 @smin_of_add_nsw_nuw(i8 %a, i8 %b, i8 %c) { ret i8 %min } -define i8 @smin_of_add_nsw_nuw_comm(i8 %a, i8 %b, i8 %c) { -; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_comm( +define i8 @smin_of_add_nsw_nuw_l(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw nuw i8 %a, %b From e313f9607937f3dd2b5c622e0b4ede5a4781e112 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Sat, 15 Mar 2025 00:59:13 +0800 Subject: [PATCH 14/15] add intrinsic-distributive commutative regression tests --- .../InstCombine/intrinsic-distributive.ll | 242 ++++++++++++++++-- 1 file changed, 226 insertions(+), 16 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll b/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll index a3504dd2d5edf..87f4557a98523 100644 --- a/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll +++ b/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll @@ -19,7 +19,7 @@ define i8 @umax_of_add_nuw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw i8 %a, %b @@ -28,6 +28,19 @@ define i8 @umax_of_add_nuw_l(i8 %a, i8 %b, i8 %c) { ret i8 %max } +define i8 @umax_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw i8 %b, %a + %add2 = add nuw i8 %a, %c + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + define i8 @umax_of_add_nuw_nsw_lhs_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -45,7 +58,7 @@ define i8 @umax_of_add_nuw_nsw_lhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %a, %b @@ -54,6 +67,19 @@ define i8 @umax_of_add_nuw_nsw_lhs_l(i8 %a, i8 %b, i8 %c) { ret i8 %max } +define i8 @umax_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw nsw i8 %a, %b + %add2 = add nuw i8 %c, %a + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + define i8 @umax_of_add_nuw_nsw_rhs_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -71,7 +97,7 @@ define i8 @umax_of_add_nuw_nsw_rhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw i8 %a, %b @@ -80,6 +106,19 @@ define i8 @umax_of_add_nuw_nsw_rhs_l(i8 %a, i8 %b, i8 %c) { ret i8 %max } +define i8 @umax_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw i8 %b, %a + %add2 = add nuw nsw i8 %a, %c + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + define i8 @umax_of_add_nuw_nsw_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -97,7 +136,7 @@ define i8 @umax_of_add_nuw_nsw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %a, %b @@ -106,6 +145,19 @@ define i8 @umax_of_add_nuw_nsw_l(i8 %a, i8 %b, i8 %c) { ret i8 %max } +define i8 @umax_of_add_nuw_nsw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw nsw i8 %a, %b + %add2 = add nuw nsw i8 %c, %a + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + ; negative test define i8 @umax_of_add_nsw(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nsw( @@ -153,7 +205,7 @@ define i8 @umin_of_add_nuw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw i8 %a, %b @@ -162,6 +214,19 @@ define i8 @umin_of_add_nuw_l(i8 %a, i8 %b, i8 %c) { ret i8 %min } +define i8 @umin_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw i8 %b, %a + %add2 = add nuw i8 %a, %c + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + define i8 @umin_of_add_nuw_nsw_lhs_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -179,7 +244,7 @@ define i8 @umin_of_add_nuw_nsw_lhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %a, %b @@ -188,6 +253,19 @@ define i8 @umin_of_add_nuw_nsw_lhs_l(i8 %a, i8 %b, i8 %c) { ret i8 %min } +define i8 @umin_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw nsw i8 %a, %b + %add2 = add nuw i8 %c, %a + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + define i8 @umin_of_add_nuw_nsw_rhs_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -205,7 +283,7 @@ define i8 @umin_of_add_nuw_nsw_rhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw i8 %a, %b @@ -214,6 +292,19 @@ define i8 @umin_of_add_nuw_nsw_rhs_l(i8 %a, i8 %b, i8 %c) { ret i8 %min } +define i8 @umin_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw i8 %b, %a + %add2 = add nuw nsw i8 %a, %c + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + define i8 @umin_of_add_nuw_nsw_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -231,7 +322,7 @@ define i8 @umin_of_add_nuw_nsw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %a, %b @@ -240,6 +331,19 @@ define i8 @umin_of_add_nuw_nsw_l(i8 %a, i8 %b, i8 %c) { ret i8 %min } +define i8 @umin_of_add_nuw_nsw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw nsw i8 %a, %b + %add2 = add nuw nsw i8 %c, %a + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + ; negative test define i8 @umin_of_add_nsw(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nsw( @@ -302,7 +406,7 @@ define i8 @smax_of_add_nsw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw i8 %a, %b @@ -311,6 +415,19 @@ define i8 @smax_of_add_nsw_l(i8 %a, i8 %b, i8 %c) { ret i8 %max } +define i8 @smax_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw i8 %b, %a + %add2 = add nsw i8 %a, %c + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + define i8 @smax_of_add_nsw_nuw_lhs_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -328,7 +445,7 @@ define i8 @smax_of_add_nsw_nuw_lhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw nuw i8 %a, %b @@ -337,6 +454,19 @@ define i8 @smax_of_add_nsw_nuw_lhs_l(i8 %a, i8 %b, i8 %c) { ret i8 %max } +define i8 @smax_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw nsw i8 %a, %b + %add2 = add nsw i8 %c, %a + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + define i8 @smax_of_add_nsw_nuw_rhs_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -354,7 +484,7 @@ define i8 @smax_of_add_nsw_nuw_rhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw i8 %a, %b @@ -363,6 +493,19 @@ define i8 @smax_of_add_nsw_nuw_rhs_l(i8 %a, i8 %b, i8 %c) { ret i8 %max } +define i8 @smax_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw i8 %b, %a + %add2 = add nsw nuw i8 %a, %c + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + define i8 @smax_of_add_nsw_nuw_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -380,7 +523,7 @@ define i8 @smax_of_add_nsw_nuw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw nuw i8 %a, %b @@ -389,6 +532,19 @@ define i8 @smax_of_add_nsw_nuw_l(i8 %a, i8 %b, i8 %c) { ret i8 %max } +define i8 @smax_of_add_nsw_nuw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw nuw i8 %a, %b + %add2 = add nsw nuw i8 %c, %a + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + ; negative test define i8 @smax_of_add(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add( @@ -436,7 +592,7 @@ define i8 @smin_of_add_nsw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw i8 %a, %b @@ -445,6 +601,19 @@ define i8 @smin_of_add_nsw_l(i8 %a, i8 %b, i8 %c) { ret i8 %min } +define i8 @smin_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw i8 %b, %a + %add2 = add nsw i8 %a, %c + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + define i8 @smin_of_add_nsw_nuw_lhs_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -462,7 +631,7 @@ define i8 @smin_of_add_nsw_nuw_lhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw nuw i8 %a, %b @@ -471,6 +640,20 @@ define i8 @smin_of_add_nsw_nuw_lhs_l(i8 %a, i8 %b, i8 %c) { ret i8 %min } +define i8 @smin_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw nuw i8 %a, %b + %add2 = add nuw i8 %c, %a + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + define i8 @smin_of_add_nsw_nuw_rhs_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -488,7 +671,7 @@ define i8 @smin_of_add_nsw_nuw_rhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw i8 %a, %b @@ -497,6 +680,20 @@ define i8 @smin_of_add_nsw_nuw_rhs_l(i8 %a, i8 %b, i8 %c) { ret i8 %min } +define i8 @smin_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw i8 %b, %a + %add2 = add nsw nuw i8 %a, %c + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + + define i8 @smin_of_add_nsw_nuw_r(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_r( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { @@ -514,7 +711,7 @@ define i8 @smin_of_add_nsw_nuw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw nuw i8 %a, %b @@ -523,6 +720,19 @@ define i8 @smin_of_add_nsw_nuw_l(i8 %a, i8 %b, i8 %c) { ret i8 %min } +define i8 @smin_of_add_nsw_nuw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw nuw i8 %a, %b + %add2 = add nsw nuw i8 %c, %a + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + ; negative test define i8 @smin_of_add(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add( From 7fda0f44896bc6da0f660880f43bdef0506027ee Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Sat, 15 Mar 2025 01:00:59 +0800 Subject: [PATCH 15/15] fix missed swap pattern --- .../InstCombine/InstCombineCalls.cpp | 8 +++- .../InstCombine/intrinsic-distributive.ll | 46 +++++++++---------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index bbcee7f2700b6..12dd4cec85f59 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1603,8 +1603,12 @@ foldIntrinsicUsingDistributiveLaws(IntrinsicInst *II, // Attempts to swap variables such that A equals C or B equals D, // if the inner operation is commutative. - if (Op0->isCommutative() && A != C && B != D && A == D) - std::swap(C, D); + if (Op0->isCommutative() && A != C && B != D) { + if (A == D || B == C) + std::swap(C, D); + else + return nullptr; + } BinaryOperator *NewBinop; if (A == C) { diff --git a/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll b/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll index 87f4557a98523..630d4ee4d4221 100644 --- a/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll +++ b/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll @@ -19,7 +19,7 @@ define i8 @umax_of_add_nuw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw i8 %a, %b @@ -58,7 +58,7 @@ define i8 @umax_of_add_nuw_nsw_lhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %a, %b @@ -71,7 +71,7 @@ define i8 @umax_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %a, %b @@ -97,7 +97,7 @@ define i8 @umax_of_add_nuw_nsw_rhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw i8 %a, %b @@ -136,7 +136,7 @@ define i8 @umax_of_add_nuw_nsw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %a, %b @@ -149,7 +149,7 @@ define i8 @umax_of_add_nuw_nsw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %a, %b @@ -205,7 +205,7 @@ define i8 @umin_of_add_nuw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw i8 %a, %b @@ -244,7 +244,7 @@ define i8 @umin_of_add_nuw_nsw_lhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %a, %b @@ -257,7 +257,7 @@ define i8 @umin_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %a, %b @@ -283,7 +283,7 @@ define i8 @umin_of_add_nuw_nsw_rhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw i8 %a, %b @@ -322,7 +322,7 @@ define i8 @umin_of_add_nuw_nsw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %a, %b @@ -335,7 +335,7 @@ define i8 @umin_of_add_nuw_nsw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %a, %b @@ -406,7 +406,7 @@ define i8 @smax_of_add_nsw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw i8 %a, %b @@ -445,7 +445,7 @@ define i8 @smax_of_add_nsw_nuw_lhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw nuw i8 %a, %b @@ -458,7 +458,7 @@ define i8 @smax_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %a, %b @@ -484,7 +484,7 @@ define i8 @smax_of_add_nsw_nuw_rhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw i8 %a, %b @@ -523,7 +523,7 @@ define i8 @smax_of_add_nsw_nuw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw nuw i8 %a, %b @@ -536,7 +536,7 @@ define i8 @smax_of_add_nsw_nuw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw nuw i8 %a, %b @@ -592,7 +592,7 @@ define i8 @smin_of_add_nsw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw i8 %a, %b @@ -631,7 +631,7 @@ define i8 @smin_of_add_nsw_nuw_lhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw nuw i8 %a, %b @@ -671,7 +671,7 @@ define i8 @smin_of_add_nsw_nuw_rhs_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw i8 %a, %b @@ -711,7 +711,7 @@ define i8 @smin_of_add_nsw_nuw_l(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_l( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw nuw i8 %a, %b @@ -724,7 +724,7 @@ define i8 @smin_of_add_nsw_nuw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) -; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[A]], [[TMP1]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw nuw i8 %a, %b