[llvm] r268119 - AMDGPU: Fix crash with unreachable terminators.
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 29 14:52:14 PDT 2016
Author: arsenm
Date: Fri Apr 29 16:52:13 2016
New Revision: 268119
URL: http://llvm.org/viewvc/llvm-project?rev=268119&view=rev
Log:
AMDGPU: Fix crash with unreachable terminators.
If a block has no successors because it ends in unreachable,
this was accessing an invalid iterator.
Also stop counting instructions that don't emit any
real instructions.
Added:
llvm/trunk/test/CodeGen/AMDGPU/si-lower-control-flow-unreachable-block.ll
Modified:
llvm/trunk/lib/Target/AMDGPU/SILowerControlFlow.cpp
Modified: llvm/trunk/lib/Target/AMDGPU/SILowerControlFlow.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SILowerControlFlow.cpp?rev=268119&r1=268118&r2=268119&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/SILowerControlFlow.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/SILowerControlFlow.cpp Fri Apr 29 16:52:13 2016
@@ -125,29 +125,44 @@ FunctionPass *llvm::createSILowerControl
return new SILowerControlFlow();
}
+static bool opcodeEmitsNoInsts(unsigned Opc) {
+ switch (Opc) {
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
+ case TargetOpcode::BUNDLE:
+ case TargetOpcode::CFI_INSTRUCTION:
+ case TargetOpcode::EH_LABEL:
+ case TargetOpcode::GC_LABEL:
+ case TargetOpcode::DBG_VALUE:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool SILowerControlFlow::shouldSkip(MachineBasicBlock *From,
MachineBasicBlock *To) {
unsigned NumInstr = 0;
+ MachineFunction *MF = From->getParent();
- for (MachineFunction::iterator MBBI = MachineFunction::iterator(From),
- ToI = MachineFunction::iterator(To); MBBI != ToI; ++MBBI) {
-
+ for (MachineFunction::iterator MBBI(From), ToI(To), End = MF->end();
+ MBBI != End && MBBI != ToI; ++MBBI) {
MachineBasicBlock &MBB = *MBBI;
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
NumInstr < SkipThreshold && I != E; ++I) {
+ if (opcodeEmitsNoInsts(I->getOpcode()))
+ continue;
+
+ // When a uniform loop is inside non-uniform control flow, the branch
+ // leaving the loop might be an S_CBRANCH_VCCNZ, which is never taken
+ // when EXEC = 0. We should skip the loop lest it becomes infinite.
+ if (I->getOpcode() == AMDGPU::S_CBRANCH_VCCNZ)
+ return true;
- if (I->isBundle() || !I->isBundled()) {
- // When a uniform loop is inside non-uniform control flow, the branch
- // leaving the loop might be an S_CBRANCH_VCCNZ, which is never taken
- // when EXEC = 0. We should skip the loop lest it becomes infinite.
- if (I->getOpcode() == AMDGPU::S_CBRANCH_VCCNZ)
- return true;
-
- if (++NumInstr >= SkipThreshold)
- return true;
- }
+ if (++NumInstr >= SkipThreshold)
+ return true;
}
}
Added: llvm/trunk/test/CodeGen/AMDGPU/si-lower-control-flow-unreachable-block.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/si-lower-control-flow-unreachable-block.ll?rev=268119&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AMDGPU/si-lower-control-flow-unreachable-block.ll (added)
+++ llvm/trunk/test/CodeGen/AMDGPU/si-lower-control-flow-unreachable-block.ll Fri Apr 29 16:52:13 2016
@@ -0,0 +1,56 @@
+; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
+
+; GCN-LABEL: {{^}}lower_control_flow_unreachable_terminator:
+; GCN: v_cmp_eq_i32
+; GCN: s_and_saveexec_b64
+; GCN: s_xor_b64
+; GCN: s_branch BB0_1
+
+; GCN: s_or_b64 exec, exec
+; GCN: s_endpgm
+
+; GCN: ds_write_b32
+; GCN: s_waitcnt
+define void @lower_control_flow_unreachable_terminator() #0 {
+bb:
+ %tmp15 = tail call i32 @llvm.amdgcn.workitem.id.y()
+ %tmp63 = icmp eq i32 %tmp15, 32
+ br i1 %tmp63, label %bb64, label %bb68
+
+bb64:
+ store volatile i32 0, i32 addrspace(3)* undef, align 4
+ unreachable
+
+bb68:
+ ret void
+}
+
+; GCN-LABEL: {{^}}lower_control_flow_unreachable_terminator_swap_block_order:
+; GCN: v_cmp_eq_i32
+; GCN: s_and_saveexec_b64
+; GCN: s_xor_b64
+; GCN: s_endpgm
+
+; GCN: s_or_b64 exec, exec
+; GCN: ds_write_b32
+; GCN: s_waitcnt
+define void @lower_control_flow_unreachable_terminator_swap_block_order() #0 {
+bb:
+ %tmp15 = tail call i32 @llvm.amdgcn.workitem.id.y()
+ %tmp63 = icmp eq i32 %tmp15, 32
+ br i1 %tmp63, label %bb68, label %bb64
+
+bb68:
+ ret void
+
+bb64:
+ store volatile i32 0, i32 addrspace(3)* undef, align 4
+ unreachable
+}
+
+; Function Attrs: nounwind readnone
+declare i32 @llvm.amdgcn.workitem.id.y() #1
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
+attributes #2 = { nounwind }
More information about the llvm-commits
mailing list