[llvm] [InstCombine] Missed optimization for select a%2==0, (a/2*2)*(a/2*2), 0 (PR #92658)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 15 12:56:28 PDT 2024


================
@@ -1073,6 +1073,50 @@ static Value *foldAbsDiff(ICmpInst *Cmp, Value *TVal, Value *FVal,
   return nullptr;
 }
 
+// When the lsb of cond is 0:
+// cond ? A & -2 : B --> cond ? A : B
+// cond ? BinOp (A & -2), (A & -2) : B --> cond ? BinOp A, A : B
+static Value *foldSelectWithIcmpEqAndPattern(ICmpInst *Cmp, Value *TVal,
+                                             Value *FVal,
+                                             InstCombiner::BuilderTy &Builder,
+                                             SelectInst &SI,
+                                             InstCombinerImpl &IC) {
+
+  Value *A;
+  ConstantInt *MaskedConstant;
+
+  // Checks if true branche matches the pattern 'A % 2'.
+  if (match(TVal,
+            m_OneUse(m_c_And(m_Value(A), m_ConstantInt(MaskedConstant)))) &&
+      MaskedConstant->getValue().getSExtValue() == -2) {
+    KnownBits Known;
+    Known = IC.computeKnownBits(A, 0, &SI);
+    IC.computeKnownBitsFromCond(A, Cmp, Known, 0, &SI, false);
+    if (Known.Zero[0])
+      return Builder.CreateSelect(Cmp, A, FVal);
+    else
+      return nullptr;
+  }
+
+  // Checks if true branch matches nested 'A % 2' within a binary operation.
+  Value *MulVal;
+  if (match(TVal, m_OneUse(m_BinOp(m_Value(MulVal), m_Deferred(MulVal)))))
+    if (match(MulVal, m_c_And(m_Value(A), m_ConstantInt(MaskedConstant))) &&
+        MaskedConstant->getValue().getSExtValue() == -2) {
+      KnownBits Known;
+      Known = IC.computeKnownBits(A, 0, &SI);
+      IC.computeKnownBitsFromCond(A, Cmp, Known, 0, &SI, false);
+      if (Known.Zero[0]) {
+        Instruction::BinaryOps OpCode = cast<BinaryOperator>(TVal)->getOpcode();
+        Value *NewTValue = Builder.CreateBinOp(OpCode, A, A);
+        return Builder.CreateSelect(Cmp, NewTValue, FVal);
+      } else
+        return nullptr;
+    }
+
+  return nullptr;
+}
+
----------------
goldsteinn wrote:

In general, I think this would be better as a recursive function.

The base case being matching `m_c_And(m_Value(A), m_APInt(Mask))` and then you can try to simplfy operands of binops/etc... you find along the way.


https://github.com/llvm/llvm-project/pull/92658


More information about the llvm-commits mailing list