Skip to content

Commit

Permalink
[Hexagon] Fix insertBranch for loops with multiple ENDLOOP instructions
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293925 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Krzysztof Parzyszek committed Feb 2, 2017
1 parent e56a9ab commit 4ea8989
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 18 deletions.
42 changes: 24 additions & 18 deletions lib/Target/Hexagon/HexagonInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<MachineBasicBlock *, 8> &Visited) {
int LOOPi;
int LOOPr;
unsigned LOOPi;
unsigned LOOPr;
if (EndLoopOp == Hexagon::ENDLOOP0) {
LOOPi = Hexagon::J2_loop0i;
LOOPr = Hexagon::J2_loop0r;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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<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.
Expand Down Expand Up @@ -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<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.
Expand Down Expand Up @@ -687,7 +692,8 @@ unsigned HexagonInstrInfo::reduceLoopCount(MachineBasicBlock &MBB,
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
Expand Down
79 changes: 79 additions & 0 deletions test/CodeGen/Hexagon/find-loop-instr.ll
Original file line number Diff line number Diff line change
@@ -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" }

0 comments on commit 4ea8989

Please sign in to comment.