brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.2 KiB · 121dd30 Raw
632 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 32; RUN: llc -global-isel -new-reg-bank-select -mtriple=amdgcn-amd-amdpal -mcpu=gfx1010 < %s | FileCheck -check-prefix=GFX10 %s3 4; This file contains various tests that have divergent i1s used outside of5; the loop. These are lane masks is sgpr and need to have correct value in6; corresponding bit at the iteration lane exits the loop.7; Achieved by merging lane mask with same lane mask from previous iteration8; and using that merged lane mask outside of the loop.9 10; Phi used outside of the loop directly (loopfinder will figure out that it11; needs to merge lane mask across all iterations)12define void @divergent_i1_phi_used_outside_loop(float %val, float %pre.cond.val, ptr %addr) {13; GFX10-LABEL: divergent_i1_phi_used_outside_loop:14; GFX10:       ; %bb.0: ; %entry15; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)16; GFX10-NEXT:    v_cmp_lt_f32_e64 s5, 1.0, v117; GFX10-NEXT:    s_mov_b32 s4, 018; GFX10-NEXT:    s_mov_b32 s6, 019; GFX10-NEXT:    ; implicit-def: $sgpr720; GFX10-NEXT:  .LBB0_1: ; %loop21; GFX10-NEXT:    ; =>This Inner Loop Header: Depth=122; GFX10-NEXT:    v_cvt_f32_u32_e32 v1, s623; GFX10-NEXT:    s_mov_b32 s8, exec_lo24; GFX10-NEXT:    s_add_i32 s6, s6, 125; GFX10-NEXT:    s_xor_b32 s8, s5, s826; GFX10-NEXT:    v_cmp_gt_f32_e32 vcc_lo, v1, v027; GFX10-NEXT:    s_or_b32 s4, vcc_lo, s428; GFX10-NEXT:    s_andn2_b32 s7, s7, exec_lo29; GFX10-NEXT:    s_and_b32 s9, exec_lo, s530; GFX10-NEXT:    s_mov_b32 s5, s831; GFX10-NEXT:    s_or_b32 s7, s7, s932; GFX10-NEXT:    s_andn2_b32 exec_lo, exec_lo, s433; GFX10-NEXT:    s_cbranch_execnz .LBB0_134; GFX10-NEXT:  ; %bb.2: ; %exit35; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s436; GFX10-NEXT:    v_cndmask_b32_e64 v0, 0, 1.0, s737; GFX10-NEXT:    flat_store_dword v[2:3], v038; GFX10-NEXT:    s_waitcnt lgkmcnt(0)39; GFX10-NEXT:    s_setpc_b64 s[30:31]40entry:41  %pre.cond = fcmp ogt float %pre.cond.val, 1.042  br label %loop43 44loop:45  %counter = phi i32 [ 0, %entry ], [ %counter.plus.1, %loop ]46  %bool.counter = phi i1 [ %pre.cond, %entry ], [ %neg.bool.counter, %loop ]47  %neg.bool.counter = xor i1 %bool.counter, true48  %f.counter = uitofp i32 %counter to float49  %cond = fcmp ogt float %f.counter, %val50  %counter.plus.1 = add i32 %counter, 151  br i1 %cond, label %exit, label %loop52 53exit:54  %select = select i1 %bool.counter, float 1.000000e+00, float 0.000000e+0055  store float %select, ptr %addr56  ret void57}58 59define void @divergent_i1_phi_used_outside_loop_larger_loop_body(float %val, ptr addrspace(1) %a, ptr %addr) {60; GFX10-LABEL: divergent_i1_phi_used_outside_loop_larger_loop_body:61; GFX10:       ; %bb.0: ; %entry62; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)63; GFX10-NEXT:    s_andn2_b32 s5, s4, exec_lo64; GFX10-NEXT:    s_and_b32 s6, exec_lo, exec_lo65; GFX10-NEXT:    s_mov_b32 s4, -166; GFX10-NEXT:    s_or_b32 s7, s5, s667; GFX10-NEXT:    ; implicit-def: $sgpr568; GFX10-NEXT:    s_branch .LBB1_269; GFX10-NEXT:  .LBB1_1: ; %loop.cond70; GFX10-NEXT:    ; in Loop: Header=BB1_2 Depth=171; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s772; GFX10-NEXT:    s_add_i32 s4, s4, 173; GFX10-NEXT:    v_add_co_u32 v1, vcc_lo, v1, 474; GFX10-NEXT:    s_cmp_ge_i32 s4, 1075; GFX10-NEXT:    v_add_co_ci_u32_e32 v2, vcc_lo, 0, v2, vcc_lo76; GFX10-NEXT:    s_cselect_b32 s8, 1, 077; GFX10-NEXT:    s_andn2_b32 s7, s6, exec_lo78; GFX10-NEXT:    s_and_b32 s9, exec_lo, s579; GFX10-NEXT:    s_or_b32 s7, s7, s980; GFX10-NEXT:    s_cmp_lg_u32 s8, 081; GFX10-NEXT:    s_cbranch_scc0 .LBB1_482; GFX10-NEXT:  .LBB1_2: ; %loop.start83; GFX10-NEXT:    ; =>This Inner Loop Header: Depth=184; GFX10-NEXT:    s_mov_b32 s6, s785; GFX10-NEXT:    s_andn2_b32 s5, s5, exec_lo86; GFX10-NEXT:    s_and_b32 s7, exec_lo, s787; GFX10-NEXT:    s_or_b32 s5, s5, s788; GFX10-NEXT:    s_and_saveexec_b32 s7, s689; GFX10-NEXT:    s_cbranch_execz .LBB1_190; GFX10-NEXT:  ; %bb.3: ; %is.eq.zero91; GFX10-NEXT:    ; in Loop: Header=BB1_2 Depth=192; GFX10-NEXT:    global_load_dword v0, v[1:2], off93; GFX10-NEXT:    s_andn2_b32 s5, s5, exec_lo94; GFX10-NEXT:    s_waitcnt vmcnt(0)95; GFX10-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v096; GFX10-NEXT:    s_and_b32 s8, exec_lo, vcc_lo97; GFX10-NEXT:    s_or_b32 s5, s5, s898; GFX10-NEXT:    s_branch .LBB1_199; GFX10-NEXT:  .LBB1_4: ; %exit100; GFX10-NEXT:    v_cndmask_b32_e64 v0, 0, 1.0, s6101; GFX10-NEXT:    flat_store_dword v[3:4], v0102; GFX10-NEXT:    s_waitcnt lgkmcnt(0)103; GFX10-NEXT:    s_setpc_b64 s[30:31]104entry:105  br label %loop.start106 107loop.start:108  %i = phi i32 [ 0, %entry ], [ %i.plus.1, %loop.cond ]109  %all.eq.zero = phi i1 [ true, %entry ], [ %eq.zero, %loop.cond ]110  br i1 %all.eq.zero, label %is.eq.zero, label %loop.cond111 112is.eq.zero:113  %a.plus.i = getelementptr i32, ptr addrspace(1) %a, i32 %i114  %elt.i = load i32, ptr addrspace(1) %a.plus.i115  %elt.i.eq.zero = icmp eq i32 %elt.i, 0116  br label %loop.cond117 118loop.cond:119  %eq.zero = phi i1 [ %all.eq.zero, %loop.start ], [ %elt.i.eq.zero, %is.eq.zero ]120  %cond = icmp slt i32 %i, 10121  %i.plus.1 = add i32 %i, 1122  br i1 %cond, label %exit, label %loop.start123 124exit:125  %select = select i1 %all.eq.zero, float 1.000000e+00, float 0.000000e+00126  store float %select, ptr %addr127  ret void128}129 130; Non-phi used outside of the loop131 132define void @divergent_i1_xor_used_outside_loop(float %val, float %pre.cond.val, ptr %addr) {133; GFX10-LABEL: divergent_i1_xor_used_outside_loop:134; GFX10:       ; %bb.0: ; %entry135; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)136; GFX10-NEXT:    v_cmp_lt_f32_e64 s5, 1.0, v1137; GFX10-NEXT:    s_mov_b32 s4, 0138; GFX10-NEXT:    s_mov_b32 s6, 0139; GFX10-NEXT:    ; implicit-def: $sgpr7140; GFX10-NEXT:  .LBB2_1: ; %loop141; GFX10-NEXT:    ; =>This Inner Loop Header: Depth=1142; GFX10-NEXT:    v_cvt_f32_u32_e32 v1, s6143; GFX10-NEXT:    s_mov_b32 s8, exec_lo144; GFX10-NEXT:    s_add_i32 s6, s6, 1145; GFX10-NEXT:    s_xor_b32 s5, s5, s8146; GFX10-NEXT:    v_cmp_gt_f32_e32 vcc_lo, v1, v0147; GFX10-NEXT:    s_or_b32 s4, vcc_lo, s4148; GFX10-NEXT:    s_andn2_b32 s7, s7, exec_lo149; GFX10-NEXT:    s_and_b32 s8, exec_lo, s5150; GFX10-NEXT:    s_or_b32 s7, s7, s8151; GFX10-NEXT:    s_andn2_b32 exec_lo, exec_lo, s4152; GFX10-NEXT:    s_cbranch_execnz .LBB2_1153; GFX10-NEXT:  ; %bb.2: ; %exit154; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s4155; GFX10-NEXT:    v_cndmask_b32_e64 v0, 0, 1.0, s7156; GFX10-NEXT:    flat_store_dword v[2:3], v0157; GFX10-NEXT:    s_waitcnt lgkmcnt(0)158; GFX10-NEXT:    s_setpc_b64 s[30:31]159entry:160  %pre.cond = fcmp ogt float %pre.cond.val, 1.0161  br label %loop162 163loop:164  %counter = phi i32 [ 0, %entry ], [ %counter.plus.1, %loop ]165  %bool.counter = phi i1 [ %pre.cond, %entry ], [ %neg.bool.counter, %loop ]166  %neg.bool.counter = xor i1 %bool.counter, true167  %f.counter = uitofp i32 %counter to float168  %cond = fcmp ogt float %f.counter, %val169  %counter.plus.1 = add i32 %counter, 1170  br i1 %cond, label %exit, label %loop171 172exit:173  %select = select i1 %neg.bool.counter, float 1.000000e+00, float 0.000000e+00174  store float %select, ptr %addr175  ret void176}177 178define void @divergent_i1_xor_used_outside_loop_twice(float %val, float %pre.cond.val, ptr %addr, ptr %addr2) {179; GFX10-LABEL: divergent_i1_xor_used_outside_loop_twice:180; GFX10:       ; %bb.0: ; %entry181; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)182; GFX10-NEXT:    v_cmp_lt_f32_e64 s5, 1.0, v1183; GFX10-NEXT:    s_mov_b32 s4, 0184; GFX10-NEXT:    s_mov_b32 s7, 0185; GFX10-NEXT:    ; implicit-def: $sgpr6186; GFX10-NEXT:  .LBB3_1: ; %loop187; GFX10-NEXT:    ; =>This Inner Loop Header: Depth=1188; GFX10-NEXT:    v_cvt_f32_u32_e32 v1, s7189; GFX10-NEXT:    s_mov_b32 s8, exec_lo190; GFX10-NEXT:    s_add_i32 s7, s7, 1191; GFX10-NEXT:    s_xor_b32 s5, s5, s8192; GFX10-NEXT:    v_cmp_gt_f32_e32 vcc_lo, v1, v0193; GFX10-NEXT:    s_or_b32 s4, vcc_lo, s4194; GFX10-NEXT:    s_andn2_b32 s6, s6, exec_lo195; GFX10-NEXT:    s_and_b32 s8, exec_lo, s5196; GFX10-NEXT:    s_or_b32 s6, s6, s8197; GFX10-NEXT:    s_andn2_b32 exec_lo, exec_lo, s4198; GFX10-NEXT:    s_cbranch_execnz .LBB3_1199; GFX10-NEXT:  ; %bb.2: ; %exit200; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s4201; GFX10-NEXT:    v_cndmask_b32_e64 v0, 0, 1.0, s6202; GFX10-NEXT:    v_cndmask_b32_e64 v1, -1.0, 2.0, s6203; GFX10-NEXT:    flat_store_dword v[2:3], v0204; GFX10-NEXT:    flat_store_dword v[4:5], v1205; GFX10-NEXT:    s_waitcnt lgkmcnt(0)206; GFX10-NEXT:    s_setpc_b64 s[30:31]207entry:208  %pre.cond = fcmp ogt float %pre.cond.val, 1.0209  br label %loop210 211loop:212  %counter = phi i32 [ 0, %entry ], [ %counter.plus.1, %loop ]213  %bool.counter = phi i1 [ %pre.cond, %entry ], [ %neg.bool.counter, %loop ]214  %neg.bool.counter = xor i1 %bool.counter, true215  %f.counter = uitofp i32 %counter to float216  %cond = fcmp ogt float %f.counter, %val217  %counter.plus.1 = add i32 %counter, 1218  br i1 %cond, label %exit, label %loop219 220exit:221  %select = select i1 %neg.bool.counter, float 1.000000e+00, float 0.000000e+00222  store float %select, ptr %addr223  %select2 = select i1 %neg.bool.counter, float 2.000000e+00, float -1.000000e+00224  store float %select2, ptr %addr2225  ret void226}227 228;void xor(int num_elts, int* a, int* addr) {229;for(int i=0; i<num_elts; ++i) {230;  if(a[i]==0)231;    return;232;}233;addr[0] = 5234;return;235;}236 237define void @divergent_i1_xor_used_outside_loop_larger_loop_body(i32 %num.elts, ptr addrspace(1) %a, ptr %addr) {238; GFX10-LABEL: divergent_i1_xor_used_outside_loop_larger_loop_body:239; GFX10:       ; %bb.0: ; %entry240; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)241; GFX10-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0242; GFX10-NEXT:    s_mov_b32 s6, exec_lo243; GFX10-NEXT:    s_mov_b32 s4, 0244; GFX10-NEXT:    s_and_saveexec_b32 s7, vcc_lo245; GFX10-NEXT:    s_cbranch_execz .LBB4_6246; GFX10-NEXT:  ; %bb.1: ; %loop.start.preheader247; GFX10-NEXT:    s_mov_b32 s8, 0248; GFX10-NEXT:    ; implicit-def: $sgpr10249; GFX10-NEXT:    ; implicit-def: $sgpr11250; GFX10-NEXT:    ; implicit-def: $sgpr9251; GFX10-NEXT:    s_branch .LBB4_3252; GFX10-NEXT:  .LBB4_2: ; %Flow253; GFX10-NEXT:    ; in Loop: Header=BB4_3 Depth=1254; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s5255; GFX10-NEXT:    s_xor_b32 s5, s11, exec_lo256; GFX10-NEXT:    s_and_b32 s12, exec_lo, s10257; GFX10-NEXT:    s_or_b32 s8, s12, s8258; GFX10-NEXT:    s_andn2_b32 s9, s9, exec_lo259; GFX10-NEXT:    s_and_b32 s5, exec_lo, s5260; GFX10-NEXT:    s_or_b32 s9, s9, s5261; GFX10-NEXT:    s_andn2_b32 exec_lo, exec_lo, s8262; GFX10-NEXT:    s_cbranch_execz .LBB4_5263; GFX10-NEXT:  .LBB4_3: ; %loop.start264; GFX10-NEXT:    ; =>This Inner Loop Header: Depth=1265; GFX10-NEXT:    s_ashr_i32 s5, s4, 31266; GFX10-NEXT:    s_andn2_b32 s10, s10, exec_lo267; GFX10-NEXT:    s_lshl_b64 s[12:13], s[4:5], 2268; GFX10-NEXT:    s_andn2_b32 s5, s11, exec_lo269; GFX10-NEXT:    v_mov_b32_e32 v5, s12270; GFX10-NEXT:    v_mov_b32_e32 v6, s13271; GFX10-NEXT:    s_and_b32 s11, exec_lo, exec_lo272; GFX10-NEXT:    s_and_b32 s12, exec_lo, exec_lo273; GFX10-NEXT:    s_or_b32 s11, s5, s11274; GFX10-NEXT:    v_add_co_u32 v5, vcc_lo, v1, v5275; GFX10-NEXT:    v_add_co_ci_u32_e32 v6, vcc_lo, v2, v6, vcc_lo276; GFX10-NEXT:    s_or_b32 s10, s10, s12277; GFX10-NEXT:    global_load_dword v5, v[5:6], off278; GFX10-NEXT:    s_waitcnt vmcnt(0)279; GFX10-NEXT:    v_cmp_ne_u32_e32 vcc_lo, 0, v5280; GFX10-NEXT:    s_and_saveexec_b32 s5, vcc_lo281; GFX10-NEXT:    s_cbranch_execz .LBB4_2282; GFX10-NEXT:  ; %bb.4: ; %loop.cond283; GFX10-NEXT:    ; in Loop: Header=BB4_3 Depth=1284; GFX10-NEXT:    v_cmp_lt_i32_e32 vcc_lo, s4, v0285; GFX10-NEXT:    s_andn2_b32 s11, s11, exec_lo286; GFX10-NEXT:    s_and_b32 s12, exec_lo, 0287; GFX10-NEXT:    s_andn2_b32 s10, s10, exec_lo288; GFX10-NEXT:    s_add_i32 s4, s4, 1289; GFX10-NEXT:    s_and_b32 s13, exec_lo, vcc_lo290; GFX10-NEXT:    s_or_b32 s11, s11, s12291; GFX10-NEXT:    s_or_b32 s10, s10, s13292; GFX10-NEXT:    s_branch .LBB4_2293; GFX10-NEXT:  .LBB4_5: ; %loop.exit.guard294; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s8295; GFX10-NEXT:    s_andn2_b32 s4, s6, exec_lo296; GFX10-NEXT:    s_and_b32 s5, exec_lo, s9297; GFX10-NEXT:    s_or_b32 s6, s4, s5298; GFX10-NEXT:  .LBB4_6: ; %Flow1299; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s7300; GFX10-NEXT:    s_and_saveexec_b32 s4, s6301; GFX10-NEXT:    s_cbranch_execz .LBB4_8302; GFX10-NEXT:  ; %bb.7: ; %block.after.loop303; GFX10-NEXT:    v_mov_b32_e32 v0, 5304; GFX10-NEXT:    flat_store_dword v[3:4], v0305; GFX10-NEXT:  .LBB4_8: ; %exit306; GFX10-NEXT:    s_waitcnt_depctr depctr_vm_vsrc(0)307; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s4308; GFX10-NEXT:    s_waitcnt lgkmcnt(0)309; GFX10-NEXT:    s_setpc_b64 s[30:31]310entry:311  %start.cond = icmp eq i32 %num.elts, 0312  br i1 %start.cond, label %loop.start, label %block.after.loop313 314loop.start:315  %i = phi i32 [ 0, %entry ], [ %i.plus.1, %loop.cond ]316  %a.plus.i = getelementptr i32, ptr addrspace(1) %a, i32 %i317  %elt.i = load i32, ptr addrspace(1) %a.plus.i318  %elt.i.eq.zero = icmp eq i32 %elt.i, 0319  br i1 %elt.i.eq.zero, label %exit, label %loop.cond320 321loop.cond:322  %cond = icmp slt i32 %i, %num.elts323  %i.plus.1 = add i32 %i, 1324  br i1 %cond, label %block.after.loop, label %loop.start325 326block.after.loop:327  store i32 5, ptr %addr328  br label %exit329 330exit:331  ret void332}333 334 335;void icmp(int num_elts, int* a, int* addr) {336;for(;;) {337;  if(a[i]==0)338;    return;339;}340;addr[0] = 5341;return;342;}343 344define void @divergent_i1_icmp_used_outside_loop(i32 %v0, i32 %v1, ptr addrspace(1) %a, ptr addrspace(1) %b, ptr addrspace(1) %c, ptr %addr) {345; GFX10-LABEL: divergent_i1_icmp_used_outside_loop:346; GFX10:       ; %bb.0: ; %entry347; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)348; GFX10-NEXT:    s_mov_b32 s4, 0349; GFX10-NEXT:    s_mov_b32 s6, 0350; GFX10-NEXT:    ; implicit-def: $sgpr7351; GFX10-NEXT:    s_branch .LBB5_2352; GFX10-NEXT:  .LBB5_1: ; %Flow353; GFX10-NEXT:    ; in Loop: Header=BB5_2 Depth=1354; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s8355; GFX10-NEXT:    s_and_b32 s5, exec_lo, s5356; GFX10-NEXT:    s_or_b32 s6, s5, s6357; GFX10-NEXT:    s_andn2_b32 exec_lo, exec_lo, s6358; GFX10-NEXT:    s_cbranch_execz .LBB5_6359; GFX10-NEXT:  .LBB5_2: ; %cond.block.0360; GFX10-NEXT:    ; =>This Inner Loop Header: Depth=1361; GFX10-NEXT:    v_cmp_eq_u32_e32 vcc_lo, s4, v0362; GFX10-NEXT:    v_mov_b32_e32 v4, s4363; GFX10-NEXT:    s_andn2_b32 s5, s7, exec_lo364; GFX10-NEXT:    s_and_b32 s7, exec_lo, vcc_lo365; GFX10-NEXT:    s_or_b32 s7, s5, s7366; GFX10-NEXT:    s_and_saveexec_b32 s8, vcc_lo367; GFX10-NEXT:    s_cbranch_execz .LBB5_4368; GFX10-NEXT:  ; %bb.3: ; %if.block.0369; GFX10-NEXT:    ; in Loop: Header=BB5_2 Depth=1370; GFX10-NEXT:    s_ashr_i32 s5, s4, 31371; GFX10-NEXT:    v_mov_b32_e32 v5, s4372; GFX10-NEXT:    s_lshl_b64 s[10:11], s[4:5], 2373; GFX10-NEXT:    v_mov_b32_e32 v8, s10374; GFX10-NEXT:    v_mov_b32_e32 v9, s11375; GFX10-NEXT:    v_add_co_u32 v8, vcc_lo, v2, v8376; GFX10-NEXT:    v_add_co_ci_u32_e32 v9, vcc_lo, v3, v9, vcc_lo377; GFX10-NEXT:    global_store_dword v[8:9], v5, off378; GFX10-NEXT:  .LBB5_4: ; %loop.break.block379; GFX10-NEXT:    ; in Loop: Header=BB5_2 Depth=1380; GFX10-NEXT:    s_waitcnt_depctr depctr_vm_vsrc(0)381; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s8382; GFX10-NEXT:    v_cmp_ne_u32_e32 vcc_lo, s4, v1383; GFX10-NEXT:    s_mov_b32 s5, exec_lo384; GFX10-NEXT:    s_and_saveexec_b32 s8, vcc_lo385; GFX10-NEXT:    s_cbranch_execz .LBB5_1386; GFX10-NEXT:  ; %bb.5: ; %loop.cond387; GFX10-NEXT:    ; in Loop: Header=BB5_2 Depth=1388; GFX10-NEXT:    s_andn2_b32 s5, s5, exec_lo389; GFX10-NEXT:    s_and_b32 s9, exec_lo, 0390; GFX10-NEXT:    s_add_i32 s4, s4, 1391; GFX10-NEXT:    s_or_b32 s5, s5, s9392; GFX10-NEXT:    s_branch .LBB5_1393; GFX10-NEXT:  .LBB5_6: ; %cond.block.1394; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s6395; GFX10-NEXT:    s_and_saveexec_b32 s4, s7396; GFX10-NEXT:    s_cbranch_execz .LBB5_8397; GFX10-NEXT:  ; %bb.7: ; %if.block.1398; GFX10-NEXT:    global_store_dword v[6:7], v4, off399; GFX10-NEXT:  .LBB5_8: ; %exit400; GFX10-NEXT:    s_waitcnt_depctr depctr_vm_vsrc(0)401; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s4402; GFX10-NEXT:    s_setpc_b64 s[30:31]403entry:404  br label %loop.start405 406loop.start:407  %i = phi i32 [ 0, %entry ], [ %i.plus.1, %loop.cond ]408  br label %cond.block.0409 410cond.block.0:411  %cond.0 = icmp eq i32 %v0, %i412  br i1 %cond.0, label %if.block.0, label %loop.break.block413 414if.block.0:415  %a.plus.i = getelementptr i32, ptr addrspace(1) %a, i32 %i416  store i32 %i, ptr addrspace(1) %a.plus.i417  br label %loop.break.block418 419loop.break.block:420  %cond.1 = icmp eq i32 %v1, %i421  br i1 %cond.1, label %cond.block.1, label %loop.cond422 423loop.cond:424  ; no cond, infinite loop with one break425  %i.plus.1 = add i32 %i, 1426  br label %loop.start427 428cond.block.1:429  %cond.2 = icmp eq i32 %v0, %i430  br i1 %cond.2, label %if.block.1, label %exit431 432if.block.1:433  store i32 %i, ptr addrspace(1) %c434  br label %exit435 436exit:437  ret void438}439 440 441; bool all_eq_zero = true;442; i32 i = 0;443; do {444;   if(all_eq_zero)445;     all_eq_zero = (a[i] == 0);446;447;   i += 1;448; } while ( i < n )449 450; *addr = all_eq_zero ? 1.0 : 0.0;451 452; check that all elements in an array of size n are zero, loop has divergent453; exit condition based on array size, but zero check does not break out of the454; loop but instead skips zero check in remaining iterations455; llpc "freezes" zero check since it is (via phi) used in a conditional branch456define amdgpu_ps void @divergent_i1_freeze_used_outside_loop(i32 %n, ptr addrspace(1) %a, ptr %addr) {457; GFX10-LABEL: divergent_i1_freeze_used_outside_loop:458; GFX10:       ; %bb.0: ; %entry459; GFX10-NEXT:    s_mov_b32 s1, exec_lo460; GFX10-NEXT:    s_mov_b32 s0, 0461; GFX10-NEXT:    s_mov_b32 s2, 0462; GFX10-NEXT:    ; implicit-def: $sgpr4463; GFX10-NEXT:    ; implicit-def: $sgpr3464; GFX10-NEXT:    s_branch .LBB6_2465; GFX10-NEXT:  .LBB6_1: ; %loop.cond466; GFX10-NEXT:    ; in Loop: Header=BB6_2 Depth=1467; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s5468; GFX10-NEXT:    v_cmp_lt_i32_e32 vcc_lo, s0, v0469; GFX10-NEXT:    s_add_i32 s0, s0, 1470; GFX10-NEXT:    s_or_b32 s2, vcc_lo, s2471; GFX10-NEXT:    s_andn2_b32 s3, s3, exec_lo472; GFX10-NEXT:    s_and_b32 s5, exec_lo, s4473; GFX10-NEXT:    s_andn2_b32 s1, s1, exec_lo474; GFX10-NEXT:    s_or_b32 s3, s3, s5475; GFX10-NEXT:    s_or_b32 s1, s1, s5476; GFX10-NEXT:    s_andn2_b32 exec_lo, exec_lo, s2477; GFX10-NEXT:    s_cbranch_execz .LBB6_4478; GFX10-NEXT:  .LBB6_2: ; %loop.start479; GFX10-NEXT:    ; =>This Inner Loop Header: Depth=1480; GFX10-NEXT:    s_andn2_b32 s4, s4, exec_lo481; GFX10-NEXT:    s_and_b32 s5, exec_lo, s1482; GFX10-NEXT:    s_or_b32 s4, s4, s5483; GFX10-NEXT:    s_and_saveexec_b32 s5, s1484; GFX10-NEXT:    s_cbranch_execz .LBB6_1485; GFX10-NEXT:  ; %bb.3: ; %is.eq.zero486; GFX10-NEXT:    ; in Loop: Header=BB6_2 Depth=1487; GFX10-NEXT:    s_ashr_i32 s1, s0, 31488; GFX10-NEXT:    s_lshl_b64 s[6:7], s[0:1], 2489; GFX10-NEXT:    s_andn2_b32 s1, s4, exec_lo490; GFX10-NEXT:    v_mov_b32_e32 v5, s6491; GFX10-NEXT:    v_mov_b32_e32 v6, s7492; GFX10-NEXT:    v_add_co_u32 v5, vcc_lo, v1, v5493; GFX10-NEXT:    v_add_co_ci_u32_e32 v6, vcc_lo, v2, v6, vcc_lo494; GFX10-NEXT:    global_load_dword v5, v[5:6], off495; GFX10-NEXT:    s_waitcnt vmcnt(0)496; GFX10-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v5497; GFX10-NEXT:    s_and_b32 s4, exec_lo, vcc_lo498; GFX10-NEXT:    s_or_b32 s4, s1, s4499; GFX10-NEXT:    ; implicit-def: $sgpr1500; GFX10-NEXT:    s_branch .LBB6_1501; GFX10-NEXT:  .LBB6_4: ; %exit502; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s2503; GFX10-NEXT:    v_cndmask_b32_e64 v0, 0, 1.0, s3504; GFX10-NEXT:    flat_store_dword v[3:4], v0505; GFX10-NEXT:    s_endpgm506entry:507  br label %loop.start508 509loop.start:510  %i = phi i32 [ 0, %entry ], [ %i.plus.1, %loop.cond ]511  %all.eq.zero = phi i1 [ true, %entry ], [ %eq.zero.fr, %loop.cond ]512  br i1 %all.eq.zero, label %is.eq.zero, label %loop.cond513 514is.eq.zero:515  %a.plus.i = getelementptr i32, ptr addrspace(1) %a, i32 %i516  %elt.i = load i32, ptr addrspace(1) %a.plus.i517  %elt.i.eq.zero = icmp eq i32 %elt.i, 0518  br label %loop.cond519 520loop.cond:521  %eq.zero = phi i1 [ %all.eq.zero, %loop.start ], [ %elt.i.eq.zero, %is.eq.zero ]522  %eq.zero.fr = freeze i1 %eq.zero523  %cond = icmp slt i32 %i, %n524  %i.plus.1 = add i32 %i, 1525  br i1 %cond, label %exit, label %loop.start526 527exit:528  %select = select i1 %eq.zero.fr, float 1.000000e+00, float 0.000000e+00529  store float %select, ptr %addr530  ret void531}532 533; Divergent i1 phi from structurize-cfg used outside of the loop534define amdgpu_cs void @loop_with_1break(ptr addrspace(1) %x, ptr addrspace(1) %a, ptr addrspace(1) %a.break) {535; GFX10-LABEL: loop_with_1break:536; GFX10:       ; %bb.0: ; %entry537; GFX10-NEXT:    s_mov_b32 s0, 0538; GFX10-NEXT:    s_mov_b32 s4, 0539; GFX10-NEXT:    ; implicit-def: $sgpr6540; GFX10-NEXT:    ; implicit-def: $sgpr7541; GFX10-NEXT:    ; implicit-def: $sgpr5542; GFX10-NEXT:    s_branch .LBB7_2543; GFX10-NEXT:  .LBB7_1: ; %Flow544; GFX10-NEXT:    ; in Loop: Header=BB7_2 Depth=1545; GFX10-NEXT:    s_waitcnt_depctr depctr_vm_vsrc(0)546; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s1547; GFX10-NEXT:    s_and_b32 s1, exec_lo, s6548; GFX10-NEXT:    s_or_b32 s4, s1, s4549; GFX10-NEXT:    s_andn2_b32 s1, s5, exec_lo550; GFX10-NEXT:    s_and_b32 s2, exec_lo, s7551; GFX10-NEXT:    s_or_b32 s5, s1, s2552; GFX10-NEXT:    s_andn2_b32 exec_lo, exec_lo, s4553; GFX10-NEXT:    s_cbranch_execz .LBB7_4554; GFX10-NEXT:  .LBB7_2: ; %A555; GFX10-NEXT:    ; =>This Inner Loop Header: Depth=1556; GFX10-NEXT:    s_ashr_i32 s1, s0, 31557; GFX10-NEXT:    s_mov_b32 s8, exec_lo558; GFX10-NEXT:    s_lshl_b64 s[2:3], s[0:1], 2559; GFX10-NEXT:    s_andn2_b32 s1, s7, exec_lo560; GFX10-NEXT:    v_mov_b32_e32 v7, s3561; GFX10-NEXT:    v_mov_b32_e32 v6, s2562; GFX10-NEXT:    s_and_b32 s7, exec_lo, s8563; GFX10-NEXT:    s_andn2_b32 s6, s6, exec_lo564; GFX10-NEXT:    s_and_b32 s8, exec_lo, exec_lo565; GFX10-NEXT:    s_or_b32 s7, s1, s7566; GFX10-NEXT:    v_add_co_u32 v6, vcc_lo, v2, v6567; GFX10-NEXT:    v_add_co_ci_u32_e32 v7, vcc_lo, v3, v7, vcc_lo568; GFX10-NEXT:    s_or_b32 s6, s6, s8569; GFX10-NEXT:    global_load_dword v6, v[6:7], off570; GFX10-NEXT:    s_waitcnt vmcnt(0)571; GFX10-NEXT:    v_cmp_ne_u32_e32 vcc_lo, 0, v6572; GFX10-NEXT:    s_and_saveexec_b32 s1, vcc_lo573; GFX10-NEXT:    s_cbranch_execz .LBB7_1574; GFX10-NEXT:  ; %bb.3: ; %loop.body575; GFX10-NEXT:    ; in Loop: Header=BB7_2 Depth=1576; GFX10-NEXT:    v_mov_b32_e32 v7, s3577; GFX10-NEXT:    v_mov_b32_e32 v6, s2578; GFX10-NEXT:    s_add_i32 s2, s0, 1579; GFX10-NEXT:    s_cmpk_lt_u32 s0, 0x64580; GFX10-NEXT:    s_cselect_b32 s0, exec_lo, 0581; GFX10-NEXT:    v_add_co_u32 v6, vcc_lo, v0, v6582; GFX10-NEXT:    v_add_co_ci_u32_e32 v7, vcc_lo, v1, v7, vcc_lo583; GFX10-NEXT:    s_andn2_b32 s3, s7, exec_lo584; GFX10-NEXT:    s_and_b32 s7, exec_lo, 0585; GFX10-NEXT:    s_andn2_b32 s6, s6, exec_lo586; GFX10-NEXT:    global_load_dword v8, v[6:7], off587; GFX10-NEXT:    s_and_b32 s0, exec_lo, s0588; GFX10-NEXT:    s_or_b32 s7, s3, s7589; GFX10-NEXT:    s_or_b32 s6, s6, s0590; GFX10-NEXT:    s_mov_b32 s0, s2591; GFX10-NEXT:    s_waitcnt vmcnt(0)592; GFX10-NEXT:    v_add_nc_u32_e32 v8, 1, v8593; GFX10-NEXT:    global_store_dword v[6:7], v8, off594; GFX10-NEXT:    s_branch .LBB7_1595; GFX10-NEXT:  .LBB7_4: ; %loop.exit.guard596; GFX10-NEXT:    s_or_b32 exec_lo, exec_lo, s4597; GFX10-NEXT:    s_and_saveexec_b32 s0, s5598; GFX10-NEXT:    s_xor_b32 s0, exec_lo, s0599; GFX10-NEXT:    s_cbranch_execz .LBB7_6600; GFX10-NEXT:  ; %bb.5: ; %break.body601; GFX10-NEXT:    v_mov_b32_e32 v0, 10602; GFX10-NEXT:    global_store_dword v[4:5], v0, off603; GFX10-NEXT:  .LBB7_6: ; %exit604; GFX10-NEXT:    s_endpgm605entry:606  br label %A607 608A:609  %counter = phi i32 [ %counter.plus.1, %loop.body ], [ 0, %entry ]610  %a.plus.counter = getelementptr inbounds i32, ptr addrspace(1) %a, i32 %counter611  %a.val = load i32, ptr addrspace(1) %a.plus.counter612  %a.cond = icmp eq i32 %a.val, 0613  br i1 %a.cond, label %break.body, label %loop.body614 615break.body:616  store i32 10, ptr addrspace(1) %a.break617  br label %exit618 619loop.body:620  %x.plus.counter = getelementptr inbounds i32, ptr addrspace(1) %x, i32 %counter621  %x.val = load i32, ptr addrspace(1) %x.plus.counter622  %x.val.plus.1 = add i32 %x.val, 1623  store i32 %x.val.plus.1, ptr addrspace(1) %x.plus.counter624  %counter.plus.1 = add i32 %counter, 1625  %x.cond = icmp ult i32 %counter, 100626  br i1 %x.cond, label %exit, label %A627 628exit:629  ret void630}631 632