[llvm] 83370e4 - Revert "[InstCombine] lshr (mul (X, 2^N + 1)), N -> add (X, lshr(X, N)) (#92907)"
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Sun May 26 23:32:57 PDT 2024
Author: Nikita Popov
Date: 2024-05-27T08:31:28+02:00
New Revision: 83370e4878aa96489d9a60cb10431e271d6aea1a
URL: https://github.com/llvm/llvm-project/commit/83370e4878aa96489d9a60cb10431e271d6aea1a
DIFF: https://github.com/llvm/llvm-project/commit/83370e4878aa96489d9a60cb10431e271d6aea1a.diff
LOG: Revert "[InstCombine] lshr (mul (X, 2^N + 1)), N -> add (X, lshr(X, N)) (#92907)"
This reverts commit 6d484965ca96b616c3cce0d08eed358b97dbc39b.
PR merged without review.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
llvm/test/Transforms/InstCombine/ashr-lshr.ll
llvm/test/Transforms/InstCombine/lshr.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 4f91993750fd2..0f1979fbe0c76 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1461,24 +1461,13 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
const APInt *MulC;
if (match(Op0, m_NUWMul(m_Value(X), m_APInt(MulC)))) {
- if (BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
- MulC->logBase2() == ShAmtC) {
- // Look for a "splat" mul pattern - it replicates bits across each half
- // of a value, so a right shift is just a mask of the low bits:
- // lshr i[2N] (mul nuw X, (2^N)+1), N --> and iN X, (2^N)-1
- if (ShAmtC * 2 == BitWidth)
- return BinaryOperator::CreateAnd(X, ConstantInt::get(Ty, *MulC - 2));
-
- // lshr (mul nuw (X, 2^N + 1)), N -> add nuw (X, lshr(X, N))
- if (Op0->hasOneUse()) {
- auto *NewAdd = BinaryOperator::CreateNUWAdd(
- X, Builder.CreateLShr(X, ConstantInt::get(Ty, ShAmtC), "",
- I.isExact()));
- NewAdd->setHasNoSignedWrap(
- cast<OverflowingBinaryOperator>(Op0)->hasNoSignedWrap());
- return NewAdd;
- }
- }
+ // Look for a "splat" mul pattern - it replicates bits across each half of
+ // a value, so a right shift is just a mask of the low bits:
+ // lshr i[2N] (mul nuw X, (2^N)+1), N --> and iN X, (2^N)-1
+ // TODO: Generalize to allow more than just half-width shifts?
+ if (BitWidth > 2 && ShAmtC * 2 == BitWidth && (*MulC - 1).isPowerOf2() &&
+ MulC->logBase2() == ShAmtC)
+ return BinaryOperator::CreateAnd(X, ConstantInt::get(Ty, *MulC - 2));
// The one-use check is not strictly necessary, but codegen may not be
// able to invert the transform and perf may suffer with an extra mul
@@ -1498,16 +1487,6 @@ 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 (BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
- MulC->logBase2() == ShAmtC) {
- return BinaryOperator::CreateNSWAdd(
- X, Builder.CreateLShr(X, ConstantInt::get(Ty, ShAmtC), "",
- I.isExact()));
- }
- }
-
// Try to narrow bswap.
// In the case where the shift amount equals the bitwidth
diff erence, the
// shift is eliminated.
@@ -1711,21 +1690,6 @@ Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) {
if (match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y)))))
return new SExtInst(Builder.CreateICmpSLT(X, Y), Ty);
}
-
- const APInt *MulC;
- if (match(Op0, m_OneUse(m_NSWMul(m_Value(X), m_APInt(MulC)))) &&
- (BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
- MulC->logBase2() == ShAmt &&
- (ShAmt < BitWidth - 1))) /* Minus 1 for the sign bit */ {
-
- // ashr (mul nsw (X, 2^N + 1)), N -> add nsw (X, ashr(X, N))
- auto *NewAdd = BinaryOperator::CreateNSWAdd(
- X,
- Builder.CreateAShr(X, ConstantInt::get(Ty, ShAmt), "", I.isExact()));
- NewAdd->setHasNoUnsignedWrap(
- cast<OverflowingBinaryOperator>(Op0)->hasNoUnsignedWrap());
- return NewAdd;
- }
}
const SimplifyQuery Q = SQ.getWithInstruction(&I);
diff --git a/llvm/test/Transforms/InstCombine/ashr-lshr.ll b/llvm/test/Transforms/InstCombine/ashr-lshr.ll
index c2a4f35412670..ac206dc7999dd 100644
--- a/llvm/test/Transforms/InstCombine/ashr-lshr.ll
+++ b/llvm/test/Transforms/InstCombine/ashr-lshr.ll
@@ -604,262 +604,3 @@ define <2 x i8> @ashr_known_pos_exact_vec(<2 x i8> %x, <2 x i8> %y) {
%r = ashr exact <2 x i8> %p, %y
ret <2 x i8> %r
}
-
-define i32 @lshr_mul_times_3_div_2(i32 %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]]
-; 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 %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]]
-; CHECK-NEXT: ret i32 [[LSHR]]
-;
- %mul = mul nsw i32 %x, 3
- %lshr = lshr exact i32 %mul, 1
- ret i32 %lshr
-}
-
-; Negative test
-
-define i32 @lshr_mul_times_3_div_2_no_flags(i32 %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
-; CHECK-NEXT: ret i32 [[LSHR]]
-;
- %mul = mul i32 %0, 3
- %lshr = lshr i32 %mul, 1
- ret i32 %lshr
-}
-
-; Negative test
-
-define i32 @mul_times_3_div_2_multiuse_lshr(i32 %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
-; CHECK-NEXT: call void @use(i32 [[MUL]])
-; CHECK-NEXT: ret i32 [[RES]]
-;
- %mul = mul nuw i32 %x, 3
- %res = lshr i32 %mul, 1
- call void @use(i32 %mul)
- ret i32 %res
-}
-
-define i32 @lshr_mul_times_3_div_2_exact_2(i32 %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]]
-; CHECK-NEXT: ret i32 [[LSHR]]
-;
- %mul = mul nuw i32 %x, 3
- %lshr = lshr exact i32 %mul, 1
- ret i32 %lshr
-}
-
-define i32 @lshr_mul_times_5_div_4(i32 %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]]
-; CHECK-NEXT: ret i32 [[LSHR]]
-;
- %mul = mul nsw nuw i32 %0, 5
- %lshr = lshr i32 %mul, 2
- ret i32 %lshr
-}
-
-define i32 @lshr_mul_times_5_div_4_exact(i32 %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]]
-; CHECK-NEXT: ret i32 [[LSHR]]
-;
- %mul = mul nsw i32 %x, 5
- %lshr = lshr exact i32 %mul, 2
- ret i32 %lshr
-}
-
-; Negative test
-
-define i32 @lshr_mul_times_5_div_4_no_flags(i32 %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
-; CHECK-NEXT: ret i32 [[LSHR]]
-;
- %mul = mul i32 %0, 5
- %lshr = lshr i32 %mul, 2
- ret i32 %lshr
-}
-
-; Negative test
-
-define i32 @mul_times_5_div_4_multiuse_lshr(i32 %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
-; CHECK-NEXT: call void @use(i32 [[MUL]])
-; CHECK-NEXT: ret i32 [[RES]]
-;
- %mul = mul nuw i32 %x, 5
- %res = lshr i32 %mul, 2
- call void @use(i32 %mul)
- ret i32 %res
-}
-
-define i32 @lshr_mul_times_5_div_4_exact_2(i32 %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]]
-; CHECK-NEXT: ret i32 [[LSHR]]
-;
- %mul = mul nuw i32 %x, 5
- %lshr = lshr exact i32 %mul, 2
- ret i32 %lshr
-}
-
-define i32 @ashr_mul_times_3_div_2(i32 %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]]
-; CHECK-NEXT: ret i32 [[ASHR]]
-;
- %mul = mul nuw nsw i32 %0, 3
- %ashr = ashr i32 %mul, 1
- ret i32 %ashr
-}
-
-define i32 @ashr_mul_times_3_div_2_exact(i32 %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]]
-; CHECK-NEXT: ret i32 [[ASHR]]
-;
- %mul = mul nsw i32 %x, 3
- %ashr = ashr exact i32 %mul, 1
- ret i32 %ashr
-}
-
-; Negative test
-
-define i32 @ashr_mul_times_3_div_2_no_flags(i32 %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
-; CHECK-NEXT: ret i32 [[ASHR]]
-;
- %mul = mul i32 %0, 3
- %ashr = ashr i32 %mul, 1
- ret i32 %ashr
-}
-
-; Negative test
-
-define i32 @ashr_mul_times_3_div_2_no_nsw(i32 %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
-; CHECK-NEXT: ret i32 [[ASHR]]
-;
- %mul = mul nuw i32 %0, 3
- %ashr = ashr i32 %mul, 1
- ret i32 %ashr
-}
-
-; Negative test
-
-define i32 @mul_times_3_div_2_multiuse_ashr(i32 %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
-; CHECK-NEXT: call void @use(i32 [[MUL]])
-; CHECK-NEXT: ret i32 [[RES]]
-;
- %mul = mul nsw i32 %x, 3
- %res = ashr i32 %mul, 1
- call void @use(i32 %mul)
- ret i32 %res
-}
-
-define i32 @ashr_mul_times_3_div_2_exact_2(i32 %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]]
-; CHECK-NEXT: ret i32 [[ASHR]]
-;
- %mul = mul nsw i32 %x, 3
- %ashr = ashr exact i32 %mul, 1
- ret i32 %ashr
-}
-
-define i32 @ashr_mul_times_5_div_4(i32 %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]]
-; CHECK-NEXT: ret i32 [[ASHR]]
-;
- %mul = mul nuw nsw i32 %0, 5
- %ashr = ashr i32 %mul, 2
- ret i32 %ashr
-}
-
-define i32 @ashr_mul_times_5_div_4_exact(i32 %x) {
-; CHECK-LABEL: @ashr_mul_times_5_div_4_exact(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 2
-; CHECK-NEXT: [[ASHR:%.*]] = add nsw i32 [[TMP1]], [[X]]
-; CHECK-NEXT: ret i32 [[ASHR]]
-;
- %mul = mul nsw i32 %x, 5
- %ashr = ashr exact i32 %mul, 2
- ret i32 %ashr
-}
-
-; Negative test
-
-define i32 @ashr_mul_times_5_div_4_no_flags(i32 %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
-; CHECK-NEXT: ret i32 [[ASHR]]
-;
- %mul = mul i32 %0, 5
- %ashr = ashr i32 %mul, 2
- ret i32 %ashr
-}
-
-; Negative test
-
-define i32 @mul_times_5_div_4_multiuse_ashr(i32 %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
-; CHECK-NEXT: call void @use(i32 [[MUL]])
-; CHECK-NEXT: ret i32 [[RES]]
-;
- %mul = mul nsw i32 %x, 5
- %res = ashr i32 %mul, 2
- call void @use(i32 %mul)
- ret i32 %res
-}
-
-define i32 @ashr_mul_times_5_div_4_exact_2(i32 %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]]
-; CHECK-NEXT: ret i32 [[ASHR]]
-;
- %mul = mul nsw i32 %x, 5
- %ashr = ashr exact i32 %mul, 2
- ret i32 %ashr
-}
-
-declare void @use(i32)
diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll
index dfdb6c7b4b268..fa92c1c4b3be4 100644
--- a/llvm/test/Transforms/InstCombine/lshr.ll
+++ b/llvm/test/Transforms/InstCombine/lshr.ll
@@ -628,28 +628,15 @@ define i32 @mul_splat_fold_wrong_lshr_const(i32 %x) {
ret i32 %t
}
-; Negative test (but simplifies into a
diff erent transform)
+; Negative test
define i32 @mul_splat_fold_no_nuw(i32 %x) {
; CHECK-LABEL: @mul_splat_fold_no_nuw(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 16
-; CHECK-NEXT: [[T:%.*]] = add nsw i32 [[TMP1]], [[X]]
-; CHECK-NEXT: ret i32 [[T]]
-;
- %m = mul nsw i32 %x, 65537
- %t = lshr i32 %m, 16
- ret i32 %t
-}
-
-; Negative test
-
-define i32 @mul_splat_fold_no_flags(i32 %x) {
-; CHECK-LABEL: @mul_splat_fold_no_flags(
-; CHECK-NEXT: [[M:%.*]] = mul i32 [[X:%.*]], 65537
+; CHECK-NEXT: [[M:%.*]] = mul nsw i32 [[X:%.*]], 65537
; CHECK-NEXT: [[T:%.*]] = lshr i32 [[M]], 16
; CHECK-NEXT: ret i32 [[T]]
;
- %m = mul i32 %x, 65537
+ %m = mul nsw i32 %x, 65537
%t = lshr i32 %m, 16
ret i32 %t
}
More information about the llvm-commits
mailing list