[llvm] r343417 - [PHIElimination] Lower a PHI node with only undef uses as IMPLICIT_DEF

Bjorn Pettersson via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 30 10:26:58 PDT 2018


Author: bjope
Date: Sun Sep 30 10:26:58 2018
New Revision: 343417

URL: http://llvm.org/viewvc/llvm-project?rev=343417&view=rev
Log:
[PHIElimination] Lower a PHI node with only undef uses as IMPLICIT_DEF

Summary:
The lowering of PHI nodes used to detect if all inputs originated
from IMPLICIT_DEF's. If so the PHI node was replaced by an
IMPLICIT_DEF. Now we also consider undef uses when checking the
inputs. So if all inputs are implicitly defined or undef we
lower the PHI to an IMPLICIT_DEF. This makes
PHIElimination::LowerPHINode more consistent as it checks
both implicit and undef properties at later stages.

Reviewers: MatzeB, tstellar

Reviewed By: MatzeB

Subscribers: jvesely, nhaehnle, llvm-commits

Differential Revision: https://reviews.llvm.org/D52558

Added:
    llvm/trunk/test/CodeGen/AMDGPU/phi-elimination-assertion.mir
Modified:
    llvm/trunk/lib/CodeGen/PHIElimination.cpp

Modified: llvm/trunk/lib/CodeGen/PHIElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.cpp?rev=343417&r1=343416&r2=343417&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PHIElimination.cpp (original)
+++ llvm/trunk/lib/CodeGen/PHIElimination.cpp Sun Sep 30 10:26:58 2018
@@ -211,26 +211,26 @@ bool PHIElimination::EliminatePHINodes(M
   return true;
 }
 
-/// isImplicitlyDefined - Return true if all defs of VirtReg are implicit-defs.
+/// Return true if all defs of VirtReg are implicit-defs.
 /// This includes registers with no defs.
 static bool isImplicitlyDefined(unsigned VirtReg,
-                                const MachineRegisterInfo *MRI) {
-  for (MachineInstr &DI : MRI->def_instructions(VirtReg))
+                                const MachineRegisterInfo &MRI) {
+  for (MachineInstr &DI : MRI.def_instructions(VirtReg))
     if (!DI.isImplicitDef())
       return false;
   return true;
 }
 
-/// isSourceDefinedByImplicitDef - Return true if all sources of the phi node
-/// are implicit_def's.
-static bool isSourceDefinedByImplicitDef(const MachineInstr *MPhi,
-                                         const MachineRegisterInfo *MRI) {
-  for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2)
-    if (!isImplicitlyDefined(MPhi->getOperand(i).getReg(), MRI))
+/// Return true if all sources of the phi node are implicit_def's, or undef's.
+static bool allPhiOperandsUndefined(const MachineInstr &MPhi,
+                                    const MachineRegisterInfo &MRI) {
+  for (unsigned I = 1, E = MPhi.getNumOperands(); I != E; I += 2) {
+    const MachineOperand &MO = MPhi.getOperand(I);
+    if (!isImplicitlyDefined(MO.getReg(), MRI) && !MO.isUndef())
       return false;
+  }
   return true;
 }
-
 /// LowerPHINode - Lower the PHI node at the top of the specified block.
 void PHIElimination::LowerPHINode(MachineBasicBlock &MBB,
                                   MachineBasicBlock::iterator LastPHIIt) {
@@ -255,8 +255,8 @@ void PHIElimination::LowerPHINode(Machin
   // after any remaining phi nodes) which copies the new incoming register
   // into the phi node destination.
   const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
-  if (isSourceDefinedByImplicitDef(MPhi, MRI))
-    // If all sources of a PHI node are implicit_def, just emit an
+  if (allPhiOperandsUndefined(*MPhi, *MRI))
+    // If all sources of a PHI node are implicit_def or undef uses, just emit an
     // implicit_def instead of a copy.
     BuildMI(MBB, AfterPHIsIt, MPhi->getDebugLoc(),
             TII->get(TargetOpcode::IMPLICIT_DEF), DestReg);
@@ -373,7 +373,7 @@ void PHIElimination::LowerPHINode(Machin
     unsigned SrcReg = MPhi->getOperand(i*2+1).getReg();
     unsigned SrcSubReg = MPhi->getOperand(i*2+1).getSubReg();
     bool SrcUndef = MPhi->getOperand(i*2+1).isUndef() ||
-      isImplicitlyDefined(SrcReg, MRI);
+      isImplicitlyDefined(SrcReg, *MRI);
     assert(TargetRegisterInfo::isVirtualRegister(SrcReg) &&
            "Machine PHI Operands must all be virtual registers!");
 

Added: llvm/trunk/test/CodeGen/AMDGPU/phi-elimination-assertion.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/phi-elimination-assertion.mir?rev=343417&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AMDGPU/phi-elimination-assertion.mir (added)
+++ llvm/trunk/test/CodeGen/AMDGPU/phi-elimination-assertion.mir Sun Sep 30 10:26:58 2018
@@ -0,0 +1,69 @@
+# RUN: llc -mtriple amdgcn -run-pass livevars -run-pass phi-node-elimination -o - %s | FileCheck %s
+
+################################################################################
+# This test used to hit an assert in PHIElimination:
+#  PHIElimination::LowerPHINode(llvm::MachineBasicBlock&, llvm::MachineBasicBlock::iterator): Assertion `KillInst->readsRegister(SrcReg) && "Cannot find kill instruction"'
+
+---
+name:            foo
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    S_CBRANCH_SCC0 %bb.2, implicit undef $scc
+
+  bb.1:
+    %1:sreg_32_xm0 = S_MOV_B32 255
+    S_BRANCH %bb.3
+
+  bb.2:
+    %2:sreg_32_xm0 = S_MOV_B32 254
+
+  bb.3:
+    dead %3:sreg_32_xm0 = PHI undef %2, %bb.2, undef %1, %bb.1
+    %4:sreg_32_xm0 = PHI %2, %bb.2, %1, %bb.1
+    S_NOP 0, implicit %4
+...
+
+# CHECK-LABEL: name:            foo
+# CHECK:   bb.3:
+# CHECK-NEXT:     %3:sreg_32_xm0 = COPY killed %4
+# CHECK-NEXT:     dead %2:sreg_32_xm0 = IMPLICIT_DEF
+# CHECK-NEXT:     S_NOP 0, implicit killed %3
+
+
+################################################################################
+# Similar test as above, but with swapped order for the PHI nodes.
+# With this PHI node order we did not hit the assert, but we used to get
+#
+#  bb.3:
+#    dead %3:sreg_32_xm0 = COPY killed %4
+#    %2:sreg_32_xm0 = COPY %4
+#    S_NOP 0, implicit killed %2
+#
+# which looks weird regarding killed flags for %4.
+
+---
+name:            bar
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    S_CBRANCH_SCC0 %bb.2, implicit undef $scc
+
+  bb.1:
+    %1:sreg_32_xm0 = S_MOV_B32 255
+    S_BRANCH %bb.3
+
+  bb.2:
+    %2:sreg_32_xm0 = S_MOV_B32 254
+
+  bb.3:
+    %4:sreg_32_xm0 = PHI %2, %bb.2, %1, %bb.1
+    dead %3:sreg_32_xm0 = PHI undef %2, %bb.2, undef %1, %bb.1
+    S_NOP 0, implicit %4
+...
+
+# CHECK-LABEL: name:            bar
+# CHECK:   bb.3:
+# CHECK-NEXT:     dead %3:sreg_32_xm0 = IMPLICIT_DEF
+# CHECK-NEXT:     %2:sreg_32_xm0 = COPY killed %4
+# CHECK-NEXT:     S_NOP 0, implicit killed %2




More information about the llvm-commits mailing list