545 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: opt -mtriple=amdgcn-- -S -structurizecfg -si-annotate-control-flow %s | FileCheck -check-prefix=OPT %s3; RUN: llc -mtriple=amdgcn -disable-block-placement < %s | FileCheck -check-prefix=GCN %s4 5; Uses llvm.amdgcn.break6 7define amdgpu_kernel void @break_loop(i32 %arg) #0 {8; OPT-LABEL: define amdgpu_kernel void @break_loop(9; OPT-SAME: i32 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {10; OPT-NEXT: [[BB:.*]]:11; OPT-NEXT: [[ID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()12; OPT-NEXT: [[MY_TMP:%.*]] = sub i32 [[ID]], [[ARG]]13; OPT-NEXT: br label %[[BB1:.*]]14; OPT: [[BB1]]:15; OPT-NEXT: [[PHI_BROKEN:%.*]] = phi i64 [ [[TMP2:%.*]], %[[FLOW:.*]] ], [ 0, %[[BB]] ]16; OPT-NEXT: [[LSR_IV:%.*]] = phi i32 [ undef, %[[BB]] ], [ [[TMP0:%.*]], %[[FLOW]] ]17; OPT-NEXT: [[TMP0]] = add i32 [[LSR_IV]], 118; OPT-NEXT: [[CMP0:%.*]] = icmp slt i32 [[TMP0]], 019; OPT-NEXT: br i1 [[CMP0]], label %[[BB4:.*]], label %[[FLOW]]20; OPT: [[BB4]]:21; OPT-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(1) poison, align 422; OPT-NEXT: [[CMP1:%.*]] = icmp sge i32 [[MY_TMP]], [[LOAD]]23; OPT-NEXT: br label %[[FLOW]]24; OPT: [[FLOW]]:25; OPT-NEXT: [[TMP1:%.*]] = phi i1 [ [[CMP1]], %[[BB4]] ], [ true, %[[BB1]] ]26; OPT-NEXT: [[TMP2]] = call i64 @llvm.amdgcn.if.break.i64(i1 [[TMP1]], i64 [[PHI_BROKEN]])27; OPT-NEXT: [[TMP3:%.*]] = call i1 @llvm.amdgcn.loop.i64(i64 [[TMP2]])28; OPT-NEXT: br i1 [[TMP3]], label %[[BB9:.*]], label %[[BB1]]29; OPT: [[BB9]]:30; OPT-NEXT: call void @llvm.amdgcn.end.cf.i64(i64 [[TMP2]])31; OPT-NEXT: ret void32;33; GCN-LABEL: break_loop:34; GCN: ; %bb.0: ; %bb35; GCN-NEXT: s_load_dword s3, s[4:5], 0x936; GCN-NEXT: s_mov_b64 s[0:1], 037; GCN-NEXT: s_mov_b32 s2, -138; GCN-NEXT: s_waitcnt lgkmcnt(0)39; GCN-NEXT: v_subrev_i32_e32 v0, vcc, s3, v040; GCN-NEXT: s_mov_b32 s3, 0xf00041; GCN-NEXT: ; implicit-def: $sgpr4_sgpr542; GCN-NEXT: ; implicit-def: $sgpr643; GCN-NEXT: .LBB0_1: ; %bb144; GCN-NEXT: ; =>This Inner Loop Header: Depth=145; GCN-NEXT: s_add_i32 s6, s6, 146; GCN-NEXT: s_or_b64 s[4:5], s[4:5], exec47; GCN-NEXT: s_cmp_gt_i32 s6, -148; GCN-NEXT: s_cbranch_scc1 .LBB0_349; GCN-NEXT: ; %bb.2: ; %bb450; GCN-NEXT: ; in Loop: Header=BB0_1 Depth=151; GCN-NEXT: buffer_load_dword v1, off, s[0:3], 0 glc52; GCN-NEXT: s_waitcnt vmcnt(0)53; GCN-NEXT: v_cmp_ge_i32_e32 vcc, v0, v154; GCN-NEXT: s_andn2_b64 s[4:5], s[4:5], exec55; GCN-NEXT: s_and_b64 s[8:9], vcc, exec56; GCN-NEXT: s_or_b64 s[4:5], s[4:5], s[8:9]57; GCN-NEXT: .LBB0_3: ; %Flow58; GCN-NEXT: ; in Loop: Header=BB0_1 Depth=159; GCN-NEXT: s_and_b64 s[8:9], exec, s[4:5]60; GCN-NEXT: s_or_b64 s[0:1], s[8:9], s[0:1]61; GCN-NEXT: s_andn2_b64 exec, exec, s[0:1]62; GCN-NEXT: s_cbranch_execnz .LBB0_163; GCN-NEXT: ; %bb.4: ; %bb964; GCN-NEXT: s_endpgm65bb:66 %id = call i32 @llvm.amdgcn.workitem.id.x()67 %my.tmp = sub i32 %id, %arg68 br label %bb169 70bb1:71 %lsr.iv = phi i32 [ undef, %bb ], [ %lsr.iv.next, %bb4 ]72 %lsr.iv.next = add i32 %lsr.iv, 173 %cmp0 = icmp slt i32 %lsr.iv.next, 074 br i1 %cmp0, label %bb4, label %bb975 76bb4:77 %load = load volatile i32, ptr addrspace(1) poison, align 478 %cmp1 = icmp slt i32 %my.tmp, %load79 br i1 %cmp1, label %bb1, label %bb980 81bb9:82 ret void83}84 85define amdgpu_kernel void @undef_phi_cond_break_loop(i32 %arg) #0 {86; OPT-LABEL: define amdgpu_kernel void @undef_phi_cond_break_loop(87; OPT-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {88; OPT-NEXT: [[BB:.*]]:89; OPT-NEXT: [[ID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()90; OPT-NEXT: [[MY_TMP:%.*]] = sub i32 [[ID]], [[ARG]]91; OPT-NEXT: br label %[[BB1:.*]]92; OPT: [[BB1]]:93; OPT-NEXT: [[PHI_BROKEN:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FLOW:.*]] ], [ 0, %[[BB]] ]94; OPT-NEXT: [[LSR_IV:%.*]] = phi i32 [ undef, %[[BB]] ], [ [[MY_TMP2:%.*]], %[[FLOW]] ]95; OPT-NEXT: [[LSR_IV_NEXT:%.*]] = add i32 [[LSR_IV]], 196; OPT-NEXT: [[CMP0:%.*]] = icmp slt i32 [[LSR_IV_NEXT]], 097; OPT-NEXT: br i1 [[CMP0]], label %[[BB4:.*]], label %[[FLOW]]98; OPT: [[BB4]]:99; OPT-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(1) poison, align 4100; OPT-NEXT: [[CMP1:%.*]] = icmp sge i32 [[MY_TMP]], [[LOAD]]101; OPT-NEXT: br label %[[FLOW]]102; OPT: [[FLOW]]:103; OPT-NEXT: [[MY_TMP2]] = phi i32 [ [[LSR_IV_NEXT]], %[[BB4]] ], [ undef, %[[BB1]] ]104; OPT-NEXT: [[MY_TMP3:%.*]] = phi i1 [ [[CMP1]], %[[BB4]] ], [ undef, %[[BB1]] ]105; OPT-NEXT: [[TMP0]] = call i64 @llvm.amdgcn.if.break.i64(i1 [[MY_TMP3]], i64 [[PHI_BROKEN]])106; OPT-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.loop.i64(i64 [[TMP0]])107; OPT-NEXT: br i1 [[TMP1]], label %[[BB9:.*]], label %[[BB1]]108; OPT: [[BB9]]:109; OPT-NEXT: call void @llvm.amdgcn.end.cf.i64(i64 [[TMP0]])110; OPT-NEXT: store volatile i32 7, ptr addrspace(3) poison, align 4111; OPT-NEXT: ret void112;113; GCN-LABEL: undef_phi_cond_break_loop:114; GCN: ; %bb.0: ; %bb115; GCN-NEXT: s_load_dword s3, s[4:5], 0x9116; GCN-NEXT: s_mov_b64 s[0:1], 0117; GCN-NEXT: s_mov_b32 s2, -1118; GCN-NEXT: s_waitcnt lgkmcnt(0)119; GCN-NEXT: v_subrev_i32_e32 v0, vcc, s3, v0120; GCN-NEXT: s_mov_b32 s3, 0xf000121; GCN-NEXT: ; implicit-def: $sgpr6122; GCN-NEXT: .LBB1_1: ; %bb1123; GCN-NEXT: ; =>This Inner Loop Header: Depth=1124; GCN-NEXT: s_cmp_gt_i32 s6, -1125; GCN-NEXT: ; implicit-def: $sgpr4_sgpr5126; GCN-NEXT: s_cbranch_scc1 .LBB1_3127; GCN-NEXT: ; %bb.2: ; %bb4128; GCN-NEXT: ; in Loop: Header=BB1_1 Depth=1129; GCN-NEXT: buffer_load_dword v1, off, s[0:3], 0 glc130; GCN-NEXT: s_waitcnt vmcnt(0)131; GCN-NEXT: v_cmp_ge_i32_e64 s[4:5], v0, v1132; GCN-NEXT: .LBB1_3: ; %Flow133; GCN-NEXT: ; in Loop: Header=BB1_1 Depth=1134; GCN-NEXT: s_add_i32 s6, s6, 1135; GCN-NEXT: s_and_b64 s[4:5], exec, s[4:5]136; GCN-NEXT: s_or_b64 s[0:1], s[4:5], s[0:1]137; GCN-NEXT: s_andn2_b64 exec, exec, s[0:1]138; GCN-NEXT: s_cbranch_execnz .LBB1_1139; GCN-NEXT: ; %bb.4: ; %bb9140; GCN-NEXT: s_or_b64 exec, exec, s[0:1]141; GCN-NEXT: v_mov_b32_e32 v0, 7142; GCN-NEXT: s_mov_b32 m0, -1143; GCN-NEXT: ds_write_b32 v0, v0144; GCN-NEXT: s_endpgm145bb:146 %id = call i32 @llvm.amdgcn.workitem.id.x()147 %my.tmp = sub i32 %id, %arg148 br label %bb1149 150bb1: ; preds = %Flow, %bb151 %lsr.iv = phi i32 [ undef, %bb ], [ %my.tmp2, %Flow ]152 %lsr.iv.next = add i32 %lsr.iv, 1153 %cmp0 = icmp slt i32 %lsr.iv.next, 0154 br i1 %cmp0, label %bb4, label %Flow155 156bb4: ; preds = %bb1157 %load = load volatile i32, ptr addrspace(1) poison, align 4158 %cmp1 = icmp sge i32 %my.tmp, %load159 br label %Flow160 161Flow: ; preds = %bb4, %bb1162 %my.tmp2 = phi i32 [ %lsr.iv.next, %bb4 ], [ undef, %bb1 ]163 %my.tmp3 = phi i1 [ %cmp1, %bb4 ], [ undef, %bb1 ]164 br i1 %my.tmp3, label %bb9, label %bb1165 166bb9: ; preds = %Flow167 store volatile i32 7, ptr addrspace(3) poison168 ret void169}170 171; FIXME: ConstantExpr compare of address to null folds away172@lds = addrspace(3) global i32 poison173 174define amdgpu_kernel void @constexpr_phi_cond_break_loop(i32 %arg) #0 {175; OPT-LABEL: define amdgpu_kernel void @constexpr_phi_cond_break_loop(176; OPT-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {177; OPT-NEXT: [[BB:.*]]:178; OPT-NEXT: [[ID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()179; OPT-NEXT: [[MY_TMP:%.*]] = sub i32 [[ID]], [[ARG]]180; OPT-NEXT: br label %[[BB1:.*]]181; OPT: [[BB1]]:182; OPT-NEXT: [[PHI_BROKEN:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FLOW:.*]] ], [ 0, %[[BB]] ]183; OPT-NEXT: [[LSR_IV:%.*]] = phi i32 [ undef, %[[BB]] ], [ [[MY_TMP2:%.*]], %[[FLOW]] ]184; OPT-NEXT: [[LSR_IV_NEXT:%.*]] = add i32 [[LSR_IV]], 1185; OPT-NEXT: [[CMP0:%.*]] = icmp slt i32 [[LSR_IV_NEXT]], 0186; OPT-NEXT: [[CMP2:%.*]] = icmp ne ptr addrspace(3) inttoptr (i32 4 to ptr addrspace(3)), @lds187; OPT-NEXT: br i1 [[CMP0]], label %[[BB4:.*]], label %[[FLOW]]188; OPT: [[BB4]]:189; OPT-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(1) poison, align 4190; OPT-NEXT: [[CMP1:%.*]] = icmp sge i32 [[MY_TMP]], [[LOAD]]191; OPT-NEXT: br label %[[FLOW]]192; OPT: [[FLOW]]:193; OPT-NEXT: [[MY_TMP2]] = phi i32 [ [[LSR_IV_NEXT]], %[[BB4]] ], [ undef, %[[BB1]] ]194; OPT-NEXT: [[MY_TMP3:%.*]] = phi i1 [ [[CMP1]], %[[BB4]] ], [ [[CMP2]], %[[BB1]] ]195; OPT-NEXT: [[TMP0]] = call i64 @llvm.amdgcn.if.break.i64(i1 [[MY_TMP3]], i64 [[PHI_BROKEN]])196; OPT-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.loop.i64(i64 [[TMP0]])197; OPT-NEXT: br i1 [[TMP1]], label %[[BB9:.*]], label %[[BB1]]198; OPT: [[BB9]]:199; OPT-NEXT: call void @llvm.amdgcn.end.cf.i64(i64 [[TMP0]])200; OPT-NEXT: store volatile i32 7, ptr addrspace(3) poison, align 4201; OPT-NEXT: ret void202;203; GCN-LABEL: constexpr_phi_cond_break_loop:204; GCN: ; %bb.0: ; %bb205; GCN-NEXT: s_load_dword s3, s[4:5], 0x9206; GCN-NEXT: s_mov_b64 s[0:1], 0207; GCN-NEXT: s_mov_b32 s2, -1208; GCN-NEXT: s_waitcnt lgkmcnt(0)209; GCN-NEXT: v_subrev_i32_e32 v0, vcc, s3, v0210; GCN-NEXT: s_mov_b32 s3, 0xf000211; GCN-NEXT: ; implicit-def: $sgpr4_sgpr5212; GCN-NEXT: ; implicit-def: $sgpr6213; GCN-NEXT: .LBB2_1: ; %bb1214; GCN-NEXT: ; =>This Inner Loop Header: Depth=1215; GCN-NEXT: s_or_b64 s[4:5], s[4:5], exec216; GCN-NEXT: s_cmp_gt_i32 s6, -1217; GCN-NEXT: s_cbranch_scc1 .LBB2_3218; GCN-NEXT: ; %bb.2: ; %bb4219; GCN-NEXT: ; in Loop: Header=BB2_1 Depth=1220; GCN-NEXT: buffer_load_dword v1, off, s[0:3], 0 glc221; GCN-NEXT: s_waitcnt vmcnt(0)222; GCN-NEXT: v_cmp_ge_i32_e32 vcc, v0, v1223; GCN-NEXT: s_andn2_b64 s[4:5], s[4:5], exec224; GCN-NEXT: s_and_b64 s[8:9], vcc, exec225; GCN-NEXT: s_or_b64 s[4:5], s[4:5], s[8:9]226; GCN-NEXT: .LBB2_3: ; %Flow227; GCN-NEXT: ; in Loop: Header=BB2_1 Depth=1228; GCN-NEXT: s_add_i32 s6, s6, 1229; GCN-NEXT: s_and_b64 s[8:9], exec, s[4:5]230; GCN-NEXT: s_or_b64 s[0:1], s[8:9], s[0:1]231; GCN-NEXT: s_andn2_b64 exec, exec, s[0:1]232; GCN-NEXT: s_cbranch_execnz .LBB2_1233; GCN-NEXT: ; %bb.4: ; %bb9234; GCN-NEXT: s_or_b64 exec, exec, s[0:1]235; GCN-NEXT: v_mov_b32_e32 v0, 7236; GCN-NEXT: s_mov_b32 m0, -1237; GCN-NEXT: ds_write_b32 v0, v0238; GCN-NEXT: s_endpgm239bb:240 %id = call i32 @llvm.amdgcn.workitem.id.x()241 %my.tmp = sub i32 %id, %arg242 br label %bb1243 244bb1: ; preds = %Flow, %bb245 %lsr.iv = phi i32 [ undef, %bb ], [ %my.tmp2, %Flow ]246 %lsr.iv.next = add i32 %lsr.iv, 1247 %cmp0 = icmp slt i32 %lsr.iv.next, 0248 %cmp2 = icmp ne ptr addrspace(3) inttoptr (i32 4 to ptr addrspace(3)), @lds249 br i1 %cmp0, label %bb4, label %Flow250 251bb4: ; preds = %bb1252 %load = load volatile i32, ptr addrspace(1) poison, align 4253 %cmp1 = icmp sge i32 %my.tmp, %load254 br label %Flow255 256Flow: ; preds = %bb4, %bb1257 %my.tmp2 = phi i32 [ %lsr.iv.next, %bb4 ], [ undef, %bb1 ]258 %my.tmp3 = phi i1 [ %cmp1, %bb4 ], [ %cmp2, %bb1 ]259 br i1 %my.tmp3, label %bb9, label %bb1260 261bb9: ; preds = %Flow262 store volatile i32 7, ptr addrspace(3) poison263 ret void264}265 266define amdgpu_kernel void @true_phi_cond_break_loop(i32 %arg) #0 {267; OPT-LABEL: define amdgpu_kernel void @true_phi_cond_break_loop(268; OPT-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {269; OPT-NEXT: [[BB:.*]]:270; OPT-NEXT: [[ID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()271; OPT-NEXT: [[MY_TMP:%.*]] = sub i32 [[ID]], [[ARG]]272; OPT-NEXT: br label %[[BB1:.*]]273; OPT: [[BB1]]:274; OPT-NEXT: [[PHI_BROKEN:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FLOW:.*]] ], [ 0, %[[BB]] ]275; OPT-NEXT: [[LSR_IV:%.*]] = phi i32 [ undef, %[[BB]] ], [ [[MY_TMP2:%.*]], %[[FLOW]] ]276; OPT-NEXT: [[LSR_IV_NEXT:%.*]] = add i32 [[LSR_IV]], 1277; OPT-NEXT: [[CMP0:%.*]] = icmp slt i32 [[LSR_IV_NEXT]], 0278; OPT-NEXT: br i1 [[CMP0]], label %[[BB4:.*]], label %[[FLOW]]279; OPT: [[BB4]]:280; OPT-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(1) poison, align 4281; OPT-NEXT: [[CMP1:%.*]] = icmp sge i32 [[MY_TMP]], [[LOAD]]282; OPT-NEXT: br label %[[FLOW]]283; OPT: [[FLOW]]:284; OPT-NEXT: [[MY_TMP2]] = phi i32 [ [[LSR_IV_NEXT]], %[[BB4]] ], [ undef, %[[BB1]] ]285; OPT-NEXT: [[MY_TMP3:%.*]] = phi i1 [ [[CMP1]], %[[BB4]] ], [ true, %[[BB1]] ]286; OPT-NEXT: [[TMP0]] = call i64 @llvm.amdgcn.if.break.i64(i1 [[MY_TMP3]], i64 [[PHI_BROKEN]])287; OPT-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.loop.i64(i64 [[TMP0]])288; OPT-NEXT: br i1 [[TMP1]], label %[[BB9:.*]], label %[[BB1]]289; OPT: [[BB9]]:290; OPT-NEXT: call void @llvm.amdgcn.end.cf.i64(i64 [[TMP0]])291; OPT-NEXT: store volatile i32 7, ptr addrspace(3) poison, align 4292; OPT-NEXT: ret void293;294; GCN-LABEL: true_phi_cond_break_loop:295; GCN: ; %bb.0: ; %bb296; GCN-NEXT: s_load_dword s3, s[4:5], 0x9297; GCN-NEXT: s_mov_b64 s[0:1], 0298; GCN-NEXT: s_mov_b32 s2, -1299; GCN-NEXT: s_waitcnt lgkmcnt(0)300; GCN-NEXT: v_subrev_i32_e32 v0, vcc, s3, v0301; GCN-NEXT: s_mov_b32 s3, 0xf000302; GCN-NEXT: ; implicit-def: $sgpr4_sgpr5303; GCN-NEXT: ; implicit-def: $sgpr6304; GCN-NEXT: .LBB3_1: ; %bb1305; GCN-NEXT: ; =>This Inner Loop Header: Depth=1306; GCN-NEXT: s_or_b64 s[4:5], s[4:5], exec307; GCN-NEXT: s_cmp_gt_i32 s6, -1308; GCN-NEXT: s_cbranch_scc1 .LBB3_3309; GCN-NEXT: ; %bb.2: ; %bb4310; GCN-NEXT: ; in Loop: Header=BB3_1 Depth=1311; GCN-NEXT: buffer_load_dword v1, off, s[0:3], 0 glc312; GCN-NEXT: s_waitcnt vmcnt(0)313; GCN-NEXT: v_cmp_ge_i32_e32 vcc, v0, v1314; GCN-NEXT: s_andn2_b64 s[4:5], s[4:5], exec315; GCN-NEXT: s_and_b64 s[8:9], vcc, exec316; GCN-NEXT: s_or_b64 s[4:5], s[4:5], s[8:9]317; GCN-NEXT: .LBB3_3: ; %Flow318; GCN-NEXT: ; in Loop: Header=BB3_1 Depth=1319; GCN-NEXT: s_add_i32 s6, s6, 1320; GCN-NEXT: s_and_b64 s[8:9], exec, s[4:5]321; GCN-NEXT: s_or_b64 s[0:1], s[8:9], s[0:1]322; GCN-NEXT: s_andn2_b64 exec, exec, s[0:1]323; GCN-NEXT: s_cbranch_execnz .LBB3_1324; GCN-NEXT: ; %bb.4: ; %bb9325; GCN-NEXT: s_or_b64 exec, exec, s[0:1]326; GCN-NEXT: v_mov_b32_e32 v0, 7327; GCN-NEXT: s_mov_b32 m0, -1328; GCN-NEXT: ds_write_b32 v0, v0329; GCN-NEXT: s_endpgm330bb:331 %id = call i32 @llvm.amdgcn.workitem.id.x()332 %my.tmp = sub i32 %id, %arg333 br label %bb1334 335bb1: ; preds = %Flow, %bb336 %lsr.iv = phi i32 [ undef, %bb ], [ %my.tmp2, %Flow ]337 %lsr.iv.next = add i32 %lsr.iv, 1338 %cmp0 = icmp slt i32 %lsr.iv.next, 0339 br i1 %cmp0, label %bb4, label %Flow340 341bb4: ; preds = %bb1342 %load = load volatile i32, ptr addrspace(1) poison, align 4343 %cmp1 = icmp sge i32 %my.tmp, %load344 br label %Flow345 346Flow: ; preds = %bb4, %bb1347 %my.tmp2 = phi i32 [ %lsr.iv.next, %bb4 ], [ undef, %bb1 ]348 %my.tmp3 = phi i1 [ %cmp1, %bb4 ], [ true, %bb1 ]349 br i1 %my.tmp3, label %bb9, label %bb1350 351bb9: ; preds = %Flow352 store volatile i32 7, ptr addrspace(3) poison353 ret void354}355 356define amdgpu_kernel void @false_phi_cond_break_loop(i32 %arg) #0 {357; OPT-LABEL: define amdgpu_kernel void @false_phi_cond_break_loop(358; OPT-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {359; OPT-NEXT: [[BB:.*]]:360; OPT-NEXT: [[ID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()361; OPT-NEXT: [[MY_TMP:%.*]] = sub i32 [[ID]], [[ARG]]362; OPT-NEXT: br label %[[BB1:.*]]363; OPT: [[BB1]]:364; OPT-NEXT: [[PHI_BROKEN:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FLOW:.*]] ], [ 0, %[[BB]] ]365; OPT-NEXT: [[LSR_IV:%.*]] = phi i32 [ undef, %[[BB]] ], [ [[MY_TMP2:%.*]], %[[FLOW]] ]366; OPT-NEXT: [[LSR_IV_NEXT:%.*]] = add i32 [[LSR_IV]], 1367; OPT-NEXT: [[CMP0:%.*]] = icmp slt i32 [[LSR_IV_NEXT]], 0368; OPT-NEXT: br i1 [[CMP0]], label %[[BB4:.*]], label %[[FLOW]]369; OPT: [[BB4]]:370; OPT-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(1) poison, align 4371; OPT-NEXT: [[CMP1:%.*]] = icmp sge i32 [[MY_TMP]], [[LOAD]]372; OPT-NEXT: br label %[[FLOW]]373; OPT: [[FLOW]]:374; OPT-NEXT: [[MY_TMP2]] = phi i32 [ [[LSR_IV_NEXT]], %[[BB4]] ], [ undef, %[[BB1]] ]375; OPT-NEXT: [[MY_TMP3:%.*]] = phi i1 [ [[CMP1]], %[[BB4]] ], [ false, %[[BB1]] ]376; OPT-NEXT: [[TMP0]] = call i64 @llvm.amdgcn.if.break.i64(i1 [[MY_TMP3]], i64 [[PHI_BROKEN]])377; OPT-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.loop.i64(i64 [[TMP0]])378; OPT-NEXT: br i1 [[TMP1]], label %[[BB9:.*]], label %[[BB1]]379; OPT: [[BB9]]:380; OPT-NEXT: call void @llvm.amdgcn.end.cf.i64(i64 [[TMP0]])381; OPT-NEXT: store volatile i32 7, ptr addrspace(3) poison, align 4382; OPT-NEXT: ret void383;384; GCN-LABEL: false_phi_cond_break_loop:385; GCN: ; %bb.0: ; %bb386; GCN-NEXT: s_load_dword s3, s[4:5], 0x9387; GCN-NEXT: s_mov_b64 s[0:1], 0388; GCN-NEXT: s_mov_b32 s2, -1389; GCN-NEXT: s_waitcnt lgkmcnt(0)390; GCN-NEXT: v_subrev_i32_e32 v0, vcc, s3, v0391; GCN-NEXT: s_mov_b32 s3, 0xf000392; GCN-NEXT: ; implicit-def: $sgpr4_sgpr5393; GCN-NEXT: ; implicit-def: $sgpr6394; GCN-NEXT: .LBB4_1: ; %bb1395; GCN-NEXT: ; =>This Inner Loop Header: Depth=1396; GCN-NEXT: s_andn2_b64 s[4:5], s[4:5], exec397; GCN-NEXT: s_cmp_gt_i32 s6, -1398; GCN-NEXT: s_cbranch_scc1 .LBB4_3399; GCN-NEXT: ; %bb.2: ; %bb4400; GCN-NEXT: ; in Loop: Header=BB4_1 Depth=1401; GCN-NEXT: buffer_load_dword v1, off, s[0:3], 0 glc402; GCN-NEXT: s_waitcnt vmcnt(0)403; GCN-NEXT: v_cmp_ge_i32_e32 vcc, v0, v1404; GCN-NEXT: s_andn2_b64 s[4:5], s[4:5], exec405; GCN-NEXT: s_and_b64 s[8:9], vcc, exec406; GCN-NEXT: s_or_b64 s[4:5], s[4:5], s[8:9]407; GCN-NEXT: .LBB4_3: ; %Flow408; GCN-NEXT: ; in Loop: Header=BB4_1 Depth=1409; GCN-NEXT: s_add_i32 s6, s6, 1410; GCN-NEXT: s_and_b64 s[8:9], exec, s[4:5]411; GCN-NEXT: s_or_b64 s[0:1], s[8:9], s[0:1]412; GCN-NEXT: s_andn2_b64 exec, exec, s[0:1]413; GCN-NEXT: s_cbranch_execnz .LBB4_1414; GCN-NEXT: ; %bb.4: ; %bb9415; GCN-NEXT: s_or_b64 exec, exec, s[0:1]416; GCN-NEXT: v_mov_b32_e32 v0, 7417; GCN-NEXT: s_mov_b32 m0, -1418; GCN-NEXT: ds_write_b32 v0, v0419; GCN-NEXT: s_endpgm420bb:421 %id = call i32 @llvm.amdgcn.workitem.id.x()422 %my.tmp = sub i32 %id, %arg423 br label %bb1424 425bb1: ; preds = %Flow, %bb426 %lsr.iv = phi i32 [ undef, %bb ], [ %my.tmp2, %Flow ]427 %lsr.iv.next = add i32 %lsr.iv, 1428 %cmp0 = icmp slt i32 %lsr.iv.next, 0429 br i1 %cmp0, label %bb4, label %Flow430 431bb4: ; preds = %bb1432 %load = load volatile i32, ptr addrspace(1) poison, align 4433 %cmp1 = icmp sge i32 %my.tmp, %load434 br label %Flow435 436Flow: ; preds = %bb4, %bb1437 %my.tmp2 = phi i32 [ %lsr.iv.next, %bb4 ], [ undef, %bb1 ]438 %my.tmp3 = phi i1 [ %cmp1, %bb4 ], [ false, %bb1 ]439 br i1 %my.tmp3, label %bb9, label %bb1440 441bb9: ; preds = %Flow442 store volatile i32 7, ptr addrspace(3) poison443 ret void444}445 446; Swap order of branches in flow block so that the true phi is447; continue.448 449define amdgpu_kernel void @invert_true_phi_cond_break_loop(i32 %arg) #0 {450; OPT-LABEL: define amdgpu_kernel void @invert_true_phi_cond_break_loop(451; OPT-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {452; OPT-NEXT: [[BB:.*]]:453; OPT-NEXT: [[ID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()454; OPT-NEXT: [[MY_TMP:%.*]] = sub i32 [[ID]], [[ARG]]455; OPT-NEXT: br label %[[BB1:.*]]456; OPT: [[BB1]]:457; OPT-NEXT: [[PHI_BROKEN:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FLOW:.*]] ], [ 0, %[[BB]] ]458; OPT-NEXT: [[LSR_IV:%.*]] = phi i32 [ undef, %[[BB]] ], [ [[MY_TMP2:%.*]], %[[FLOW]] ]459; OPT-NEXT: [[LSR_IV_NEXT:%.*]] = add i32 [[LSR_IV]], 1460; OPT-NEXT: [[CMP0:%.*]] = icmp slt i32 [[LSR_IV_NEXT]], 0461; OPT-NEXT: br i1 [[CMP0]], label %[[BB4:.*]], label %[[FLOW]]462; OPT: [[BB4]]:463; OPT-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(1) poison, align 4464; OPT-NEXT: [[CMP1:%.*]] = icmp sge i32 [[MY_TMP]], [[LOAD]]465; OPT-NEXT: br label %[[FLOW]]466; OPT: [[FLOW]]:467; OPT-NEXT: [[MY_TMP2]] = phi i32 [ [[LSR_IV_NEXT]], %[[BB4]] ], [ undef, %[[BB1]] ]468; OPT-NEXT: [[MY_TMP3:%.*]] = phi i1 [ [[CMP1]], %[[BB4]] ], [ true, %[[BB1]] ]469; OPT-NEXT: [[MY_TMP3_INV:%.*]] = xor i1 [[MY_TMP3]], true470; OPT-NEXT: [[TMP0]] = call i64 @llvm.amdgcn.if.break.i64(i1 [[MY_TMP3_INV]], i64 [[PHI_BROKEN]])471; OPT-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.loop.i64(i64 [[TMP0]])472; OPT-NEXT: br i1 [[TMP1]], label %[[BB9:.*]], label %[[BB1]]473; OPT: [[BB9]]:474; OPT-NEXT: call void @llvm.amdgcn.end.cf.i64(i64 [[TMP0]])475; OPT-NEXT: store volatile i32 7, ptr addrspace(3) poison, align 4476; OPT-NEXT: ret void477;478; GCN-LABEL: invert_true_phi_cond_break_loop:479; GCN: ; %bb.0: ; %bb480; GCN-NEXT: s_load_dword s3, s[4:5], 0x9481; GCN-NEXT: s_mov_b64 s[0:1], 0482; GCN-NEXT: s_mov_b32 s2, -1483; GCN-NEXT: s_waitcnt lgkmcnt(0)484; GCN-NEXT: v_subrev_i32_e32 v0, vcc, s3, v0485; GCN-NEXT: s_mov_b32 s3, 0xf000486; GCN-NEXT: ; implicit-def: $sgpr4_sgpr5487; GCN-NEXT: ; implicit-def: $sgpr6488; GCN-NEXT: .LBB5_1: ; %bb1489; GCN-NEXT: ; =>This Inner Loop Header: Depth=1490; GCN-NEXT: s_or_b64 s[4:5], s[4:5], exec491; GCN-NEXT: s_cmp_gt_i32 s6, -1492; GCN-NEXT: s_cbranch_scc1 .LBB5_3493; GCN-NEXT: ; %bb.2: ; %bb4494; GCN-NEXT: ; in Loop: Header=BB5_1 Depth=1495; GCN-NEXT: buffer_load_dword v1, off, s[0:3], 0 glc496; GCN-NEXT: s_waitcnt vmcnt(0)497; GCN-NEXT: v_cmp_ge_i32_e32 vcc, v0, v1498; GCN-NEXT: s_andn2_b64 s[4:5], s[4:5], exec499; GCN-NEXT: s_and_b64 s[8:9], vcc, exec500; GCN-NEXT: s_or_b64 s[4:5], s[4:5], s[8:9]501; GCN-NEXT: .LBB5_3: ; %Flow502; GCN-NEXT: ; in Loop: Header=BB5_1 Depth=1503; GCN-NEXT: s_xor_b64 s[8:9], s[4:5], -1504; GCN-NEXT: s_add_i32 s6, s6, 1505; GCN-NEXT: s_and_b64 s[8:9], exec, s[8:9]506; GCN-NEXT: s_or_b64 s[0:1], s[8:9], s[0:1]507; GCN-NEXT: s_andn2_b64 exec, exec, s[0:1]508; GCN-NEXT: s_cbranch_execnz .LBB5_1509; GCN-NEXT: ; %bb.4: ; %bb9510; GCN-NEXT: s_or_b64 exec, exec, s[0:1]511; GCN-NEXT: v_mov_b32_e32 v0, 7512; GCN-NEXT: s_mov_b32 m0, -1513; GCN-NEXT: ds_write_b32 v0, v0514; GCN-NEXT: s_endpgm515bb:516 %id = call i32 @llvm.amdgcn.workitem.id.x()517 %my.tmp = sub i32 %id, %arg518 br label %bb1519 520bb1: ; preds = %Flow, %bb521 %lsr.iv = phi i32 [ undef, %bb ], [ %my.tmp2, %Flow ]522 %lsr.iv.next = add i32 %lsr.iv, 1523 %cmp0 = icmp slt i32 %lsr.iv.next, 0524 br i1 %cmp0, label %bb4, label %Flow525 526bb4: ; preds = %bb1527 %load = load volatile i32, ptr addrspace(1) poison, align 4528 %cmp1 = icmp sge i32 %my.tmp, %load529 br label %Flow530 531Flow: ; preds = %bb4, %bb1532 %my.tmp2 = phi i32 [ %lsr.iv.next, %bb4 ], [ undef, %bb1 ]533 %my.tmp3 = phi i1 [ %cmp1, %bb4 ], [ true, %bb1 ]534 br i1 %my.tmp3, label %bb1, label %bb9535 536bb9: ; preds = %Flow537 store volatile i32 7, ptr addrspace(3) poison538 ret void539}540 541declare i32 @llvm.amdgcn.workitem.id.x() #1542 543attributes #0 = { nounwind }544attributes #1 = { nounwind readnone }545