[llvm] [InstCombine] Fold reconstruction across select (PR #145102)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 22 11:00:59 PDT 2025
================
@@ -1349,6 +1349,45 @@ Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
return nullptr;
};
+ // Special case for reconstructing across a select:
+ // (Cond ? V1 : (X & Mask)) |
+ // zext (Cond ? V2 : trunc X)
+ // -> (Cond ? (V1 | zext V2) : X)
+ auto foldReconstruction = [&](Value *V1, Value *Masked,
+ Value *ZExtSel) -> Value * {
+ if (Opcode != Instruction::Or)
+ return nullptr;
+
+ Value *X;
+ const APInt *C;
+ if (!match(Masked, m_OneUse(m_And(m_Value(X), m_APInt(C)))))
+ return nullptr;
+
+ const APInt *V2;
+ Value *Trunc;
+ if (!match(ZExtSel,
+ m_ZExt(m_OneUse(m_Select(m_Specific(Cond), m_APInt(V2),
+ m_Value(Trunc))))))
+ return nullptr;
+
+ if (*C != APInt::getBitsSetFrom(X->getType()->getScalarSizeInBits(),
+ Trunc->getType()->getScalarSizeInBits())) {
+ return nullptr;
+ }
+
+ if (!match(Trunc, m_Trunc(m_Specific(X))))
+ return nullptr;
+
+ unsigned V1Width = V1->getType()->getScalarSizeInBits();
+ APInt ZextV2 = V2->zext(V1Width);
+ Value *True = simplifyBinOp(
+ Opcode, V1, ConstantInt::get(V1->getType(), ZextV2), FMF, Q);
+ if (!True)
+ return nullptr;
+
+ return Builder.CreateSelect(Cond, True, X, I.getName());
----------------
dtcxzyw wrote:
As V1 is also a constant in practice, we can simply use APInt arithmetic.
https://github.com/llvm/llvm-project/pull/145102
More information about the llvm-commits
mailing list