[llvm] r269092 - Fix PR26655: Bail out if all regs of an inst BUNDLE have the correct kill flag

Mandeep Singh Grang via llvm-commits llvm-commits at lists.llvm.org
Tue May 10 10:57:27 PDT 2016


Author: mgrang
Date: Tue May 10 12:57:27 2016
New Revision: 269092

URL: http://llvm.org/viewvc/llvm-project?rev=269092&view=rev
Log:
Fix PR26655: Bail out if all regs of an inst BUNDLE have the correct kill flag

Summary:
While setting kill flags on instructions inside a BUNDLE, we bail out as soon
as we set kill flag on a register.  But we are missing a check when all the
registers already have the correct kill flag set. We need to bail out in that
case as well.

This patch refactors the old code and simply makes use of the addRegisterKilled
function in MachineInstr.cpp in order to determine whether to set/remove kill
on an instruction.

Reviewers: apazos, t.p.northover, pete, MatzeB

Subscribers: MatzeB, davide, llvm-commits

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

Added:
    llvm/trunk/test/CodeGen/Thumb2/thumb2-cpsr-liveness.ll
Modified:
    llvm/trunk/lib/CodeGen/MachineInstr.cpp
    llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp

Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=269092&r1=269091&r2=269092&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Tue May 10 12:57:27 2016
@@ -1952,6 +1952,13 @@ bool MachineInstr::addRegisterKilled(uns
     MachineOperand &MO = getOperand(i);
     if (!MO.isReg() || !MO.isUse() || MO.isUndef())
       continue;
+
+    // DEBUG_VALUE nodes do not contribute to code generation and should
+    // always be ignored. Failure to do so may result in trying to modify
+    // KILL flags on DEBUG_VALUE nodes.
+    if (MO.isDebug())
+      continue;
+
     unsigned Reg = MO.getReg();
     if (!Reg)
       continue;

Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=269092&r1=269091&r2=269092&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original)
+++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Tue May 10 12:57:27 2016
@@ -1213,7 +1213,8 @@ void ScheduleDAGInstrs::startBlockForKil
 /// operands, then we also need to propagate that to any instructions inside
 /// the bundle which had the same kill state.
 static void toggleBundleKillFlag(MachineInstr *MI, unsigned Reg,
-                                 bool NewKillState) {
+                                 bool NewKillState,
+                                 const TargetRegisterInfo *TRI) {
   if (MI->getOpcode() != TargetOpcode::BUNDLE)
     return;
 
@@ -1224,28 +1225,11 @@ static void toggleBundleKillFlag(Machine
   MachineBasicBlock::instr_iterator Begin = MI->getIterator();
   MachineBasicBlock::instr_iterator End = getBundleEnd(*MI);
   while (Begin != End) {
-    for (MachineOperand &MO : (--End)->operands()) {
-      if (!MO.isReg() || MO.isDef() || Reg != MO.getReg())
-        continue;
-
-      // DEBUG_VALUE nodes do not contribute to code generation and should
-      // always be ignored.  Failure to do so may result in trying to modify
-      // KILL flags on DEBUG_VALUE nodes, which is distressing.
-      if (MO.isDebug())
-        continue;
-
-      // If the register has the internal flag then it could be killing an
-      // internal def of the register.  In this case, just skip.  We only want
-      // to toggle the flag on operands visible outside the bundle.
-      if (MO.isInternalRead())
-        continue;
-
-      if (MO.isKill() == NewKillState)
-        continue;
-      MO.setIsKill(NewKillState);
-      if (NewKillState)
-        return;
-    }
+    if (NewKillState) {
+      if ((--End)->addRegisterKilled(Reg, TRI, /* addIfNotFound= */ false))
+         return;
+    } else
+        (--End)->clearRegisterKills(Reg, TRI);
   }
 }
 
@@ -1253,21 +1237,21 @@ bool ScheduleDAGInstrs::toggleKillFlag(M
   // Setting kill flag...
   if (!MO.isKill()) {
     MO.setIsKill(true);
-    toggleBundleKillFlag(MI, MO.getReg(), true);
+    toggleBundleKillFlag(MI, MO.getReg(), true, TRI);
     return false;
   }
 
   // If MO itself is live, clear the kill flag...
   if (LiveRegs.test(MO.getReg())) {
     MO.setIsKill(false);
-    toggleBundleKillFlag(MI, MO.getReg(), false);
+    toggleBundleKillFlag(MI, MO.getReg(), false, TRI);
     return false;
   }
 
   // If any subreg of MO is live, then create an imp-def for that
   // subreg and keep MO marked as killed.
   MO.setIsKill(false);
-  toggleBundleKillFlag(MI, MO.getReg(), false);
+  toggleBundleKillFlag(MI, MO.getReg(), false, TRI);
   bool AllDead = true;
   const unsigned SuperReg = MO.getReg();
   MachineInstrBuilder MIB(MF, MI);
@@ -1280,7 +1264,7 @@ bool ScheduleDAGInstrs::toggleKillFlag(M
 
   if(AllDead) {
     MO.setIsKill(true);
-    toggleBundleKillFlag(MI, MO.getReg(), true);
+    toggleBundleKillFlag(MI, MO.getReg(), true, TRI);
   }
   return false;
 }

Added: llvm/trunk/test/CodeGen/Thumb2/thumb2-cpsr-liveness.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-cpsr-liveness.ll?rev=269092&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-cpsr-liveness.ll (added)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-cpsr-liveness.ll Tue May 10 12:57:27 2016
@@ -0,0 +1,41 @@
+; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi -misched-postra=true
+
+define i32 @test_cpsr() {
+entry:
+  %a = alloca [10 x i32], align 4
+  %0 = bitcast [10 x i32]* %a to i8*
+  %arrayidx.gep = getelementptr [10 x i32], [10 x i32]* %a, i32 0, i32 0
+  br label %for.body
+
+for.cond.cleanup:
+  %c.1.reg2mem.0.lcssa = phi i32 [ %c.1.reg2mem.0, %for.inc ]
+  ret i32 %c.1.reg2mem.0.lcssa
+
+for.body:
+  %1 = phi i32 [ 0, %entry ], [ %.pre, %for.inc.for.body_crit_edge ]
+  %c.018.reg2mem.0 = phi i32 [ 0, %entry ], [ %c.1.reg2mem.0, %for.inc.for.body_crit_edge ]
+  %b.017.reg2mem.0 = phi double [ 0.000000e+00, %entry ], [ %b.1.reg2mem.0, %for.inc.for.body_crit_edge ]
+  %arrayidx.phi = phi i32* [ %arrayidx.gep, %entry ], [ %arrayidx.inc, %for.inc.for.body_crit_edge ]
+  %i.019 = phi i32 [ 0, %entry ], [ %inc, %for.inc.for.body_crit_edge ]
+  %cmp1 = icmp slt i32 %1, 10
+  %arrayidx.inc = getelementptr i32, i32* %arrayidx.phi, i32 1
+  br i1 %cmp1, label %for.inc, label %if.end
+
+if.end:
+  %conv = sitofp i32 %i.019 to double
+  %cmp2 = fcmp nsz ogt double %conv, %b.017.reg2mem.0
+  %selv = select i1 %cmp2, double %conv, double %b.017.reg2mem.0
+  %selv7 = select i1 %cmp2, i32 %i.019, i32 %c.018.reg2mem.0
+  br label %for.inc
+
+for.inc:
+  %b.1.reg2mem.0 = phi double [ %b.017.reg2mem.0, %for.body ], [ %selv, %if.end ]
+  %c.1.reg2mem.0 = phi i32 [ %c.018.reg2mem.0, %for.body ], [ %selv7, %if.end ]
+  %exitcond = icmp eq i32 %i.019, 9
+  br i1 %exitcond, label %for.cond.cleanup, label %for.inc.for.body_crit_edge
+
+for.inc.for.body_crit_edge:
+  %inc = add nuw nsw i32 %i.019, 1
+  %.pre = load i32, i32* %arrayidx.inc, align 4
+  br label %for.body
+}




More information about the llvm-commits mailing list