1*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=amdgcn -verify-machineinstrs< %s | FileCheck -check-prefix=SI %s 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; 4*9880d681SAndroid Build Coastguard Worker; Most SALU instructions ignore control flow, so we need to make sure 5*9880d681SAndroid Build Coastguard Worker; they don't overwrite values from other blocks. 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; If the branch decision is made based on a value in an SGPR then all 8*9880d681SAndroid Build Coastguard Worker; threads will execute the same code paths, so we don't need to worry 9*9880d681SAndroid Build Coastguard Worker; about instructions in different blocks overwriting each other. 10*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}sgpr_if_else_salu_br: 11*9880d681SAndroid Build Coastguard Worker; SI: s_add 12*9880d681SAndroid Build Coastguard Worker; SI: s_add 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Workerdefine void @sgpr_if_else_salu_br(i32 addrspace(1)* %out, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) { 15*9880d681SAndroid Build Coastguard Workerentry: 16*9880d681SAndroid Build Coastguard Worker %0 = icmp eq i32 %a, 0 17*9880d681SAndroid Build Coastguard Worker br i1 %0, label %if, label %else 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Workerif: 20*9880d681SAndroid Build Coastguard Worker %1 = add i32 %b, %c 21*9880d681SAndroid Build Coastguard Worker br label %endif 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Workerelse: 24*9880d681SAndroid Build Coastguard Worker %2 = add i32 %d, %e 25*9880d681SAndroid Build Coastguard Worker br label %endif 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Workerendif: 28*9880d681SAndroid Build Coastguard Worker %3 = phi i32 [%1, %if], [%2, %else] 29*9880d681SAndroid Build Coastguard Worker %4 = add i32 %3, %a 30*9880d681SAndroid Build Coastguard Worker store i32 %4, i32 addrspace(1)* %out 31*9880d681SAndroid Build Coastguard Worker ret void 32*9880d681SAndroid Build Coastguard Worker} 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker; The two S_ADD instructions should write to different registers, since 35*9880d681SAndroid Build Coastguard Worker; different threads will take different control flow paths. 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}sgpr_if_else_valu_br: 38*9880d681SAndroid Build Coastguard Worker; SI: s_add_i32 [[SGPR:s[0-9]+]] 39*9880d681SAndroid Build Coastguard Worker; SI-NOT: s_add_i32 [[SGPR]] 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Workerdefine void @sgpr_if_else_valu_br(i32 addrspace(1)* %out, float %a, i32 %b, i32 %c, i32 %d, i32 %e) { 42*9880d681SAndroid Build Coastguard Workerentry: 43*9880d681SAndroid Build Coastguard Worker %tid = call i32 @llvm.amdgcn.workitem.id.x() #0 44*9880d681SAndroid Build Coastguard Worker %tid_f = uitofp i32 %tid to float 45*9880d681SAndroid Build Coastguard Worker %tmp1 = fcmp ueq float %tid_f, 0.0 46*9880d681SAndroid Build Coastguard Worker br i1 %tmp1, label %if, label %else 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Workerif: 49*9880d681SAndroid Build Coastguard Worker %tmp2 = add i32 %b, %c 50*9880d681SAndroid Build Coastguard Worker br label %endif 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Workerelse: 53*9880d681SAndroid Build Coastguard Worker %tmp3 = add i32 %d, %e 54*9880d681SAndroid Build Coastguard Worker br label %endif 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Workerendif: 57*9880d681SAndroid Build Coastguard Worker %tmp4 = phi i32 [%tmp2, %if], [%tmp3, %else] 58*9880d681SAndroid Build Coastguard Worker store i32 %tmp4, i32 addrspace(1)* %out 59*9880d681SAndroid Build Coastguard Worker ret void 60*9880d681SAndroid Build Coastguard Worker} 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker; FIXME: Should write to different SGPR pairs instead of copying to 63*9880d681SAndroid Build Coastguard Worker; VALU for i1 phi. 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker; SI-LABEL: {{^}}sgpr_if_else_valu_cmp_phi_br: 66*9880d681SAndroid Build Coastguard Worker; SI: buffer_load_dword [[AVAL:v[0-9]+]] 67*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_gt_i32_e32 [[CMP_IF:vcc]], 0, [[AVAL]] 68*9880d681SAndroid Build Coastguard Worker; SI: v_cndmask_b32_e64 [[V_CMP:v[0-9]+]], 0, -1, [[CMP_IF]] 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker; SI: BB2_2: 71*9880d681SAndroid Build Coastguard Worker; SI: buffer_load_dword [[AVAL:v[0-9]+]] 72*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_eq_i32_e32 [[CMP_ELSE:vcc]], 0, [[AVAL]] 73*9880d681SAndroid Build Coastguard Worker; SI: v_cndmask_b32_e64 [[V_CMP]], 0, -1, [[CMP_ELSE]] 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker; SI: v_cmp_ne_i32_e32 [[CMP_CMP:vcc]], 0, [[V_CMP]] 76*9880d681SAndroid Build Coastguard Worker; SI: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, -1, [[CMP_CMP]] 77*9880d681SAndroid Build Coastguard Worker; SI: buffer_store_dword [[RESULT]] 78*9880d681SAndroid Build Coastguard Workerdefine void @sgpr_if_else_valu_cmp_phi_br(i32 addrspace(1)* %out, i32 addrspace(1)* %a, i32 addrspace(1)* %b) { 79*9880d681SAndroid Build Coastguard Workerentry: 80*9880d681SAndroid Build Coastguard Worker %tid = call i32 @llvm.amdgcn.workitem.id.x() #0 81*9880d681SAndroid Build Coastguard Worker %tmp1 = icmp eq i32 %tid, 0 82*9880d681SAndroid Build Coastguard Worker br i1 %tmp1, label %if, label %else 83*9880d681SAndroid Build Coastguard Worker 84*9880d681SAndroid Build Coastguard Workerif: 85*9880d681SAndroid Build Coastguard Worker %gep.if = getelementptr i32, i32 addrspace(1)* %a, i32 %tid 86*9880d681SAndroid Build Coastguard Worker %a.val = load i32, i32 addrspace(1)* %gep.if 87*9880d681SAndroid Build Coastguard Worker %cmp.if = icmp eq i32 %a.val, 0 88*9880d681SAndroid Build Coastguard Worker br label %endif 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Workerelse: 91*9880d681SAndroid Build Coastguard Worker %gep.else = getelementptr i32, i32 addrspace(1)* %b, i32 %tid 92*9880d681SAndroid Build Coastguard Worker %b.val = load i32, i32 addrspace(1)* %gep.else 93*9880d681SAndroid Build Coastguard Worker %cmp.else = icmp slt i32 %b.val, 0 94*9880d681SAndroid Build Coastguard Worker br label %endif 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Workerendif: 97*9880d681SAndroid Build Coastguard Worker %tmp4 = phi i1 [%cmp.if, %if], [%cmp.else, %else] 98*9880d681SAndroid Build Coastguard Worker %ext = sext i1 %tmp4 to i32 99*9880d681SAndroid Build Coastguard Worker store i32 %ext, i32 addrspace(1)* %out 100*9880d681SAndroid Build Coastguard Worker ret void 101*9880d681SAndroid Build Coastguard Worker} 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Workerdeclare i32 @llvm.amdgcn.workitem.id.x() #0 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Workerattributes #0 = { readnone } 106