[llvm] [RISCV] Handle freeze in vp.merge widening codegen prepare (PR #189346)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 06:07:18 PDT 2026
================
@@ -130,57 +132,64 @@ bool RISCVCodeGenPrepare::visitAnd(BinaryOperator &BO) {
// generate a single vmerge.vim:
//
// loop:
-// %phi = phi <vscale x 4 x i8> [ zeroinitializer, %entry ], [ %rec, %loop ]
+// %phi = phi <vscale x 4 x i8> [zeroinitializer, %entry], [%freeze, %loop]
// %cmp = icmp ...
// %rec = call <vscale x 4 x i8> @llvm.vp.merge(%cmp, i8 true, %phi, %evl)
-// %trunc = trunc <vscale x 4 x i8> %rec to <vscale x 4 x i1>
+// %freeze = freeze <vscale x 4 x i8> %rec
+// %trunc = trunc <vscale x 4 x i8> %freeze to <vscale x 4 x i1>
// ...
// middle:
-// %res = call i1 @llvm.vector.reduce.or(<vscale x 4 x i1> %rec)
+// %res = call i1 @llvm.vector.reduce.or(<vscale x 4 x i1> %trunc)
//
// The trunc will normally be sunk outside of the loop, but even if there are
// users inside the loop it is still profitable.
-bool RISCVCodeGenPrepare::widenVPMerge(IntrinsicInst &II) {
- if (!II.getType()->getScalarType()->isIntegerTy(1))
+bool RISCVCodeGenPrepare::widenVPMerge(Instruction *Root) {
+ if (!Root->getType()->getScalarType()->isIntegerTy(1))
return false;
Value *Mask, *True, *PhiV, *EVL;
using namespace PatternMatch;
- if (!match(&II,
- m_Intrinsic<Intrinsic::vp_merge>(m_Value(Mask), m_Value(True),
- m_Value(PhiV), m_Value(EVL))))
+ auto m_VPMerge = m_Intrinsic<Intrinsic::vp_merge>(
+ m_Value(Mask), m_Value(True), m_Value(PhiV), m_Value(EVL));
+ if (!match(Root, m_CombineOr(m_VPMerge, m_Freeze(m_VPMerge))))
return false;
auto *Phi = dyn_cast<PHINode>(PhiV);
if (!Phi || !Phi->hasOneUse() || Phi->getNumIncomingValues() != 2 ||
!match(Phi->getIncomingValue(0), m_Zero()) ||
- Phi->getIncomingValue(1) != &II)
+ Phi->getIncomingValue(1) != Root)
return false;
Type *WideTy =
- VectorType::get(IntegerType::getInt8Ty(II.getContext()),
- cast<VectorType>(II.getType())->getElementCount());
+ VectorType::get(IntegerType::getInt8Ty(Root->getContext()),
+ cast<VectorType>(Root->getType())->getElementCount());
IRBuilder<> Builder(Phi);
PHINode *WidePhi = Builder.CreatePHI(WideTy, 2);
WidePhi->addIncoming(ConstantAggregateZero::get(WideTy),
Phi->getIncomingBlock(0));
- Builder.SetInsertPoint(&II);
+ Builder.SetInsertPoint(Root);
Value *WideTrue = Builder.CreateZExt(True, WideTy);
Value *WideMerge = Builder.CreateIntrinsic(Intrinsic::vp_merge, {WideTy},
{Mask, WideTrue, WidePhi, EVL});
+ if (isa<FreezeInst>(Root))
+ WideMerge = Builder.CreateFreeze(WideMerge);
WidePhi->addIncoming(WideMerge, Phi->getIncomingBlock(1));
- Value *Trunc = Builder.CreateTrunc(WideMerge, II.getType());
+ Value *Trunc = Builder.CreateTrunc(WideMerge, Root->getType());
- II.replaceAllUsesWith(Trunc);
+ Root->replaceAllUsesWith(Trunc);
// Break the cycle and delete the old chain.
Phi->setIncomingValue(1, Phi->getIncomingValue(0));
- llvm::RecursivelyDeleteTriviallyDeadInstructions(&II);
+ llvm::RecursivelyDeleteTriviallyDeadInstructions(Root);
return true;
}
+bool RISCVCodeGenPrepare::visitFreezeInst(FreezeInst &I) {
+ return widenVPMerge(&I);
----------------
lukel97 wrote:
Done in 039b68b9a4de, I think it makes the code easier to read anyway
https://github.com/llvm/llvm-project/pull/189346
More information about the llvm-commits
mailing list