1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck %s 2 3; CHECK-LABEL: {{^}}test_kill_depth_0_imm_pos: 4; CHECK-NEXT: ; %bb.0: 5; CHECK-NEXT: ; %bb.1: 6; CHECK-NEXT: s_endpgm 7define amdgpu_ps void @test_kill_depth_0_imm_pos() #0 { 8 call void @llvm.amdgcn.kill(i1 true) 9 ret void 10} 11 12; CHECK-LABEL: {{^}}test_kill_depth_0_imm_neg: 13; CHECK-NEXT: ; %bb.0: 14; CHECK-NEXT: s_mov_b64 exec, 0 15; CHECK-NEXT: ; %bb.1: 16; CHECK-NEXT: s_endpgm 17define amdgpu_ps void @test_kill_depth_0_imm_neg() #0 { 18 call void @llvm.amdgcn.kill(i1 false) 19 ret void 20} 21 22; FIXME: Ideally only one would be emitted 23; CHECK-LABEL: {{^}}test_kill_depth_0_imm_neg_x2: 24; CHECK-NEXT: ; %bb.0: 25; CHECK-NEXT: s_mov_b64 exec, 0 26; CHECK-NEXT: ; %bb.1: 27; CHECK-NEXT: s_mov_b64 exec, 0 28; CHECK-NEXT: ; %bb.2: 29; CHECK-NEXT: s_endpgm 30define amdgpu_ps void @test_kill_depth_0_imm_neg_x2() #0 { 31 call void @llvm.amdgcn.kill(i1 false) 32 call void @llvm.amdgcn.kill(i1 false) 33 ret void 34} 35 36; CHECK-LABEL: {{^}}test_kill_depth_var: 37; CHECK-NEXT: ; %bb.0: 38; CHECK-NEXT: v_cmpx_gt_f32_e32 vcc, 0, v0 39; CHECK-NEXT: ; %bb.1: 40; CHECK-NEXT: s_endpgm 41define amdgpu_ps void @test_kill_depth_var(float %x) #0 { 42 %cmp = fcmp olt float %x, 0.0 43 call void @llvm.amdgcn.kill(i1 %cmp) 44 ret void 45} 46 47; FIXME: Ideally only one would be emitted 48; CHECK-LABEL: {{^}}test_kill_depth_var_x2_same: 49; CHECK-NEXT: ; %bb.0: 50; CHECK-NEXT: v_cmpx_gt_f32_e32 vcc, 0, v0 51; CHECK-NEXT: ; %bb.1: 52; CHECK-NEXT: v_cmpx_gt_f32_e32 vcc, 0, v0 53; CHECK-NEXT: ; %bb.2: 54; CHECK-NEXT: s_endpgm 55define amdgpu_ps void @test_kill_depth_var_x2_same(float %x) #0 { 56 %cmp = fcmp olt float %x, 0.0 57 call void @llvm.amdgcn.kill(i1 %cmp) 58 call void @llvm.amdgcn.kill(i1 %cmp) 59 ret void 60} 61 62; CHECK-LABEL: {{^}}test_kill_depth_var_x2: 63; CHECK-NEXT: ; %bb.0: 64; CHECK-NEXT: v_cmpx_gt_f32_e32 vcc, 0, v0 65; CHECK-NEXT: ; %bb.1: 66; CHECK-NEXT: v_cmpx_gt_f32_e32 vcc, 0, v1 67; CHECK-NEXT: ; %bb.2: 68; CHECK-NEXT: s_endpgm 69define amdgpu_ps void @test_kill_depth_var_x2(float %x, float %y) #0 { 70 %cmp.x = fcmp olt float %x, 0.0 71 call void @llvm.amdgcn.kill(i1 %cmp.x) 72 %cmp.y = fcmp olt float %y, 0.0 73 call void @llvm.amdgcn.kill(i1 %cmp.y) 74 ret void 75} 76 77; CHECK-LABEL: {{^}}test_kill_depth_var_x2_instructions: 78; CHECK-NEXT: ; %bb.0: 79; CHECK-NEXT: v_cmpx_gt_f32_e32 vcc, 0, v0 80; CHECK-NEXT: s_cbranch_execnz BB6_2 81; CHECK-NEXT: ; %bb.1: 82; CHECK-NEXT: exp 83; CHECK-NEXT: s_endpgm 84; CHECK-NEXT: BB6_2: 85; CHECK: v_mov_b32_e64 v7, -1 86; CHECK: v_cmpx_gt_f32_e32 vcc, 0, v7 87; CHECK-NEXT: s_cbranch_execnz BB6_4 88; CHECK-NEXT: ; %bb.3: 89; CHECK-NEXT: exp 90; CHECK-NEXT: s_endpgm 91; CHECK-NEXT: BB6_4: 92; CHECK-NEXT: s_endpgm 93define amdgpu_ps void @test_kill_depth_var_x2_instructions(float %x) #0 { 94 %cmp.x = fcmp olt float %x, 0.0 95 call void @llvm.amdgcn.kill(i1 %cmp.x) 96 %y = call float asm sideeffect "v_mov_b32_e64 v7, -1", "={v7}"() 97 %cmp.y = fcmp olt float %y, 0.0 98 call void @llvm.amdgcn.kill(i1 %cmp.y) 99 ret void 100} 101 102; FIXME: why does the skip depend on the asm length in the same block? 103 104; CHECK-LABEL: {{^}}test_kill_control_flow: 105; CHECK: s_cmp_lg_u32 s{{[0-9]+}}, 0 106; CHECK: s_cbranch_scc1 [[RETURN_BB:BB[0-9]+_[0-9]+]] 107 108; CHECK-NEXT: ; %bb.1: 109; CHECK: v_mov_b32_e64 v7, -1 110; CHECK: v_nop_e64 111; CHECK: v_nop_e64 112; CHECK: v_nop_e64 113; CHECK: v_nop_e64 114; CHECK: v_nop_e64 115; CHECK: v_nop_e64 116; CHECK: v_nop_e64 117; CHECK: v_nop_e64 118; CHECK: v_nop_e64 119; CHECK: v_nop_e64 120 121; CHECK: v_cmpx_gt_f32_e32 vcc, 0, v7 122; CHECK-NEXT: s_cbranch_execnz [[SPLIT_BB:BB[0-9]+_[0-9]+]] 123; CHECK-NEXT: ; %bb.2: 124; CHECK-NEXT: exp null off, off, off, off done vm 125; CHECK-NEXT: s_endpgm 126 127; CHECK-NEXT: {{^}}[[SPLIT_BB]]: 128; CHECK-NEXT: s_endpgm 129define amdgpu_ps void @test_kill_control_flow(i32 inreg %arg) #0 { 130entry: 131 %cmp = icmp eq i32 %arg, 0 132 br i1 %cmp, label %bb, label %exit 133 134bb: 135 %var = call float asm sideeffect " 136 v_mov_b32_e64 v7, -1 137 v_nop_e64 138 v_nop_e64 139 v_nop_e64 140 v_nop_e64 141 v_nop_e64 142 v_nop_e64 143 v_nop_e64 144 v_nop_e64 145 v_nop_e64 146 v_nop_e64", "={v7}"() 147 %cmp.var = fcmp olt float %var, 0.0 148 call void @llvm.amdgcn.kill(i1 %cmp.var) 149 br label %exit 150 151exit: 152 ret void 153} 154 155; CHECK-LABEL: {{^}}test_kill_control_flow_remainder: 156; CHECK: s_cmp_lg_u32 s{{[0-9]+}}, 0 157; CHECK-NEXT: v_mov_b32_e32 v{{[0-9]+}}, 0 158; CHECK-NEXT: s_cbranch_scc1 [[RETURN_BB:BB[0-9]+_[0-9]+]] 159 160; CHECK-NEXT: ; %bb.1: ; %bb 161; CHECK: v_mov_b32_e64 v7, -1 162; CHECK: v_nop_e64 163; CHECK: v_nop_e64 164; CHECK: v_nop_e64 165; CHECK: v_nop_e64 166; CHECK: v_nop_e64 167; CHECK: v_nop_e64 168; CHECK: v_nop_e64 169; CHECK: v_nop_e64 170; CHECK: ;;#ASMEND 171; CHECK: v_mov_b32_e64 v8, -1 172; CHECK: ;;#ASMEND 173; CHECK: v_cmpx_gt_f32_e32 vcc, 0, v7 174; CHECK-NEXT: s_cbranch_execnz [[SPLIT_BB:BB[0-9]+_[0-9]+]] 175 176; CHECK-NEXT: ; %bb.2: 177; CHECK-NEXT: exp null off, off, off, off done vm 178; CHECK-NEXT: s_endpgm 179 180; CHECK-NEXT: {{^}}[[SPLIT_BB]]: 181; CHECK: buffer_store_dword v8 182; CHECK: v_mov_b32_e64 v9, -2 183 184; CHECK: {{^}}BB{{[0-9]+_[0-9]+}}: 185; CHECK: buffer_store_dword v9 186; CHECK-NEXT: s_endpgm 187define amdgpu_ps void @test_kill_control_flow_remainder(i32 inreg %arg) #0 { 188entry: 189 %cmp = icmp eq i32 %arg, 0 190 br i1 %cmp, label %bb, label %exit 191 192bb: 193 %var = call float asm sideeffect " 194 v_mov_b32_e64 v7, -1 195 v_nop_e64 196 v_nop_e64 197 v_nop_e64 198 v_nop_e64 199 v_nop_e64 200 v_nop_e64 201 v_nop_e64 202 v_nop_e64 203 v_nop_e64 204 v_nop_e64 205 v_nop_e64", "={v7}"() 206 %live.across = call float asm sideeffect "v_mov_b32_e64 v8, -1", "={v8}"() 207 %cmp.var = fcmp olt float %var, 0.0 208 call void @llvm.amdgcn.kill(i1 %cmp.var) 209 store volatile float %live.across, float addrspace(1)* undef 210 %live.out = call float asm sideeffect "v_mov_b32_e64 v9, -2", "={v9}"() 211 br label %exit 212 213exit: 214 %phi = phi float [ 0.0, %entry ], [ %live.out, %bb ] 215 store float %phi, float addrspace(1)* undef 216 ret void 217} 218 219; CHECK-LABEL: {{^}}test_kill_divergent_loop: 220; CHECK: v_cmp_eq_u32_e32 vcc, 0, v0 221; CHECK-NEXT: s_and_saveexec_b64 [[SAVEEXEC:s\[[0-9]+:[0-9]+\]]], vcc 222; CHECK-NEXT: s_xor_b64 [[SAVEEXEC]], exec, [[SAVEEXEC]] 223; CHECK-NEXT: ; mask branch [[EXIT:BB[0-9]+_[0-9]+]] 224; CHECK-NEXT: s_cbranch_execz [[EXIT]] 225 226; CHECK: {{BB[0-9]+_[0-9]+}}: ; %bb.preheader 227; CHECK: s_mov_b32 228 229; CHECK: [[LOOP_BB:BB[0-9]+_[0-9]+]]: 230 231; CHECK: v_mov_b32_e64 v7, -1 232; CHECK: v_nop_e64 233; CHECK: v_cmpx_gt_f32_e32 vcc, 0, v7 234 235; CHECK-NEXT: ; %bb.3: 236; CHECK: buffer_load_dword [[LOAD:v[0-9]+]] 237; CHECK: v_cmp_eq_u32_e32 vcc, 0, [[LOAD]] 238; CHECK-NEXT: s_and_b64 vcc, exec, vcc 239; CHECK-NEXT: s_cbranch_vccnz [[LOOP_BB]] 240 241; CHECK-NEXT: {{^}}[[EXIT]]: 242; CHECK: s_or_b64 exec, exec, [[SAVEEXEC]] 243; CHECK: buffer_store_dword 244; CHECK: s_endpgm 245define amdgpu_ps void @test_kill_divergent_loop(i32 %arg) #0 { 246entry: 247 %cmp = icmp eq i32 %arg, 0 248 br i1 %cmp, label %bb, label %exit 249 250bb: 251 %var = call float asm sideeffect " 252 v_mov_b32_e64 v7, -1 253 v_nop_e64 254 v_nop_e64 255 v_nop_e64 256 v_nop_e64 257 v_nop_e64 258 v_nop_e64 259 v_nop_e64 260 v_nop_e64 261 v_nop_e64 262 v_nop_e64", "={v7}"() 263 %cmp.var = fcmp olt float %var, 0.0 264 call void @llvm.amdgcn.kill(i1 %cmp.var) 265 %vgpr = load volatile i32, i32 addrspace(1)* undef 266 %loop.cond = icmp eq i32 %vgpr, 0 267 br i1 %loop.cond, label %bb, label %exit 268 269exit: 270 store volatile i32 8, i32 addrspace(1)* undef 271 ret void 272} 273 274; bug 28550 275; CHECK-LABEL: {{^}}phi_use_def_before_kill: 276; CHECK: v_cndmask_b32_e64 [[PHIREG:v[0-9]+]], 0, -1.0, 277; CHECK: v_cmpx_lt_f32_e32 vcc, 0, 278; CHECK-NEXT: s_cbranch_execnz [[BB4:BB[0-9]+_[0-9]+]] 279 280; CHECK: exp 281; CHECK-NEXT: s_endpgm 282 283; CHECK: [[KILLBB:BB[0-9]+_[0-9]+]]: 284; CHECK-NEXT: s_cbranch_scc0 [[PHIBB:BB[0-9]+_[0-9]+]] 285 286; CHECK: [[PHIBB]]: 287; CHECK: v_cmp_eq_f32_e32 vcc, 0, [[PHIREG]] 288; CHECK: s_cbranch_vccz [[ENDBB:BB[0-9]+_[0-9]+]] 289 290; CHECK: ; %bb10 291; CHECK: v_mov_b32_e32 v{{[0-9]+}}, 9 292; CHECK: buffer_store_dword 293 294; CHECK: [[ENDBB]]: 295; CHECK-NEXT: s_endpgm 296define amdgpu_ps void @phi_use_def_before_kill(float inreg %x) #0 { 297bb: 298 %tmp = fadd float %x, 1.000000e+00 299 %tmp1 = fcmp olt float 0.000000e+00, %tmp 300 %tmp2 = select i1 %tmp1, float -1.000000e+00, float 0.000000e+00 301 %cmp.tmp2 = fcmp olt float %tmp2, 0.0 302 call void @llvm.amdgcn.kill(i1 %cmp.tmp2) 303 br i1 undef, label %phibb, label %bb8 304 305phibb: 306 %tmp5 = phi float [ %tmp2, %bb ], [ 4.0, %bb8 ] 307 %tmp6 = fcmp oeq float %tmp5, 0.000000e+00 308 br i1 %tmp6, label %bb10, label %end 309 310bb8: 311 store volatile i32 8, i32 addrspace(1)* undef 312 br label %phibb 313 314bb10: 315 store volatile i32 9, i32 addrspace(1)* undef 316 br label %end 317 318end: 319 ret void 320} 321 322; CHECK-LABEL: {{^}}no_skip_no_successors: 323; CHECK: v_cmp_nge_f32 324; CHECK: s_cbranch_vccz [[SKIPKILL:BB[0-9]+_[0-9]+]] 325 326; CHECK: ; %bb6 327; CHECK: s_mov_b64 exec, 0 328 329; CHECK: [[SKIPKILL]]: 330; CHECK: v_cmp_nge_f32_e32 vcc 331; CHECK: %bb.3: ; %bb5 332; CHECK-NEXT: .Lfunc_end{{[0-9]+}} 333define amdgpu_ps void @no_skip_no_successors(float inreg %arg, float inreg %arg1) #0 { 334bb: 335 %tmp = fcmp ult float %arg1, 0.000000e+00 336 %tmp2 = fcmp ult float %arg, 0x3FCF5C2900000000 337 br i1 %tmp, label %bb6, label %bb3 338 339bb3: ; preds = %bb 340 br i1 %tmp2, label %bb5, label %bb4 341 342bb4: ; preds = %bb3 343 br i1 true, label %bb5, label %bb7 344 345bb5: ; preds = %bb4, %bb3 346 unreachable 347 348bb6: ; preds = %bb 349 call void @llvm.amdgcn.kill(i1 false) 350 unreachable 351 352bb7: ; preds = %bb4 353 ret void 354} 355 356; CHECK-LABEL: {{^}}if_after_kill_block: 357; CHECK: ; %bb.0: 358; CHECK: s_and_saveexec_b64 359; CHECK: s_xor_b64 360; CHECK-NEXT: mask branch [[BB4:BB[0-9]+_[0-9]+]] 361 362; CHECK: v_cmpx_gt_f32_e32 vcc, 0, 363; CHECK: [[BB4]]: 364; CHECK: s_or_b64 exec, exec 365; CHECK: image_sample_c 366 367; CHECK: v_cmp_neq_f32_e32 vcc, 0, 368; CHECK: s_and_saveexec_b64 s{{\[[0-9]+:[0-9]+\]}}, vcc 369; CHECK: mask branch [[END:BB[0-9]+_[0-9]+]] 370; CHECK-NOT: branch 371 372; CHECK: BB{{[0-9]+_[0-9]+}}: ; %bb8 373; CHECK: buffer_store_dword 374 375; CHECK: [[END]]: 376; CHECK: s_endpgm 377define amdgpu_ps void @if_after_kill_block(float %arg, float %arg1, float %arg2, float %arg3) #0 { 378bb: 379 %tmp = fcmp ult float %arg1, 0.000000e+00 380 br i1 %tmp, label %bb3, label %bb4 381 382bb3: ; preds = %bb 383 %cmp.arg = fcmp olt float %arg, 0.0 384 call void @llvm.amdgcn.kill(i1 %cmp.arg) 385 br label %bb4 386 387bb4: ; preds = %bb3, %bb 388 %tmp5 = call <4 x float> @llvm.amdgcn.image.sample.c.1d.v4f32.f32(i32 16, float %arg2, float %arg3, <8 x i32> undef, <4 x i32> undef, i1 0, i32 0, i32 0) 389 %tmp6 = extractelement <4 x float> %tmp5, i32 0 390 %tmp7 = fcmp une float %tmp6, 0.000000e+00 391 br i1 %tmp7, label %bb8, label %bb9 392 393bb8: ; preds = %bb9, %bb4 394 store volatile i32 9, i32 addrspace(1)* undef 395 ret void 396 397bb9: ; preds = %bb4 398 ret void 399} 400 401declare <4 x float> @llvm.amdgcn.image.sample.c.1d.v4f32.f32(i32, float, float, <8 x i32>, <4 x i32>, i1, i32, i32) #1 402declare void @llvm.amdgcn.kill(i1) #0 403 404attributes #0 = { nounwind } 405attributes #1 = { nounwind readonly } 406