1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -march=r600 -mcpu=redwood -r600-ir-structurize=0 | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; Test case for a crash in the AMDILCFGStructurizer from a CFG like this: 3*9880d681SAndroid Build Coastguard Worker; 4*9880d681SAndroid Build Coastguard Worker; entry 5*9880d681SAndroid Build Coastguard Worker; / \ 6*9880d681SAndroid Build Coastguard Worker; diamond_head branch_from 7*9880d681SAndroid Build Coastguard Worker; / \ | 8*9880d681SAndroid Build Coastguard Worker; diamond_false diamond_true 9*9880d681SAndroid Build Coastguard Worker; \ / 10*9880d681SAndroid Build Coastguard Worker; done 11*9880d681SAndroid Build Coastguard Worker; 12*9880d681SAndroid Build Coastguard Worker; When the diamond_true branch had more than 100 instructions. 13*9880d681SAndroid Build Coastguard Worker; 14*9880d681SAndroid Build Coastguard Worker; 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: {{^}}branch_into_diamond: 17*9880d681SAndroid Build Coastguard Worker; === entry block: 18*9880d681SAndroid Build Coastguard Worker; CHECK: ALU_PUSH_BEFORE 19*9880d681SAndroid Build Coastguard Worker; === Branch instruction (IF): 20*9880d681SAndroid Build Coastguard Worker; CHECK: JUMP 21*9880d681SAndroid Build Coastguard Worker ; === branch_from block 22*9880d681SAndroid Build Coastguard Worker ; CHECK: ALU 23*9880d681SAndroid Build Coastguard Worker ; === Duplicated diamond_true block (There can be more than one ALU clause): 24*9880d681SAndroid Build Coastguard Worker ; === XXX: We should be able to optimize this so the basic block is not 25*9880d681SAndroid Build Coastguard Worker ; === duplicated. See comments in 26*9880d681SAndroid Build Coastguard Worker ; === AMDGPUCFGStructurizer::improveSimpleJumpintoIf() 27*9880d681SAndroid Build Coastguard Worker ; CHECK: ALU 28*9880d681SAndroid Build Coastguard Worker; === Branch instruction (ELSE): 29*9880d681SAndroid Build Coastguard Worker; CHECK: ELSE 30*9880d681SAndroid Build Coastguard Worker ; === diamond_head block: 31*9880d681SAndroid Build Coastguard Worker ; CHECK: ALU_PUSH_BEFORE 32*9880d681SAndroid Build Coastguard Worker ; === Branch instruction (IF): 33*9880d681SAndroid Build Coastguard Worker ; CHECK: JUMP 34*9880d681SAndroid Build Coastguard Worker ; === diamond_true block (There can be more than one ALU clause): 35*9880d681SAndroid Build Coastguard Worker ; ALU 36*9880d681SAndroid Build Coastguard Worker ; === Branch instruction (ELSE): 37*9880d681SAndroid Build Coastguard Worker ; CHECK: ELSE 38*9880d681SAndroid Build Coastguard Worker ; === diamond_false block plus implicit ENDIF 39*9880d681SAndroid Build Coastguard Worker ; CHECK: ALU_POP_AFTER 40*9880d681SAndroid Build Coastguard Worker; === Branch instruction (ENDIF): 41*9880d681SAndroid Build Coastguard Worker; CHECK: POP 42*9880d681SAndroid Build Coastguard Worker; === done block: 43*9880d681SAndroid Build Coastguard Worker; CHECK: ALU 44*9880d681SAndroid Build Coastguard Worker; CHECK: MEM_RAT_CACHELESS 45*9880d681SAndroid Build Coastguard Worker; CHECK: CF_END 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Workerdefine void @branch_into_diamond(i32 addrspace(1)* %out, i32 %a, i32 %b, i32 %c) { 49*9880d681SAndroid Build Coastguard Workerentry: 50*9880d681SAndroid Build Coastguard Worker%0 = icmp ne i32 %a, 0 51*9880d681SAndroid Build Coastguard Worker br i1 %0, label %diamond_head, label %branch_from 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Workerdiamond_head: 54*9880d681SAndroid Build Coastguard Worker %1 = icmp ne i32 %a, 1 55*9880d681SAndroid Build Coastguard Worker br i1 %1, label %diamond_true, label %diamond_false 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Workerbranch_from: 58*9880d681SAndroid Build Coastguard Worker %2 = add i32 %a, 1 59*9880d681SAndroid Build Coastguard Worker br label %diamond_true 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Workerdiamond_false: 62*9880d681SAndroid Build Coastguard Worker %3 = add i32 %a, 2 63*9880d681SAndroid Build Coastguard Worker br label %done 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Workerdiamond_true: 66*9880d681SAndroid Build Coastguard Worker %4 = phi i32 [%2, %branch_from], [%a, %diamond_head] 67*9880d681SAndroid Build Coastguard Worker ; This block needs to be > 100 ISA instructions to hit the bug, 68*9880d681SAndroid Build Coastguard Worker ; so we'll use udiv instructions. 69*9880d681SAndroid Build Coastguard Worker %div0 = udiv i32 %a, %b 70*9880d681SAndroid Build Coastguard Worker %div1 = udiv i32 %div0, %4 71*9880d681SAndroid Build Coastguard Worker %div2 = udiv i32 %div1, 11 72*9880d681SAndroid Build Coastguard Worker %div3 = udiv i32 %div2, %a 73*9880d681SAndroid Build Coastguard Worker %div4 = udiv i32 %div3, %b 74*9880d681SAndroid Build Coastguard Worker %div5 = udiv i32 %div4, %c 75*9880d681SAndroid Build Coastguard Worker %div6 = udiv i32 %div5, %div0 76*9880d681SAndroid Build Coastguard Worker %div7 = udiv i32 %div6, %div1 77*9880d681SAndroid Build Coastguard Worker br label %done 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Workerdone: 80*9880d681SAndroid Build Coastguard Worker %5 = phi i32 [%3, %diamond_false], [%div7, %diamond_true] 81*9880d681SAndroid Build Coastguard Worker store i32 %5, i32 addrspace(1)* %out 82*9880d681SAndroid Build Coastguard Worker ret void 83*9880d681SAndroid Build Coastguard Worker} 84