[llvm] 295d6b1 - [InstCombine] Fold `(X * (Y << K)) u>> K -> X * Y` when highbits are not demanded (#111151)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 2 20:04:08 PST 2024
Author: Yingwei Zheng
Date: 2024-12-03T12:04:04+08:00
New Revision: 295d6b18f77fc67c186c031204a82ff82cf59daa
URL: https://github.com/llvm/llvm-project/commit/295d6b18f77fc67c186c031204a82ff82cf59daa
DIFF: https://github.com/llvm/llvm-project/commit/295d6b18f77fc67c186c031204a82ff82cf59daa.diff
LOG: [InstCombine] Fold `(X * (Y << K)) u>> K -> X * Y` when highbits are not demanded (#111151)
Alive2: https://alive2.llvm.org/ce/z/Z7QgjH
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
llvm/test/Transforms/InstCombine/lshr.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 392c5c78345c29..943598a30f040f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -776,6 +776,15 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
return InsertNewInstWith(Shl, I->getIterator());
}
}
+
+ const APInt *Factor;
+ if (match(I->getOperand(0),
+ m_OneUse(m_Mul(m_Value(X), m_APInt(Factor)))) &&
+ Factor->countr_zero() >= ShiftAmt) {
+ BinaryOperator *Mul = BinaryOperator::CreateMul(
+ X, ConstantInt::get(X->getType(), Factor->lshr(ShiftAmt)));
+ return InsertNewInstWith(Mul, I->getIterator());
+ }
}
// Unsigned shift right.
diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll
index 00626015d2ed76..ff358c6bc772a7 100644
--- a/llvm/test/Transforms/InstCombine/lshr.ll
+++ b/llvm/test/Transforms/InstCombine/lshr.ll
@@ -1523,3 +1523,65 @@ define <2 x i8> @bool_add_lshr_vec_wrong_shift_amt(<2 x i1> %a, <2 x i1> %b) {
%lshr = lshr <2 x i8> %add, <i8 1, i8 2>
ret <2 x i8> %lshr
}
+
+define i32 @lowbits_of_lshr_mul(i64 %x) {
+; CHECK-LABEL: @lowbits_of_lshr_mul(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[X:%.*]] to i32
+; CHECK-NEXT: [[CONV:%.*]] = mul i32 [[TMP0]], 15
+; CHECK-NEXT: ret i32 [[CONV]]
+;
+entry:
+ %mul = mul i64 %x, 64424509440
+ %shift = lshr i64 %mul, 32
+ %conv = trunc i64 %shift to i32
+ ret i32 %conv
+}
+
+define i32 @lowbits_of_lshr_mul_mask(i32 %x) {
+; CHECK-LABEL: @lowbits_of_lshr_mul_mask(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = mul i32 [[X:%.*]], 1600
+; CHECK-NEXT: [[CONV:%.*]] = and i32 [[TMP0]], 32704
+; CHECK-NEXT: ret i32 [[CONV]]
+;
+entry:
+ %mul = mul i32 %x, 104857600
+ %shift = lshr i32 %mul, 16
+ %conv = and i32 %shift, 32767
+ ret i32 %conv
+}
+
+; Negative tests
+
+define i32 @lowbits_of_lshr_mul_mask_multiuse(i32 %x) {
+; CHECK-LABEL: @lowbits_of_lshr_mul_mask_multiuse(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X:%.*]], 104857600
+; CHECK-NEXT: call void @use(i32 [[MUL]])
+; CHECK-NEXT: [[SHIFT:%.*]] = lshr exact i32 [[MUL]], 16
+; CHECK-NEXT: [[CONV:%.*]] = and i32 [[SHIFT]], 32704
+; CHECK-NEXT: ret i32 [[CONV]]
+;
+entry:
+ %mul = mul i32 %x, 104857600
+ call void @use(i32 %mul)
+ %shift = lshr i32 %mul, 16
+ %conv = and i32 %shift, 32767
+ ret i32 %conv
+}
+
+define i32 @lowbits_of_lshr_mul_mask_indivisible(i32 %x) {
+; CHECK-LABEL: @lowbits_of_lshr_mul_mask_indivisible(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X:%.*]], 25600
+; CHECK-NEXT: [[SHIFT:%.*]] = lshr i32 [[MUL]], 16
+; CHECK-NEXT: [[CONV:%.*]] = and i32 [[SHIFT]], 32767
+; CHECK-NEXT: ret i32 [[CONV]]
+;
+entry:
+ %mul = mul i32 %x, 25600
+ %shift = lshr i32 %mul, 16
+ %conv = and i32 %shift, 32767
+ ret i32 %conv
+}
More information about the llvm-commits
mailing list