[PATCH] D148420: [InstCombine] Enhance select icmp and folding
Peixin Qiao via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 15 07:54:11 PDT 2023
peixin updated this revision to Diff 513908.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D148420/new/
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,35 @@
return V;
}
+/// This folds:
+/// select (icmp eq (and X, C), 0), 0, (shl X, K)
+/// iff C is a mask and the number of its 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;
+
+ const APInt *C;
+ if (!match(Cmp->getOperand(0), m_And(m_Specific(X), m_APInt(C))))
+ return nullptr;
+
+ if (!C->isMask() || (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 +1751,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.513908.patch
Type: text/x-patch
Size: 2411 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230415/f7e8271e/attachment.bin>
More information about the llvm-commits
mailing list