[llvm] r293925 - [Hexagon] Fix insertBranch for loops with multiple ENDLOOP instructions

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 2 11:36:38 PST 2017


Author: kparzysz
Date: Thu Feb  2 13:36:37 2017
New Revision: 293925

URL: http://llvm.org/viewvc/llvm-project?rev=293925&view=rev
Log:
[Hexagon] Fix insertBranch for loops with multiple ENDLOOP instructions

Added:
    llvm/trunk/test/CodeGen/Hexagon/find-loop-instr.ll
Modified:
    llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp

Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp?rev=293925&r1=293924&r2=293925&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp Thu Feb  2 13:36:37 2017
@@ -152,10 +152,11 @@ static unsigned nonDbgMICount(MachineBas
 /// On Hexagon, we have two instructions used to set-up the hardware loop
 /// (LOOP0, LOOP1) with corresponding endloop (ENDLOOP0, ENDLOOP1) instructions
 /// to indicate the end of a loop.
-static MachineInstr *findLoopInstr(MachineBasicBlock *BB, int EndLoopOp,
+static MachineInstr *findLoopInstr(MachineBasicBlock *BB, unsigned EndLoopOp,
+      MachineBasicBlock *TargetBB,
       SmallPtrSet<MachineBasicBlock *, 8> &Visited) {
-  int LOOPi;
-  int LOOPr;
+  unsigned LOOPi;
+  unsigned LOOPr;
   if (EndLoopOp == Hexagon::ENDLOOP0) {
     LOOPi = Hexagon::J2_loop0i;
     LOOPr = Hexagon::J2_loop0r;
@@ -165,26 +166,24 @@ static MachineInstr *findLoopInstr(Machi
   }
 
   // The loop set-up instruction will be in a predecessor block
-  for (MachineBasicBlock::pred_iterator PB = BB->pred_begin(),
-         PE = BB->pred_end(); PB != PE; ++PB) {
+  for (MachineBasicBlock *PB : BB->predecessors()) {
     // If this has been visited, already skip it.
-    if (!Visited.insert(*PB).second)
+    if (!Visited.insert(PB).second)
       continue;
-    if (*PB == BB)
+    if (PB == BB)
       continue;
-    for (MachineBasicBlock::reverse_instr_iterator I = (*PB)->instr_rbegin(),
-           E = (*PB)->instr_rend(); I != E; ++I) {
-      int Opc = I->getOpcode();
+    for (auto I = PB->instr_rbegin(), E = PB->instr_rend(); I != E; ++I) {
+      unsigned Opc = I->getOpcode();
       if (Opc == LOOPi || Opc == LOOPr)
         return &*I;
-      // We've reached a different loop, which means the loop0 has been removed.
-      if (Opc == EndLoopOp)
+      // We've reached a different loop, which means the loop01 has been
+      // removed.
+      if (Opc == EndLoopOp && I->getOperand(0).getMBB() != TargetBB)
         return nullptr;
     }
     // Check the predecessors for the LOOP instruction.
-    MachineInstr *loop = findLoopInstr(*PB, EndLoopOp, Visited);
-    if (loop)
-      return loop;
+    if (MachineInstr *Loop = findLoopInstr(PB, EndLoopOp, TargetBB, Visited))
+      return Loop;
   }
   return nullptr;
 }
@@ -597,7 +596,8 @@ unsigned HexagonInstrInfo::insertBranch(
       // Since we're adding an ENDLOOP, there better be a LOOP instruction.
       // Check for it, and change the BB target if needed.
       SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
-      MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, VisitedBBs);
+      MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
+                                         VisitedBBs);
       assert(Loop != 0 && "Inserting an ENDLOOP without a LOOP");
       Loop->getOperand(0).setMBB(TBB);
       // Add the ENDLOOP after the finding the LOOP0.
@@ -637,7 +637,12 @@ unsigned HexagonInstrInfo::insertBranch(
     // Since we're adding an ENDLOOP, there better be a LOOP instruction.
     // Check for it, and change the BB target if needed.
     SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
-    MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, VisitedBBs);
+    MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
+                                       VisitedBBs);
+if (Loop == 0) {
+  MachineFunction &MF = *MBB.getParent();
+  MF.print(dbgs(), 0);
+}
     assert(Loop != 0 && "Inserting an ENDLOOP without a LOOP");
     Loop->getOperand(0).setMBB(TBB);
     // Add the ENDLOOP after the finding the LOOP0.
@@ -687,7 +692,8 @@ unsigned HexagonInstrInfo::reduceLoopCou
   MachineFunction *MF = MBB.getParent();
   DebugLoc DL = Cmp.getDebugLoc();
   SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
-  MachineInstr *Loop = findLoopInstr(&MBB, Cmp.getOpcode(), VisitedBBs);
+  MachineInstr *Loop = findLoopInstr(&MBB, Cmp.getOpcode(),
+                                     Cmp.getOperand(0).getMBB(), VisitedBBs);
   if (!Loop)
     return 0;
   // If the loop trip count is a compile-time value, then just change the

Added: llvm/trunk/test/CodeGen/Hexagon/find-loop-instr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/find-loop-instr.ll?rev=293925&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/find-loop-instr.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/find-loop-instr.ll Thu Feb  2 13:36:37 2017
@@ -0,0 +1,79 @@
+; RUN: llc -march=hexagon < %s
+; REQUIRES: asserts
+
+; This code causes multiple endloop instructions to be generated for the
+; same loop. The findLoopInstr would encounter for one endloop would encounter
+; the other endloop, and return null in response. This resulted in a crash.
+;
+; Check that with the fix we are able to compile this code successfully.
+
+target triple = "hexagon"
+
+; Function Attrs: norecurse
+define void @fred() local_unnamed_addr #0 align 2 {
+b0:
+  br label %b7
+
+b1:                                               ; preds = %b9
+  br i1 undef, label %b4, label %b2
+
+b2:                                               ; preds = %b1
+  %v3 = sub i32 undef, undef
+  br label %b4
+
+b4:                                               ; preds = %b2, %b1
+  %v5 = phi i32 [ undef, %b1 ], [ %v3, %b2 ]
+  br i1 undef, label %b14, label %b6
+
+b6:                                               ; preds = %b4
+  br label %b10
+
+b7:                                               ; preds = %b0
+  br i1 undef, label %b9, label %b8
+
+b8:                                               ; preds = %b7
+  unreachable
+
+b9:                                               ; preds = %b7
+  br label %b1
+
+b10:                                              ; preds = %b21, %b6
+  %v11 = phi i32 [ %v22, %b21 ], [ %v5, %b6 ]
+  br i1 undef, label %b21, label %b12
+
+b12:                                              ; preds = %b10
+  br label %b15
+
+b13:                                              ; preds = %b21
+  br label %b14
+
+b14:                                              ; preds = %b13, %b4
+  ret void
+
+b15:                                              ; preds = %b12
+  br i1 undef, label %b16, label %b17
+
+b16:                                              ; preds = %b15
+  store i32 0, i32* undef, align 4
+  br label %b21
+
+b17:                                              ; preds = %b15
+  br label %b18
+
+b18:                                              ; preds = %b17
+  br i1 undef, label %b19, label %b20
+
+b19:                                              ; preds = %b18
+  br label %b21
+
+b20:                                              ; preds = %b18
+  store i32 0, i32* undef, align 4
+  br label %b21
+
+b21:                                              ; preds = %b20, %b19, %b16, %b10
+  %v22 = add i32 %v11, -8
+  %v23 = icmp eq i32 %v22, 0
+  br i1 %v23, label %b13, label %b10
+}
+
+attributes #0 = { norecurse "target-cpu"="hexagonv60" "target-features"="-hvx,-hvx-double,-long-calls" }




More information about the llvm-commits mailing list