From: Krzysztof Parzyszek Date: Thu, 2 Feb 2017 19:36:37 +0000 (+0000) Subject: [Hexagon] Fix insertBranch for loops with multiple ENDLOOP instructions X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4ea8989ed668e0251062cb82a1305460158c998c;p=llvm [Hexagon] Fix insertBranch for loops with multiple ENDLOOP instructions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293925 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp index 28b6f7a8936..813f4f81b41 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -152,10 +152,11 @@ static unsigned nonDbgMICount(MachineBasicBlock::const_instr_iterator MIB, /// 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 &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(MachineBasicBlock *BB, int EndLoopOp, } // 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(MachineBasicBlock &MBB, // Since we're adding an ENDLOOP, there better be a LOOP instruction. // Check for it, and change the BB target if needed. SmallPtrSet 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(MachineBasicBlock &MBB, // Since we're adding an ENDLOOP, there better be a LOOP instruction. // Check for it, and change the BB target if needed. SmallPtrSet 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::reduceLoopCount(MachineBasicBlock &MBB, MachineFunction *MF = MBB.getParent(); DebugLoc DL = Cmp.getDebugLoc(); SmallPtrSet 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 diff --git a/test/CodeGen/Hexagon/find-loop-instr.ll b/test/CodeGen/Hexagon/find-loop-instr.ll new file mode 100644 index 00000000000..1234baf17f5 --- /dev/null +++ b/test/CodeGen/Hexagon/find-loop-instr.ll @@ -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" }