[PATCH] D77783: [MachineVerifier] Relax verifier for predicated returns

Oliver Stannard (Linaro) via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 9 02:40:55 PDT 2020


ostannard created this revision.
ostannard added reviewers: arphaman, ahatanak, efriedma.
Herald added subscribers: danielkiss, dexonsmith, hiraditya, kristof.beyls.
Herald added a project: LLVM.

For ARM, the if-converter can generate predicated tail-calls. These are calls, so have a mask of clobbered registers, but execution may continue beyond them, so we want to check liveness of registers after them. However, it is not possible for the instruction to both clobber registers and continue execution, so we shouldn't consider the register mask when checking liveness in the verifier.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77783

Files:
  llvm/lib/CodeGen/MachineVerifier.cpp
  llvm/test/MachineVerifier/predicated-call.mir


Index: llvm/test/MachineVerifier/predicated-call.mir
===================================================================
--- /dev/null
+++ llvm/test/MachineVerifier/predicated-call.mir
@@ -0,0 +1,35 @@
+# RUN: llc -o - %s -mtriple=armv7a-none-eabi --run-pass none
+# REQUIRES: arm-registered-target
+
+# It looks like r0 is clobbered by the register mask of the first tTAILJMPd, so
+# the second tTAILJMPd uses a dead register ($r0).  However, the first
+# instruction is predicated, so there are two possible executions:
+# - If the predicate is true, then the tail call will be executed, and the
+#   second will never be reached, so the liveness of r0 there doesn't matter.
+# - If the predicate is false, the first call won't be executed, so $r0 will
+#   remain live until the second call.
+
+--- |
+  declare void @bar(i32)
+  declare void @baz(i32)
+  define void @foo() {
+  entry:
+    ret void
+  }
+...
+
+---
+name:            foo
+tracksRegLiveness: true
+machineFunctionInfo: {}
+body:             |
+  bb.0.entry:
+    liveins: $lr
+  
+    $r0 = IMPLICIT_DEF
+    $cpsr = IMPLICIT_DEF
+
+    tTAILJMPd @bar, 1 /* CC::ne */, killed $cpsr, csr_aapcs, implicit $sp, implicit $r0
+    tTAILJMPd @baz, 14 /* CC::al */, $noreg, csr_aapcs, implicit $sp, implicit $r0
+
+...
Index: llvm/lib/CodeGen/MachineVerifier.cpp
===================================================================
--- llvm/lib/CodeGen/MachineVerifier.cpp
+++ llvm/lib/CodeGen/MachineVerifier.cpp
@@ -2097,13 +2097,17 @@
   BBInfo &MInfo = MBBInfoMap[MI->getParent()];
   set_union(MInfo.regsKilled, regsKilled);
   set_subtract(regsLive, regsKilled); regsKilled.clear();
-  // Kill any masked registers.
-  while (!regMasks.empty()) {
-    const uint32_t *Mask = regMasks.pop_back_val();
-    for (RegSet::iterator I = regsLive.begin(), E = regsLive.end(); I != E; ++I)
-      if (Register::isPhysicalRegister(*I) &&
-          MachineOperand::clobbersPhysReg(Mask, *I))
-        regsDead.push_back(*I);
+  // Kill any masked registers, unless the instruction is a predicated return,
+  // in which case either it returns (so we don't care about liveness after
+  // it), or it doesn't actually clobber any registers.
+  if (!(TII->isPredicated(*MI) && MI->isReturn())) {
+    while (!regMasks.empty()) {
+      const uint32_t *Mask = regMasks.pop_back_val();
+      for (RegSet::iterator I = regsLive.begin(), E = regsLive.end(); I != E; ++I)
+        if (Register::isPhysicalRegister(*I) &&
+            MachineOperand::clobbersPhysReg(Mask, *I))
+          regsDead.push_back(*I);
+    }
   }
   set_subtract(regsLive, regsDead);   regsDead.clear();
   set_union(regsLive, regsDefined);   regsDefined.clear();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D77783.256217.patch
Type: text/x-patch
Size: 2694 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200409/773a343b/attachment-0001.bin>


More information about the llvm-commits mailing list