Skip to content

Commit 0d6e5bb

Browse files
committed
Fix OpLoopMerge instruction placement
1 parent 4836a41 commit 0d6e5bb

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

lib/SPIRV/libSPIRV/SPIRVModule.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1858,20 +1858,46 @@ SPIRVInstruction *SPIRVModuleImpl::addSelectionMergeInst(
18581858
SPIRVInstruction *SPIRVModuleImpl::addLoopMergeInst(
18591859
SPIRVId MergeBlock, SPIRVId ContinueTarget, SPIRVWord LoopControl,
18601860
std::vector<SPIRVWord> LoopControlParameters, SPIRVBasicBlock *BB) {
1861-
return addInstruction(
1862-
new SPIRVLoopMerge(MergeBlock, ContinueTarget, LoopControl,
1863-
LoopControlParameters, BB),
1864-
BB, const_cast<SPIRVInstruction *>(BB->getTerminateInstr()));
1861+
SPIRVInstruction *TermInst =
1862+
const_cast<SPIRVInstruction *>(BB->getTerminateInstr());
1863+
// OpLoopMerge must be the second-to-last instruction in the block,
1864+
// immediately preceding the branch instruction (OpBranch or
1865+
// OpBranchConditional)
1866+
if (TermInst && (TermInst->getOpCode() == OpBranch ||
1867+
TermInst->getOpCode() == OpBranchConditional)) {
1868+
return addInstruction(new SPIRVLoopMerge(MergeBlock, ContinueTarget,
1869+
LoopControl, LoopControlParameters,
1870+
BB),
1871+
BB, TermInst);
1872+
}
1873+
// If terminator doesn't exist yet or is not a branch, add at end
1874+
// (it will be before terminator when added)
1875+
return addInstruction(new SPIRVLoopMerge(MergeBlock, ContinueTarget,
1876+
LoopControl, LoopControlParameters,
1877+
BB),
1878+
BB);
18651879
}
18661880

18671881
SPIRVInstruction *SPIRVModuleImpl::addLoopControlINTELInst(
18681882
SPIRVWord LoopControl, std::vector<SPIRVWord> LoopControlParameters,
18691883
SPIRVBasicBlock *BB) {
18701884
addCapability(CapabilityUnstructuredLoopControlsINTEL);
18711885
addExtension(ExtensionID::SPV_INTEL_unstructured_loop_controls);
1886+
SPIRVInstruction *TermInst =
1887+
const_cast<SPIRVInstruction *>(BB->getTerminateInstr());
1888+
// OpLoopControlINTEL must be the second-to-last instruction in the block,
1889+
// immediately preceding the branch instruction (OpBranch or
1890+
// OpBranchConditional)
1891+
if (TermInst && (TermInst->getOpCode() == OpBranch ||
1892+
TermInst->getOpCode() == OpBranchConditional)) {
1893+
return addInstruction(
1894+
new SPIRVLoopControlINTEL(LoopControl, LoopControlParameters, BB), BB,
1895+
TermInst);
1896+
}
1897+
// If terminator doesn't exist yet or is not a branch, add at end
1898+
// (it will be before terminator when added)
18721899
return addInstruction(
1873-
new SPIRVLoopControlINTEL(LoopControl, LoopControlParameters, BB), BB,
1874-
const_cast<SPIRVInstruction *>(BB->getTerminateInstr()));
1900+
new SPIRVLoopControlINTEL(LoopControl, LoopControlParameters, BB), BB);
18751901
}
18761902

18771903
SPIRVInstruction *SPIRVModuleImpl::addFixedPointIntelInst(

test/OpLoopMerge_loopMerge.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
; RUN: llvm-as %s -o %t.bc
22
; RUN: llvm-spirv %t.bc -o %t.spv
33
; RUN: spirv-val %t.spv
4+
; RUN: llvm-spirv --to-text %t.spv -o - | FileCheck %s
5+
6+
; CHECK: LoopMerge
7+
; CHECK-NEXT: BranchConditional
48

59
target triple = "spir64"
610

0 commit comments

Comments
 (0)