201 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2 3; NOTE: The checks for opt are NOT added by the update script. Those4; checks are looking for the absence of specific metadata, which5; cannot be expressed reliably by the generated checks.6 7; RUN: llc -mtriple=amdgcn -mcpu=gfx900 < %s | FileCheck %s -check-prefix=ISA8; RUN: opt --amdgpu-annotate-uniform -S %s | FileCheck %s -check-prefix=UNIFORM9; RUN: opt --amdgpu-annotate-uniform --si-annotate-control-flow -S %s | FileCheck %s -check-prefix=CONTROLFLOW10 11; This module creates a divergent branch in block Flow2. The branch is12; marked as divergent by the divergence analysis but the condition is13; not. This test ensures that the divergence of the branch is tested,14; not its condition, so that branch is correctly emitted as divergent.15 16target triple = "amdgcn-mesa-mesa3d"17 18define amdgpu_ps void @main(i32 %0, float %1) {19; ISA-LABEL: main:20; ISA: ; %bb.0: ; %start21; ISA-NEXT: v_readfirstlane_b32 s0, v022; ISA-NEXT: s_mov_b32 m0, s023; ISA-NEXT: s_mov_b32 s8, 024; ISA-NEXT: v_interp_p1_f32_e32 v0, v1, attr0.x25; ISA-NEXT: v_cmp_nlt_f32_e32 vcc, 0, v026; ISA-NEXT: s_mov_b64 s[0:1], 027; ISA-NEXT: ; implicit-def: $sgpr4_sgpr528; ISA-NEXT: ; implicit-def: $sgpr2_sgpr329; ISA-NEXT: s_branch .LBB0_330; ISA-NEXT: .LBB0_1: ; %Flow131; ISA-NEXT: ; in Loop: Header=BB0_3 Depth=132; ISA-NEXT: s_or_b64 exec, exec, s[4:5]33; ISA-NEXT: s_mov_b64 s[4:5], s[6:7]34; ISA-NEXT: s_mov_b64 s[6:7], 035; ISA-NEXT: .LBB0_2: ; %Flow36; ISA-NEXT: ; in Loop: Header=BB0_3 Depth=137; ISA-NEXT: s_and_b64 s[10:11], exec, s[4:5]38; ISA-NEXT: s_or_b64 s[0:1], s[10:11], s[0:1]39; ISA-NEXT: s_andn2_b64 s[2:3], s[2:3], exec40; ISA-NEXT: s_and_b64 s[6:7], s[6:7], exec41; ISA-NEXT: s_or_b64 s[2:3], s[2:3], s[6:7]42; ISA-NEXT: s_andn2_b64 exec, exec, s[0:1]43; ISA-NEXT: s_cbranch_execz .LBB0_744; ISA-NEXT: .LBB0_3: ; %loop45; ISA-NEXT: ; =>This Inner Loop Header: Depth=146; ISA-NEXT: s_or_b64 s[4:5], s[4:5], exec47; ISA-NEXT: s_cmp_lt_u32 s8, 3248; ISA-NEXT: s_mov_b64 s[6:7], -149; ISA-NEXT: s_cbranch_scc0 .LBB0_650; ISA-NEXT: ; %bb.4: ; %endif151; ISA-NEXT: ; in Loop: Header=BB0_3 Depth=152; ISA-NEXT: s_and_saveexec_b64 s[4:5], vcc53; ISA-NEXT: s_cbranch_execz .LBB0_154; ISA-NEXT: ; %bb.5: ; %endif255; ISA-NEXT: ; in Loop: Header=BB0_3 Depth=156; ISA-NEXT: s_add_i32 s8, s8, 157; ISA-NEXT: s_xor_b64 s[6:7], exec, -158; ISA-NEXT: s_branch .LBB0_159; ISA-NEXT: .LBB0_6: ; in Loop: Header=BB0_3 Depth=160; ISA-NEXT: ; implicit-def: $sgpr861; ISA-NEXT: s_branch .LBB0_262; ISA-NEXT: .LBB0_7: ; %Flow263; ISA-NEXT: s_or_b64 exec, exec, s[0:1]64; ISA-NEXT: v_mov_b32_e32 v1, 065; ISA-NEXT: s_and_saveexec_b64 s[0:1], s[2:3]66; ISA-NEXT: ; %bb.8: ; %if167; ISA-NEXT: v_sqrt_f32_e32 v1, v068; ISA-NEXT: ; %bb.9: ; %endloop69; ISA-NEXT: s_or_b64 exec, exec, s[0:1]70; ISA-NEXT: exp mrt0 v1, v1, v1, v1 done vm71; ISA-NEXT: s_endpgm72start:73 %v0 = call float @llvm.amdgcn.interp.p1(float %1, i32 0, i32 0, i32 %0)74 br label %loop75 76loop: ; preds = %Flow, %start77 %v1 = phi i32 [ 0, %start ], [ %6, %Flow ]78 %v2 = icmp ugt i32 %v1, 3179 %2 = xor i1 %v2, true80 br i1 %2, label %endif1, label %Flow81 82Flow1: ; preds = %endif2, %endif183 %3 = phi i32 [ %v5, %endif2 ], [ poison, %endif1 ]84 %4 = phi i1 [ false, %endif2 ], [ true, %endif1 ]85 br label %Flow86 87; UNIFORM-LABEL: Flow2:88; UNIFORM-NEXT: br i1 %8, label %if1, label %endloop89; UNIFORM-NOT: !amdgpu.uniform90; UNIFORM: if1:91 92; CONTROLFLOW-LABEL: Flow2:93; CONTROLFLOW-NEXT: call void @llvm.amdgcn.end.cf.i64(i64 %{{.*}})94; CONTROLFLOW-NEXT: [[IF:%.*]] = call { i1, i64 } @llvm.amdgcn.if.i64(i1 %{{.*}})95; CONTROLFLOW-NEXT: [[COND:%.*]] = extractvalue { i1, i64 } [[IF]], 096; CONTROLFLOW-NEXT: %{{.*}} = extractvalue { i1, i64 } [[IF]], 197; CONTROLFLOW-NEXT: br i1 [[COND]], label %if1, label %endloop98 99Flow2: ; preds = %Flow100 br i1 %8, label %if1, label %endloop101 102if1: ; preds = %Flow2103 %v3 = call afn float @llvm.sqrt.f32(float %v0)104 br label %endloop105 106endif1: ; preds = %loop107 %v4 = fcmp ogt float %v0, 0.000000e+00108 %5 = xor i1 %v4, true109 br i1 %5, label %endif2, label %Flow1110 111Flow: ; preds = %Flow1, %loop112 %6 = phi i32 [ %3, %Flow1 ], [ poison, %loop ]113 %7 = phi i1 [ %4, %Flow1 ], [ true, %loop ]114 %8 = phi i1 [ false, %Flow1 ], [ true, %loop ]115 br i1 %7, label %Flow2, label %loop116 117endif2: ; preds = %endif1118 %v5 = add i32 %v1, 1119 br label %Flow1120 121endloop: ; preds = %if1, %Flow2122 %v6 = phi float [ 0.000000e+00, %Flow2 ], [ %v3, %if1 ]123 call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %v6, float %v6, float %v6, float %v6, i1 true, i1 true)124 ret void125}126 127define amdgpu_ps void @i1_copy_assert(i1 %v4) {128; ISA-LABEL: i1_copy_assert:129; ISA: ; %bb.0: ; %start130; ISA-NEXT: v_and_b32_e32 v0, 1, v0131; ISA-NEXT: v_cmp_eq_u32_e32 vcc, 1, v0132; ISA-NEXT: s_mov_b32 s8, 0133; ISA-NEXT: s_mov_b64 s[0:1], 0134; ISA-NEXT: ; implicit-def: $sgpr4_sgpr5135; ISA-NEXT: ; implicit-def: $sgpr2_sgpr3136; ISA-NEXT: s_branch .LBB1_3137; ISA-NEXT: .LBB1_1: ; %endif1138; ISA-NEXT: ; in Loop: Header=BB1_3 Depth=1139; ISA-NEXT: s_andn2_b64 s[4:5], s[4:5], exec140; ISA-NEXT: s_and_b64 s[8:9], vcc, exec141; ISA-NEXT: s_mov_b64 s[6:7], 0142; ISA-NEXT: s_or_b64 s[4:5], s[4:5], s[8:9]143; ISA-NEXT: .LBB1_2: ; %Flow144; ISA-NEXT: ; in Loop: Header=BB1_3 Depth=1145; ISA-NEXT: s_and_b64 s[8:9], exec, s[4:5]146; ISA-NEXT: s_or_b64 s[0:1], s[8:9], s[0:1]147; ISA-NEXT: s_andn2_b64 s[2:3], s[2:3], exec148; ISA-NEXT: s_and_b64 s[6:7], s[6:7], exec149; ISA-NEXT: s_mov_b32 s8, 1150; ISA-NEXT: s_or_b64 s[2:3], s[2:3], s[6:7]151; ISA-NEXT: s_andn2_b64 exec, exec, s[0:1]152; ISA-NEXT: s_cbranch_execz .LBB1_5153; ISA-NEXT: .LBB1_3: ; %loop154; ISA-NEXT: ; =>This Inner Loop Header: Depth=1155; ISA-NEXT: s_or_b64 s[4:5], s[4:5], exec156; ISA-NEXT: s_cmp_lg_u32 s8, 0157; ISA-NEXT: s_cbranch_scc1 .LBB1_1158; ISA-NEXT: ; %bb.4: ; in Loop: Header=BB1_3 Depth=1159; ISA-NEXT: s_mov_b64 s[6:7], -1160; ISA-NEXT: s_branch .LBB1_2161; ISA-NEXT: .LBB1_5: ; %Flow2162; ISA-NEXT: s_or_b64 exec, exec, s[0:1]163; ISA-NEXT: v_mov_b32_e32 v0, 0164; ISA-NEXT: v_cndmask_b32_e64 v1, 0, 1.0, s[2:3]165; ISA-NEXT: exp mrt0 off, off, off, off166; ISA-NEXT: s_endpgm167start:168 br label %loop169 170loop: ; preds = %Flow, %start171 %v1 = phi i32 [ 0, %start ], [ 1, %Flow ]172 %v2 = icmp ugt i32 %v1, 0173 br i1 %v2, label %endif1, label %Flow174 175Flow2: ; preds = %Flow176 %spec.select = select i1 %i1, float 1.000000e+00, float 0.000000e+00177 call void @llvm.amdgcn.exp.f32(i32 0, i32 0, float %spec.select, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, i1 false, i1 false)178 ret void179 180endif1: ; preds = %loop181 br label %Flow182 183Flow: ; preds = %endif1, %loop184 %i = phi i1 [ %v4, %endif1 ], [ true, %loop ]185 %i1 = phi i1 [ false, %endif1 ], [ true, %loop ]186 br i1 %i, label %Flow2, label %loop187}188 189; Function Attrs: nounwind readnone speculatable willreturn190declare float @llvm.sqrt.f32(float) #0191 192; Function Attrs: nounwind readnone speculatable193declare float @llvm.amdgcn.interp.p1(float, i32 immarg, i32 immarg, i32) #1194 195; Function Attrs: inaccessiblememonly nounwind writeonly196declare void @llvm.amdgcn.exp.f32(i32 immarg, i32 immarg, float, float, float, float, i1 immarg, i1 immarg) #2197 198attributes #0 = { nounwind readnone speculatable willreturn }199attributes #1 = { nounwind readnone speculatable }200attributes #2 = { inaccessiblememonly nounwind writeonly }201