[PATCH] D148420: [InstCombine] Enhance select icmp and folding
Peixin Qiao via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 15 02:17:06 PDT 2023
peixin created this revision.
peixin added a project: LLVM.
Herald added a subscriber: hiraditya.
Herald added a project: All.
peixin requested review of this revision.
Herald added a subscriber: llvm-commits.
This folds (a << k) ? 2^k * a : 0 to 2^k * a.
Fix #62155.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D148420
Files:
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/test/Transforms/InstCombine/select-icmp-and.ll
Index: llvm/test/Transforms/InstCombine/select-icmp-and.ll
===================================================================
--- llvm/test/Transforms/InstCombine/select-icmp-and.ll
+++ llvm/test/Transforms/InstCombine/select-icmp-and.ll
@@ -618,3 +618,16 @@
ret i8 %t3
}
+; (x << k) ? 2^k * x : 0 --> 2^k * x
+
+define i32 @test_select_icmp_and_shl(i32 %x) {
+; CHECK-LABEL: @test_select_icmp_and_shl(
+; CHECK-NEXT: [[T:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT: ret i32 [[T]]
+;
+ %shl.mask = and i32 %x, 1073741823
+ %tobool.not = icmp eq i32 %shl.mask, 0
+ %mul = shl i32 %x, 2
+ %cond = select i1 %tobool.not, i32 0, i32 %mul
+ ret i32 %cond
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -227,6 +227,42 @@
return V;
}
+/// This folds:
+/// select (icmp eq (and X, C), 0), 0, (shl X, K)
+/// iff C is one number like "0..01..1" and the number of leading zeros is
+/// equal to K.
+/// To the following:
+/// shl X, K
+static Value *foldSelectICmpAndZeroShl(SelectInst &Sel, ICmpInst *Cmp,
+ InstCombiner::BuilderTy &Builder) {
+ // TODO: vector select or vector compare.
+ if (Sel.getType()->isVectorTy() || Cmp->getType()->isVectorTy())
+ return nullptr;
+
+ const APInt *K;
+ Value *X;
+ if (!match(Sel.getTrueValue(), m_Zero()) ||
+ !match(Sel.getFalseValue(), m_Shl(m_Value(X), m_APInt(K))) ||
+ !ICmpInst::isEquality(Cmp->getPredicate()) ||
+ !match(Cmp->getOperand(1), m_Zero()))
+ return nullptr;
+
+ Value *V;
+ const APInt *C;
+ if (!match(Cmp->getOperand(0), m_And(m_Value(V), m_APInt(C))))
+ return nullptr;
+
+ if (X != V)
+ return nullptr;
+
+ uint32_t BitWidth = V->getType()->getScalarSizeInBits();
+ if (C->countLeadingZeros() + C->countTrailingOnes() != BitWidth ||
+ (int64_t)C->countLeadingZeros() != K->getSExtValue())
+ return nullptr;
+
+ return Sel.getFalseValue();
+}
+
/// We want to turn code that looks like this:
/// %C = or %A, %B
/// %D = select %cond, %C, %A
@@ -1722,6 +1758,9 @@
if (Value *V = foldSelectICmpAnd(SI, ICI, Builder))
return replaceInstUsesWith(SI, V);
+ if (Value *V = foldSelectICmpAndZeroShl(SI, ICI, Builder))
+ return replaceInstUsesWith(SI, V);
+
// NOTE: if we wanted to, this is where to detect integer MIN/MAX
Value *TrueVal = SI.getTrueValue();
Value *FalseVal = SI.getFalseValue();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D148420.513865.patch
Type: text/x-patch
Size: 2597 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230415/ccbcf652/attachment.bin>
More information about the llvm-commits
mailing list