[PATCH] D101508: [EarlyIfConversion] Avoid producing selects with identical operands

Jon Roelofs via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 28 18:39:15 PDT 2021


jroelofs created this revision.
jroelofs added reviewers: greened, efriedma, thegameg.
Herald added a subscriber: hiraditya.
jroelofs requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This extends the early-ifcvt pass to avoid a few more cases where the resulting select instructions would have matching operands.  Additionally, we now use TII to determine "sameness" of the operands so that as TII gets smarter, so too will ifcvt.

      

The attached test case was bugpoint-reduced down from CINT2000/252.eon in the test-suite. See: https://clang.godbolt.org/z/WvnrcrGEn


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D101508

Files:
  llvm/lib/CodeGen/EarlyIfConversion.cpp


Index: llvm/lib/CodeGen/EarlyIfConversion.cpp
===================================================================
--- llvm/lib/CodeGen/EarlyIfConversion.cpp
+++ llvm/lib/CodeGen/EarlyIfConversion.cpp
@@ -557,6 +557,24 @@
   return true;
 }
 
+/// \return true iff the two registers are known to have the same value.
+static bool hasSameValue(const MachineRegisterInfo &MRI,
+                         const TargetInstrInfo *TII,
+                         Register TReg, Register FReg) {
+  if (TReg == FReg)
+    return true;
+
+  const MachineInstr *TDef = TReg.isVirtual() ? MRI.getVRegDef(TReg) : nullptr;
+  const MachineInstr *FDef = FReg.isVirtual() ? MRI.getVRegDef(FReg) : nullptr;
+  if (TDef && TDef == FDef)
+    return true;
+
+  if (TDef && FDef)
+    return TII->produceSameValue(*TDef, *FDef, &MRI);
+
+  return false;
+}
+
 /// replacePHIInstrs - Completely replace PHI instructions with selects.
 /// This is possible when the only Tail predecessors are the if-converted
 /// blocks.
@@ -571,7 +589,14 @@
     PHIInfo &PI = PHIs[i];
     LLVM_DEBUG(dbgs() << "If-converting " << *PI.PHI);
     Register DstReg = PI.PHI->getOperand(0).getReg();
-    TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg, Cond, PI.TReg, PI.FReg);
+    if (hasSameValue(*MRI, TII, PI.TReg, PI.FReg)) {
+      // We do not need the select instruction if both incoming values are
+      // equal, but we do need a COPY.
+      BuildMI(*Head, FirstTerm, HeadDL, TII->get(TargetOpcode::COPY), DstReg)
+        .addReg(PI.TReg);
+    } else {
+      TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg, Cond, PI.TReg, PI.FReg);
+    }
     LLVM_DEBUG(dbgs() << "          --> " << *std::prev(FirstTerm));
     PI.PHI->eraseFromParent();
     PI.PHI = nullptr;
@@ -592,7 +617,7 @@
     unsigned DstReg = 0;
 
     LLVM_DEBUG(dbgs() << "If-converting " << *PI.PHI);
-    if (PI.TReg == PI.FReg) {
+    if (hasSameValue(*MRI, TII, PI.TReg, PI.FReg)) {
       // We do not need the select instruction if both incoming values are
       // equal.
       DstReg = PI.TReg;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101508.341379.patch
Type: text/x-patch
Size: 2055 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210429/606cf61f/attachment.bin>


More information about the llvm-commits mailing list