[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