[llvm] [InstCombine] Simplify conditional round-up to power-of-2 alignment (PR #184989)

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 00:41:46 PDT 2026


================
@@ -2382,6 +2382,44 @@ static Value *simplifyAndOrWithOpReplaced(Value *V, Value *Op, Value *RepOp,
   return IC.Builder.CreateBinOp(I->getOpcode(), NewOp0, NewOp1);
 }
 
+// The pattern div_ceil(X, P) * P, where P is a power of 2, lowers to a
+// conditional round-up of the following kind: (X + select(X % Pow2 == 0, 0,
+// Pow2)) & -Pow2. This may be simplified to (X + (Pow2-1)) & -Pow2.
+static Instruction *
+foldRoundUpToPow2Alignment(BinaryOperator &I,
+                           InstCombiner::BuilderTy &Builder) {
+  const APInt *NegP;
+  Value *Add;
+  if (!match(&I, m_And(m_Value(Add), m_APInt(NegP))) ||
+      !NegP->isNegatedPowerOf2())
+    return nullptr;
+
+  Value *X, *Cond;
+  const APInt *T, *F;
+  if (!match(Add, m_c_Add(m_Value(X),
+                          m_Select(m_Value(Cond), m_APInt(T), m_APInt(F)))) ||
+      !Add->hasOneUse())
+    return nullptr;
+
+  CmpPredicate Pred;
+  const APInt &Pow2 = -*NegP;
+  const APInt &Mask = Pow2 - 1;
----------------
antoniofrighetto wrote:

I think the code is correct, binding a const reference to a temporary in C++ happens to extend the temporary's lifetime to match the lifetime of the reference (the temporary here is the one returned by value by `inline APInt operator-(APInt v)`). Your version is much better though, updated, thanks!

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


More information about the llvm-commits mailing list