[llvm] [InstCombine] Add freeze for lshr (mul (X, 2^N + 1)), N -> add (X, lshr(X, N)) (PR #96324)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 17 12:29:54 PDT 2024
https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/96324
>From a6695a4446e39aa68081fc483ae8d7e4e213f966 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Fri, 21 Jun 2024 11:37:49 -0400
Subject: [PATCH] [InstCombine] Add freeze for lshr (mul (X, 2^N + 1)), N ->
add (X, lshr(X, N))
---
.../InstCombine/InstCombineShifts.cpp | 5 +-
llvm/test/Transforms/InstCombine/ashr-lshr.ll | 53 ++++++++++++-------
llvm/test/Transforms/InstCombine/lshr.ll | 2 +-
3 files changed, 37 insertions(+), 23 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 38f8a41214b68..90e97b020b9fe 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1499,7 +1499,7 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
return replaceInstUsesWith(I, X);
// lshr (mul nuw (X, 2^N + 1)), N -> add nuw (X, lshr(X, N))
- if (Op0->hasOneUse()) {
+ if (Op0->hasOneUse() && isGuaranteedNotToBeUndef(X, &AC, &I, &DT)) {
auto *NewAdd = BinaryOperator::CreateNUWAdd(
X, Builder.CreateLShr(X, ConstantInt::get(Ty, ShAmtC), "",
I.isExact()));
@@ -1528,7 +1528,8 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
}
// lshr (mul nsw (X, 2^N + 1)), N -> add nsw (X, lshr(X, N))
- if (match(Op0, m_OneUse(m_NSWMul(m_Value(X), m_APInt(MulC))))) {
+ if (match(Op0, m_OneUse(m_NSWMul(m_Value(X), m_APInt(MulC)))) &&
+ isGuaranteedNotToBeUndef(X, &AC, &I, &DT)) {
if (BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
MulC->logBase2() == ShAmtC) {
return BinaryOperator::CreateNSWAdd(
diff --git a/llvm/test/Transforms/InstCombine/ashr-lshr.ll b/llvm/test/Transforms/InstCombine/ashr-lshr.ll
index c2a4f35412670..5ac3435994655 100644
--- a/llvm/test/Transforms/InstCombine/ashr-lshr.ll
+++ b/llvm/test/Transforms/InstCombine/ashr-lshr.ll
@@ -605,7 +605,7 @@ define <2 x i8> @ashr_known_pos_exact_vec(<2 x i8> %x, <2 x i8> %y) {
ret <2 x i8> %r
}
-define i32 @lshr_mul_times_3_div_2(i32 %0) {
+define i32 @lshr_mul_times_3_div_2(i32 noundef %0) {
; CHECK-LABEL: @lshr_mul_times_3_div_2(
; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 1
; CHECK-NEXT: [[LSHR:%.*]] = add nuw nsw i32 [[TMP2]], [[TMP0]]
@@ -616,7 +616,20 @@ define i32 @lshr_mul_times_3_div_2(i32 %0) {
ret i32 %lshr
}
-define i32 @lshr_mul_times_3_div_2_exact(i32 %x) {
+; Negative test
+
+define i32 @lshr_mul_times_3_div_2_noudef(i32 %0) {
+; CHECK-LABEL: @lshr_mul_times_3_div_2_noudef(
+; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i32 [[TMP0:%.*]], 3
+; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[MUL]], 1
+; CHECK-NEXT: ret i32 [[LSHR]]
+;
+ %mul = mul nsw nuw i32 %0, 3
+ %lshr = lshr i32 %mul, 1
+ ret i32 %lshr
+}
+
+define i32 @lshr_mul_times_3_div_2_exact(i32 noundef %x) {
; CHECK-LABEL: @lshr_mul_times_3_div_2_exact(
; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 1
; CHECK-NEXT: [[LSHR:%.*]] = add nsw i32 [[TMP1]], [[X]]
@@ -629,7 +642,7 @@ define i32 @lshr_mul_times_3_div_2_exact(i32 %x) {
; Negative test
-define i32 @lshr_mul_times_3_div_2_no_flags(i32 %0) {
+define i32 @lshr_mul_times_3_div_2_no_flags(i32 noundef %0) {
; CHECK-LABEL: @lshr_mul_times_3_div_2_no_flags(
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 3
; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[MUL]], 1
@@ -642,7 +655,7 @@ define i32 @lshr_mul_times_3_div_2_no_flags(i32 %0) {
; Negative test
-define i32 @mul_times_3_div_2_multiuse_lshr(i32 %x) {
+define i32 @mul_times_3_div_2_multiuse_lshr(i32 noundef %x) {
; CHECK-LABEL: @mul_times_3_div_2_multiuse_lshr(
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 3
; CHECK-NEXT: [[RES:%.*]] = lshr i32 [[MUL]], 1
@@ -655,7 +668,7 @@ define i32 @mul_times_3_div_2_multiuse_lshr(i32 %x) {
ret i32 %res
}
-define i32 @lshr_mul_times_3_div_2_exact_2(i32 %x) {
+define i32 @lshr_mul_times_3_div_2_exact_2(i32 noundef %x) {
; CHECK-LABEL: @lshr_mul_times_3_div_2_exact_2(
; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 1
; CHECK-NEXT: [[LSHR:%.*]] = add nuw i32 [[TMP1]], [[X]]
@@ -666,7 +679,7 @@ define i32 @lshr_mul_times_3_div_2_exact_2(i32 %x) {
ret i32 %lshr
}
-define i32 @lshr_mul_times_5_div_4(i32 %0) {
+define i32 @lshr_mul_times_5_div_4(i32 noundef %0) {
; CHECK-LABEL: @lshr_mul_times_5_div_4(
; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 2
; CHECK-NEXT: [[LSHR:%.*]] = add nuw nsw i32 [[TMP2]], [[TMP0]]
@@ -677,7 +690,7 @@ define i32 @lshr_mul_times_5_div_4(i32 %0) {
ret i32 %lshr
}
-define i32 @lshr_mul_times_5_div_4_exact(i32 %x) {
+define i32 @lshr_mul_times_5_div_4_exact(i32 noundef %x) {
; CHECK-LABEL: @lshr_mul_times_5_div_4_exact(
; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 2
; CHECK-NEXT: [[LSHR:%.*]] = add nsw i32 [[TMP1]], [[X]]
@@ -690,7 +703,7 @@ define i32 @lshr_mul_times_5_div_4_exact(i32 %x) {
; Negative test
-define i32 @lshr_mul_times_5_div_4_no_flags(i32 %0) {
+define i32 @lshr_mul_times_5_div_4_no_flags(i32 noundef %0) {
; CHECK-LABEL: @lshr_mul_times_5_div_4_no_flags(
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 5
; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[MUL]], 2
@@ -703,7 +716,7 @@ define i32 @lshr_mul_times_5_div_4_no_flags(i32 %0) {
; Negative test
-define i32 @mul_times_5_div_4_multiuse_lshr(i32 %x) {
+define i32 @mul_times_5_div_4_multiuse_lshr(i32 noundef %x) {
; CHECK-LABEL: @mul_times_5_div_4_multiuse_lshr(
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 5
; CHECK-NEXT: [[RES:%.*]] = lshr i32 [[MUL]], 2
@@ -716,7 +729,7 @@ define i32 @mul_times_5_div_4_multiuse_lshr(i32 %x) {
ret i32 %res
}
-define i32 @lshr_mul_times_5_div_4_exact_2(i32 %x) {
+define i32 @lshr_mul_times_5_div_4_exact_2(i32 noundef %x) {
; CHECK-LABEL: @lshr_mul_times_5_div_4_exact_2(
; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 2
; CHECK-NEXT: [[LSHR:%.*]] = add nuw i32 [[TMP1]], [[X]]
@@ -727,7 +740,7 @@ define i32 @lshr_mul_times_5_div_4_exact_2(i32 %x) {
ret i32 %lshr
}
-define i32 @ashr_mul_times_3_div_2(i32 %0) {
+define i32 @ashr_mul_times_3_div_2(i32 noundef %0) {
; CHECK-LABEL: @ashr_mul_times_3_div_2(
; CHECK-NEXT: [[TMP2:%.*]] = ashr i32 [[TMP0:%.*]], 1
; CHECK-NEXT: [[ASHR:%.*]] = add nuw nsw i32 [[TMP2]], [[TMP0]]
@@ -738,7 +751,7 @@ define i32 @ashr_mul_times_3_div_2(i32 %0) {
ret i32 %ashr
}
-define i32 @ashr_mul_times_3_div_2_exact(i32 %x) {
+define i32 @ashr_mul_times_3_div_2_exact(i32 noundef %x) {
; CHECK-LABEL: @ashr_mul_times_3_div_2_exact(
; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 1
; CHECK-NEXT: [[ASHR:%.*]] = add nsw i32 [[TMP1]], [[X]]
@@ -751,7 +764,7 @@ define i32 @ashr_mul_times_3_div_2_exact(i32 %x) {
; Negative test
-define i32 @ashr_mul_times_3_div_2_no_flags(i32 %0) {
+define i32 @ashr_mul_times_3_div_2_no_flags(i32 noundef %0) {
; CHECK-LABEL: @ashr_mul_times_3_div_2_no_flags(
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 3
; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[MUL]], 1
@@ -764,7 +777,7 @@ define i32 @ashr_mul_times_3_div_2_no_flags(i32 %0) {
; Negative test
-define i32 @ashr_mul_times_3_div_2_no_nsw(i32 %0) {
+define i32 @ashr_mul_times_3_div_2_no_nsw(i32 noundef %0) {
; CHECK-LABEL: @ashr_mul_times_3_div_2_no_nsw(
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[TMP0:%.*]], 3
; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[MUL]], 1
@@ -777,7 +790,7 @@ define i32 @ashr_mul_times_3_div_2_no_nsw(i32 %0) {
; Negative test
-define i32 @mul_times_3_div_2_multiuse_ashr(i32 %x) {
+define i32 @mul_times_3_div_2_multiuse_ashr(i32 noundef %x) {
; CHECK-LABEL: @mul_times_3_div_2_multiuse_ashr(
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 3
; CHECK-NEXT: [[RES:%.*]] = ashr i32 [[MUL]], 1
@@ -790,7 +803,7 @@ define i32 @mul_times_3_div_2_multiuse_ashr(i32 %x) {
ret i32 %res
}
-define i32 @ashr_mul_times_3_div_2_exact_2(i32 %x) {
+define i32 @ashr_mul_times_3_div_2_exact_2(i32 noundef %x) {
; CHECK-LABEL: @ashr_mul_times_3_div_2_exact_2(
; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 1
; CHECK-NEXT: [[ASHR:%.*]] = add nsw i32 [[TMP1]], [[X]]
@@ -801,7 +814,7 @@ define i32 @ashr_mul_times_3_div_2_exact_2(i32 %x) {
ret i32 %ashr
}
-define i32 @ashr_mul_times_5_div_4(i32 %0) {
+define i32 @ashr_mul_times_5_div_4(i32 noundef %0) {
; CHECK-LABEL: @ashr_mul_times_5_div_4(
; CHECK-NEXT: [[TMP2:%.*]] = ashr i32 [[TMP0:%.*]], 2
; CHECK-NEXT: [[ASHR:%.*]] = add nuw nsw i32 [[TMP2]], [[TMP0]]
@@ -825,7 +838,7 @@ define i32 @ashr_mul_times_5_div_4_exact(i32 %x) {
; Negative test
-define i32 @ashr_mul_times_5_div_4_no_flags(i32 %0) {
+define i32 @ashr_mul_times_5_div_4_no_flags(i32 noundef %0) {
; CHECK-LABEL: @ashr_mul_times_5_div_4_no_flags(
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 5
; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[MUL]], 2
@@ -838,7 +851,7 @@ define i32 @ashr_mul_times_5_div_4_no_flags(i32 %0) {
; Negative test
-define i32 @mul_times_5_div_4_multiuse_ashr(i32 %x) {
+define i32 @mul_times_5_div_4_multiuse_ashr(i32 noundef %x) {
; CHECK-LABEL: @mul_times_5_div_4_multiuse_ashr(
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 5
; CHECK-NEXT: [[RES:%.*]] = ashr i32 [[MUL]], 2
@@ -851,7 +864,7 @@ define i32 @mul_times_5_div_4_multiuse_ashr(i32 %x) {
ret i32 %res
}
-define i32 @ashr_mul_times_5_div_4_exact_2(i32 %x) {
+define i32 @ashr_mul_times_5_div_4_exact_2(i32 noundef %x) {
; CHECK-LABEL: @ashr_mul_times_5_div_4_exact_2(
; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 2
; CHECK-NEXT: [[ASHR:%.*]] = add nsw i32 [[TMP1]], [[X]]
diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll
index 01e07985ba6ab..51a2982f16f34 100644
--- a/llvm/test/Transforms/InstCombine/lshr.ll
+++ b/llvm/test/Transforms/InstCombine/lshr.ll
@@ -739,7 +739,7 @@ define i32 @mul_splat_fold_wrong_lshr_const(i32 %x) {
ret i32 %t
}
-define i32 @mul_splat_fold_no_nuw(i32 %x) {
+define i32 @mul_splat_fold_no_nuw(i32 noundef %x) {
; CHECK-LABEL: @mul_splat_fold_no_nuw(
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 16
; CHECK-NEXT: [[T:%.*]] = add nsw i32 [[TMP1]], [[X]]
More information about the llvm-commits
mailing list