[RegisterScavenger] Fix handling of predicated instructions
authorTobias Edler von Koch <tobias@codeaurora.org>
Tue, 9 Jun 2015 22:10:58 +0000 (22:10 +0000)
committerTobias Edler von Koch <tobias@codeaurora.org>
Tue, 9 Jun 2015 22:10:58 +0000 (22:10 +0000)
Summary:
The RegisterScavenger explicitly ignores <kill> flags on operands of
predicated instructions and therefore assumes that such registers remain
live. When it then scavenges such a register, it inserts a spill of this
(killed) register. This is invalid code and gets flagged up by the
verifier.

Nowadays kill flags are set correctly on predicated instructions. This
patch makes the Scavenger respect them.

The bug has so far only been triggered by an internal pass, so I don't
have a test case unfortunately.

Fixes PR23119.

Reviewers: hfinkel, tobiasvk_caf

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D9039

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239439 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/RegisterScavenging.cpp

index a34bd6341d228b20037594bd89320a898c413ea2..4176686d1f7f68464b64a36788d7e6e437bb9013 100644 (file)
@@ -103,10 +103,6 @@ void RegScavenger::determineKillsAndDefs() {
 
   // Find out which registers are early clobbered, killed, defined, and marked
   // def-dead in this instruction.
-  // FIXME: The scavenger is not predication aware. If the instruction is
-  // predicated, conservatively assume "kill" markers do not actually kill the
-  // register. Similarly ignores "dead" markers.
-  bool isPred = TII->isPredicated(MI);
   KillRegUnits.reset();
   DefRegUnits.reset();
   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
@@ -124,7 +120,7 @@ void RegScavenger::determineKillsAndDefs() {
       }
       
       // Apply the mask.
-      (isPred ? DefRegUnits : KillRegUnits) |= TmpRegUnits;
+      KillRegUnits |= TmpRegUnits;
     }
     if (!MO.isReg())
       continue;
@@ -136,11 +132,11 @@ void RegScavenger::determineKillsAndDefs() {
       // Ignore undef uses.
       if (MO.isUndef())
         continue;
-      if (!isPred && MO.isKill())
+      if (MO.isKill())
         addRegUnits(KillRegUnits, Reg);
     } else {
       assert(MO.isDef());
-      if (!isPred && MO.isDead())
+      if (MO.isDead())
         addRegUnits(KillRegUnits, Reg);
       else
         addRegUnits(DefRegUnits, Reg);