[llvm] [GISel][CombinerHelper] Push freeze through non-poison-producing operands (PR #90618)
Dhruv Chawla via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 30 08:13:42 PDT 2024
================
@@ -223,6 +223,64 @@ void CombinerHelper::applyCombineCopy(MachineInstr &MI) {
replaceRegWith(MRI, DstReg, SrcReg);
}
+bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
+ MachineInstr &MI, BuildFnTy &MatchInfo) {
+ // Ported from InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating
+ Register DstOp = MI.getOperand(0).getReg();
+ Register OrigOp = MI.getOperand(1).getReg();
+
+ if (OrigOp.isPhysical() || !MRI.hasOneNonDBGUse(OrigOp))
+ return false;
+
+ MachineInstr *OrigDef = MRI.getUniqueVRegDef(OrigOp);
+ // Avoid trying to fold G_PHI, G_UNMERGE_VALUES, G_FREEZE (the latter is
+ // handled by idempotent_prop)
+ if (!OrigDef || OrigDef->isPHI() || isa<GUnmerge>(OrigDef) ||
+ isa<GFreeze>(OrigDef))
+ return false;
+
+ if (canCreateUndefOrPoison(OrigOp, MRI))
+ return false;
+
+ std::optional<MachineOperand> MaybePoisonOperand = std::nullopt;
+ for (MachineOperand &Operand : OrigDef->uses()) {
+ // Avoid working on non-register operands or physical registers.
+ if (!Operand.isReg() || Operand.getReg().isPhysical())
+ return false;
+
+ if (isGuaranteedNotToBeUndefOrPoison(Operand.getReg(), MRI))
+ continue;
+
+ if (!MaybePoisonOperand)
+ MaybePoisonOperand = Operand;
+ // We have more than one maybe-poison operand. Moving the freeze is unsafe.
+ else
+ return false;
+ }
+
+ // Eliminate freeze if all operands are guaranteed non-poison
+ if (!MaybePoisonOperand) {
+ MatchInfo = [=](MachineIRBuilder &B) { MRI.replaceRegWith(DstOp, OrigOp); };
+ return true;
+ }
+
+ if (!MaybePoisonOperand->isReg())
+ return false;
+
+ Register MaybePoisonOperandReg = MaybePoisonOperand->getReg();
+ LLT MaybePoisonOperandRegTy = MRI.getType(MaybePoisonOperandReg);
+
+ MatchInfo = [=](MachineIRBuilder &B) mutable {
+ auto Reg = MRI.createGenericVirtualRegister(MaybePoisonOperandRegTy);
+ B.setInsertPt(*OrigDef->getParent(), OrigDef->getIterator());
----------------
dc03-work wrote:
The new freeze has to be inserted before the use which will come before the old freeze that is being removed, so the insert point has to be moved back.
https://github.com/llvm/llvm-project/pull/90618
More information about the llvm-commits
mailing list