[llvm] [GISel][CombinerHelper] Push freeze through non-poison-producing operands (PR #90618)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 30 07:51:34 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());
----------------
arsenm wrote:

This shouldn't be necessary anymore 

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


More information about the llvm-commits mailing list