| ; RUN: llc < %s -march=r600 -mcpu=redwood -r600-ir-structurize=0 | FileCheck %s | |
| ; Test case for a crash in the AMDILCFGStructurizer from a CFG like this: | |
| ; | |
| ; entry | |
| ; / \ | |
| ; diamond_head branch_from | |
| ; / \ | | |
| ; diamond_false diamond_true | |
| ; \ / | |
| ; done | |
| ; | |
| ; When the diamond_true branch had more than 100 instructions. | |
| ; | |
| ; | |
| ; CHECK-LABEL: {{^}}branch_into_diamond: | |
| ; === entry block: | |
| ; CHECK: ALU_PUSH_BEFORE | |
| ; === Branch instruction (IF): | |
| ; CHECK: JUMP | |
| ; === branch_from block | |
| ; CHECK: ALU | |
| ; === Duplicated diamond_true block (There can be more than one ALU clause): | |
| ; === XXX: We should be able to optimize this so the basic block is not | |
| ; === duplicated. See comments in | |
| ; === AMDGPUCFGStructurizer::improveSimpleJumpintoIf() | |
| ; CHECK: ALU | |
| ; === Branch instruction (ELSE): | |
| ; CHECK: ELSE | |
| ; === diamond_head block: | |
| ; CHECK: ALU_PUSH_BEFORE | |
| ; === Branch instruction (IF): | |
| ; CHECK: JUMP | |
| ; === diamond_true block (There can be more than one ALU clause): | |
| ; ALU | |
| ; === Branch instruction (ELSE): | |
| ; CHECK: ELSE | |
| ; === diamond_false block plus implicit ENDIF | |
| ; CHECK: ALU_POP_AFTER | |
| ; === Branch instruction (ENDIF): | |
| ; CHECK: POP | |
| ; === done block: | |
| ; CHECK: ALU | |
| ; CHECK: MEM_RAT_CACHELESS | |
| ; CHECK: CF_END | |
| define amdgpu_kernel void @branch_into_diamond(i32 addrspace(1)* %out, i32 %a, i32 %b, i32 %c) { | |
| entry: | |
| %0 = icmp ne i32 %a, 0 | |
| br i1 %0, label %diamond_head, label %branch_from | |
| diamond_head: | |
| %1 = icmp ne i32 %a, 1 | |
| br i1 %1, label %diamond_true, label %diamond_false | |
| branch_from: | |
| %2 = add i32 %a, 1 | |
| br label %diamond_true | |
| diamond_false: | |
| %3 = add i32 %a, 2 | |
| br label %done | |
| diamond_true: | |
| %4 = phi i32 [%2, %branch_from], [%a, %diamond_head] | |
| ; This block needs to be > 100 ISA instructions to hit the bug, | |
| ; so we'll use udiv instructions. | |
| %div0 = udiv i32 %a, %b | |
| %div1 = udiv i32 %div0, %4 | |
| %div2 = udiv i32 %div1, 11 | |
| %div3 = udiv i32 %div2, %a | |
| %div4 = udiv i32 %div3, %b | |
| %div5 = udiv i32 %div4, %c | |
| %div6 = udiv i32 %div5, %div0 | |
| %div7 = udiv i32 %div6, %div1 | |
| br label %done | |
| done: | |
| %5 = phi i32 [%3, %diamond_false], [%div7, %diamond_true] | |
| store i32 %5, i32 addrspace(1)* %out | |
| ret void | |
| } |