| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: llc -O1 -mtriple=amdgpu9.0a-amd-amdhsa < %s | FileCheck %s |
| |
| define void @sgpr_scavenge_fi_stack_id(double %input, i1 %enter_fma_path, i1 %repeat_outer_loop, i1 %enter_sgpr_loop, i1 %enter_inner_loop, i1 %exit_inner_loop, i1 %zero_fma_result) { |
| ; CHECK-LABEL: sgpr_scavenge_fi_stack_id: |
| ; CHECK: ; %bb.0: ; %entry |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_xor_saveexec_b64 s[4:5], -1 |
| ; CHECK-NEXT: buffer_store_dword v10, off, s[0:3], s32 offset:4 ; 4-byte Folded Spill |
| ; CHECK-NEXT: s_mov_b64 exec, s[4:5] |
| ; CHECK-NEXT: v_writelane_b32 v10, s30, 0 |
| ; CHECK-NEXT: v_writelane_b32 v10, s31, 1 |
| ; CHECK-NEXT: v_and_b32_e32 v2, 1, v2 |
| ; CHECK-NEXT: v_cmp_eq_u32_e64 s[10:11], 1, v2 |
| ; CHECK-NEXT: v_and_b32_e32 v2, 1, v4 |
| ; CHECK-NEXT: v_cmp_eq_u32_e64 s[12:13], 1, v2 |
| ; CHECK-NEXT: v_and_b32_e32 v2, 1, v3 |
| ; CHECK-NEXT: v_and_b32_e32 v7, 1, v7 |
| ; CHECK-NEXT: v_and_b32_e32 v6, 1, v6 |
| ; CHECK-NEXT: v_and_b32_e32 v5, 1, v5 |
| ; CHECK-NEXT: v_cmp_eq_u32_e64 s[14:15], 1, v2 |
| ; CHECK-NEXT: v_cmp_eq_u32_e64 s[4:5], 1, v7 |
| ; CHECK-NEXT: v_cmp_eq_u32_e64 s[6:7], 1, v6 |
| ; CHECK-NEXT: v_cmp_eq_u32_e64 s[8:9], 1, v5 |
| ; CHECK-NEXT: s_xor_b64 s[16:17], s[14:15], -1 |
| ; CHECK-NEXT: s_xor_b64 s[18:19], s[12:13], -1 |
| ; CHECK-NEXT: s_xor_b64 s[22:23], s[10:11], -1 |
| ; CHECK-NEXT: s_mov_b64 s[20:21], 0 |
| ; CHECK-NEXT: s_mov_b32 s25, 0x3fe62e42 |
| ; CHECK-NEXT: s_mov_b32 s24, 0xfefa39ef |
| ; CHECK-NEXT: s_mov_b32 s27, 0x3c7abc9e |
| ; CHECK-NEXT: s_mov_b32 s26, 0x3b39803f |
| ; CHECK-NEXT: v_mov_b32_e32 v6, 0 |
| ; CHECK-NEXT: s_mov_b32 s28, 0 |
| ; CHECK-NEXT: s_mov_b32 s29, 0x7ff00000 |
| ; CHECK-NEXT: s_mov_b32 s41, 0x40417e50 |
| ; CHECK-NEXT: s_mov_b32 s40, 0xa9dc6553 |
| ; CHECK-NEXT: s_mov_b32 s42, 0 |
| ; CHECK-NEXT: s_mov_b32 s43, 0x7ff80000 |
| ; CHECK-NEXT: s_branch .LBB0_2 |
| ; CHECK-NEXT: .LBB0_1: ; %loop.exit.guard |
| ; CHECK-NEXT: ; in Loop: Header=BB0_2 Depth=1 |
| ; CHECK-NEXT: s_or_b64 exec, exec, s[46:47] |
| ; CHECK-NEXT: s_and_b64 s[44:45], exec, s[44:45] |
| ; CHECK-NEXT: s_or_b64 s[20:21], s[44:45], s[20:21] |
| ; CHECK-NEXT: s_andn2_b64 exec, exec, s[20:21] |
| ; CHECK-NEXT: s_cbranch_execz .LBB0_21 |
| ; CHECK-NEXT: .LBB0_2: ; %outer_latch |
| ; CHECK-NEXT: ; =>This Loop Header: Depth=1 |
| ; CHECK-NEXT: ; Child Loop BB0_4 Depth 2 |
| ; CHECK-NEXT: ; Child Loop BB0_8 Depth 3 |
| ; CHECK-NEXT: ; Child Loop BB0_11 Depth 4 |
| ; CHECK-NEXT: ; Child Loop BB0_13 Depth 5 |
| ; CHECK-NEXT: s_mov_b64 s[46:47], 0 |
| ; CHECK-NEXT: ; implicit-def: $sgpr44_sgpr45 |
| ; CHECK-NEXT: ; implicit-def: $sgpr56_sgpr57 |
| ; CHECK-NEXT: s_branch .LBB0_4 |
| ; CHECK-NEXT: .LBB0_3: ; %Flow11 |
| ; CHECK-NEXT: ; in Loop: Header=BB0_4 Depth=2 |
| ; CHECK-NEXT: s_or_b64 exec, exec, s[60:61] |
| ; CHECK-NEXT: s_and_b64 s[58:59], exec, s[58:59] |
| ; CHECK-NEXT: s_or_b64 s[46:47], s[58:59], s[46:47] |
| ; CHECK-NEXT: s_andn2_b64 s[44:45], s[44:45], exec |
| ; CHECK-NEXT: s_and_b64 s[58:59], s[56:57], exec |
| ; CHECK-NEXT: s_or_b64 s[44:45], s[44:45], s[58:59] |
| ; CHECK-NEXT: s_andn2_b64 exec, exec, s[46:47] |
| ; CHECK-NEXT: s_cbranch_execz .LBB0_1 |
| ; CHECK-NEXT: .LBB0_4: ; %outer_header |
| ; CHECK-NEXT: ; Parent Loop BB0_2 Depth=1 |
| ; CHECK-NEXT: ; => This Loop Header: Depth=2 |
| ; CHECK-NEXT: ; Child Loop BB0_8 Depth 3 |
| ; CHECK-NEXT: ; Child Loop BB0_11 Depth 4 |
| ; CHECK-NEXT: ; Child Loop BB0_13 Depth 5 |
| ; CHECK-NEXT: s_mov_b64 s[58:59], -1 |
| ; CHECK-NEXT: s_mov_b64 s[62:63], -1 |
| ; CHECK-NEXT: s_and_saveexec_b64 s[60:61], s[10:11] |
| ; CHECK-NEXT: s_cbranch_execz .LBB0_19 |
| ; CHECK-NEXT: ; %bb.5: ; %fma_setup |
| ; CHECK-NEXT: ; in Loop: Header=BB0_4 Depth=2 |
| ; CHECK-NEXT: v_fma_f64 v[2:3], v[0:1], s[24:25], 0 |
| ; CHECK-NEXT: v_fmac_f64_e64 v[2:3], 0, s[26:27] |
| ; CHECK-NEXT: s_mov_b64 s[62:63], 0 |
| ; CHECK-NEXT: ; implicit-def: $sgpr72_sgpr73 |
| ; CHECK-NEXT: ; implicit-def: $sgpr74_sgpr75 |
| ; CHECK-NEXT: ; implicit-def: $sgpr76_sgpr77 |
| ; CHECK-NEXT: s_branch .LBB0_8 |
| ; CHECK-NEXT: .LBB0_6: ; %Flow9 |
| ; CHECK-NEXT: ; in Loop: Header=BB0_8 Depth=3 |
| ; CHECK-NEXT: s_or_b64 exec, exec, s[88:89] |
| ; CHECK-NEXT: s_andn2_b64 s[76:77], s[76:77], exec |
| ; CHECK-NEXT: s_and_b64 s[88:89], s[92:93], exec |
| ; CHECK-NEXT: s_or_b64 s[76:77], s[76:77], s[88:89] |
| ; CHECK-NEXT: s_andn2_b64 s[74:75], s[74:75], exec |
| ; CHECK-NEXT: s_and_b64 s[88:89], s[90:91], exec |
| ; CHECK-NEXT: s_or_b64 s[74:75], s[74:75], s[88:89] |
| ; CHECK-NEXT: .LBB0_7: ; %Flow8 |
| ; CHECK-NEXT: ; in Loop: Header=BB0_8 Depth=3 |
| ; CHECK-NEXT: s_or_b64 exec, exec, s[78:79] |
| ; CHECK-NEXT: s_and_b64 s[78:79], exec, s[74:75] |
| ; CHECK-NEXT: s_or_b64 s[62:63], s[78:79], s[62:63] |
| ; CHECK-NEXT: s_andn2_b64 s[72:73], s[72:73], exec |
| ; CHECK-NEXT: s_and_b64 s[78:79], s[76:77], exec |
| ; CHECK-NEXT: s_or_b64 s[72:73], s[72:73], s[78:79] |
| ; CHECK-NEXT: s_andn2_b64 exec, exec, s[62:63] |
| ; CHECK-NEXT: s_cbranch_execz .LBB0_18 |
| ; CHECK-NEXT: .LBB0_8: ; %sgpr_loop_header |
| ; CHECK-NEXT: ; Parent Loop BB0_2 Depth=1 |
| ; CHECK-NEXT: ; Parent Loop BB0_4 Depth=2 |
| ; CHECK-NEXT: ; => This Loop Header: Depth=3 |
| ; CHECK-NEXT: ; Child Loop BB0_11 Depth 4 |
| ; CHECK-NEXT: ; Child Loop BB0_13 Depth 5 |
| ; CHECK-NEXT: s_or_b64 s[76:77], s[76:77], exec |
| ; CHECK-NEXT: s_or_b64 s[74:75], s[74:75], exec |
| ; CHECK-NEXT: s_and_saveexec_b64 s[78:79], s[12:13] |
| ; CHECK-NEXT: s_cbranch_execz .LBB0_7 |
| ; CHECK-NEXT: ; %bb.9: ; %sgpr_pressure_loop.preheader |
| ; CHECK-NEXT: ; in Loop: Header=BB0_8 Depth=3 |
| ; CHECK-NEXT: s_mov_b64 s[90:91], 0 |
| ; CHECK-NEXT: ; implicit-def: $sgpr88_sgpr89 |
| ; CHECK-NEXT: s_branch .LBB0_11 |
| ; CHECK-NEXT: .LBB0_10: ; %Flow7 |
| ; CHECK-NEXT: ; in Loop: Header=BB0_11 Depth=4 |
| ; CHECK-NEXT: s_xor_b64 s[94:95], s[94:95], -1 |
| ; CHECK-NEXT: s_and_b64 s[92:93], exec, s[92:93] |
| ; CHECK-NEXT: s_or_b64 s[90:91], s[92:93], s[90:91] |
| ; CHECK-NEXT: s_andn2_b64 s[88:89], s[88:89], exec |
| ; CHECK-NEXT: s_and_b64 s[92:93], s[94:95], exec |
| ; CHECK-NEXT: s_or_b64 s[88:89], s[88:89], s[92:93] |
| ; CHECK-NEXT: s_andn2_b64 exec, exec, s[90:91] |
| ; CHECK-NEXT: s_cbranch_execz .LBB0_16 |
| ; CHECK-NEXT: .LBB0_11: ; %sgpr_pressure_loop |
| ; CHECK-NEXT: ; Parent Loop BB0_2 Depth=1 |
| ; CHECK-NEXT: ; Parent Loop BB0_4 Depth=2 |
| ; CHECK-NEXT: ; Parent Loop BB0_8 Depth=3 |
| ; CHECK-NEXT: ; => This Loop Header: Depth=4 |
| ; CHECK-NEXT: ; Child Loop BB0_13 Depth 5 |
| ; CHECK-NEXT: s_and_saveexec_b64 s[92:93], s[8:9] |
| ; CHECK-NEXT: s_cbranch_execz .LBB0_14 |
| ; CHECK-NEXT: ; %bb.12: ; %inner_stack_loop.preheader |
| ; CHECK-NEXT: ; in Loop: Header=BB0_11 Depth=4 |
| ; CHECK-NEXT: v_cndmask_b32_e64 v5, v3, 0, s[4:5] |
| ; CHECK-NEXT: v_cndmask_b32_e64 v4, v2, 0, s[4:5] |
| ; CHECK-NEXT: v_cndmask_b32_e64 v5, v5, 0, s[14:15] |
| ; CHECK-NEXT: v_cndmask_b32_e64 v4, v4, 0, s[14:15] |
| ; CHECK-NEXT: v_mul_f64 v[4:5], v[4:5], s[28:29] |
| ; CHECK-NEXT: v_mul_f64 v[4:5], v[4:5], s[40:41] |
| ; CHECK-NEXT: s_mov_b32 vcc_lo, 0 |
| ; CHECK-NEXT: s_mov_b64 s[94:95], 0 |
| ; CHECK-NEXT: v_mul_f64 v[4:5], v[4:5], s[42:43] |
| ; CHECK-NEXT: .LBB0_13: ; %inner_stack_loop |
| ; CHECK-NEXT: ; Parent Loop BB0_2 Depth=1 |
| ; CHECK-NEXT: ; Parent Loop BB0_4 Depth=2 |
| ; CHECK-NEXT: ; Parent Loop BB0_8 Depth=3 |
| ; CHECK-NEXT: ; Parent Loop BB0_11 Depth=4 |
| ; CHECK-NEXT: ; => This Inner Loop Header: Depth=5 |
| ; CHECK-NEXT: s_and_b64 s[30:31], exec, s[6:7] |
| ; CHECK-NEXT: s_or_b64 s[94:95], s[30:31], s[94:95] |
| ; CHECK-NEXT: s_not_b64 exec, exec |
| ; CHECK-NEXT: buffer_store_dword v7, off, s[0:3], s32 offset:8 |
| ; CHECK-NEXT: v_writelane_b32 v7, s4, 0 |
| ; CHECK-NEXT: buffer_store_dword v7, off, s[0:3], s32 offset:8 |
| ; CHECK-NEXT: s_not_b64 exec, exec |
| ; CHECK-NEXT: buffer_store_dword v7, off, s[0:3], s32 offset:8 |
| ; CHECK-NEXT: s_not_b64 exec, exec |
| ; CHECK-NEXT: buffer_load_dword v7, off, s[0:3], s32 offset:8 |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) |
| ; CHECK-NEXT: s_not_b64 exec, exec |
| ; CHECK-NEXT: s_lshr_b32 s4, s32, 6 |
| ; CHECK-NEXT: s_lshl3_add_u32 vcc_hi, vcc_lo, s4 |
| ; CHECK-NEXT: s_not_b64 exec, exec |
| ; CHECK-NEXT: buffer_store_dword v8, off, s[0:3], s32 offset:8 |
| ; CHECK-NEXT: buffer_load_dword v8, off, s[0:3], s32 offset:8 |
| ; CHECK-NEXT: s_not_b64 exec, exec |
| ; CHECK-NEXT: buffer_load_dword v8, off, s[0:3], s32 offset:8 |
| ; CHECK-NEXT: s_not_b64 exec, exec |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) |
| ; CHECK-NEXT: v_readlane_b32 s4, v8, 0 |
| ; CHECK-NEXT: buffer_load_dword v8, off, s[0:3], s32 offset:8 |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) |
| ; CHECK-NEXT: s_not_b64 exec, exec |
| ; CHECK-NEXT: v_mov_b32_e32 v7, vcc_hi |
| ; CHECK-NEXT: buffer_load_dword v8, v7, s[0:3], 0 offen |
| ; CHECK-NEXT: buffer_load_dword v9, v7, s[0:3], 0 offen offset:4 |
| ; CHECK-NEXT: v_mov_b32_e32 v7, vcc_lo |
| ; CHECK-NEXT: s_mov_b32 vcc_lo, 1 |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) |
| ; CHECK-NEXT: v_mul_f64 v[8:9], v[4:5], v[8:9] |
| ; CHECK-NEXT: buffer_store_dword v9, off, s[0:3], 0 offset:4 |
| ; CHECK-NEXT: buffer_store_dword v8, off, s[0:3], 0 |
| ; CHECK-NEXT: buffer_store_dword v6, v7, s[0:3], 0 offen |
| ; CHECK-NEXT: buffer_store_dword v6, v7, s[0:3], 0 offen offset:4 |
| ; CHECK-NEXT: s_andn2_b64 exec, exec, s[94:95] |
| ; CHECK-NEXT: s_cbranch_execnz .LBB0_13 |
| ; CHECK-NEXT: .LBB0_14: ; %Flow |
| ; CHECK-NEXT: ; in Loop: Header=BB0_11 Depth=4 |
| ; CHECK-NEXT: s_or_b64 exec, exec, s[92:93] |
| ; CHECK-NEXT: s_mov_b64 s[92:93], -1 |
| ; CHECK-NEXT: s_mov_b64 s[94:95], -1 |
| ; CHECK-NEXT: s_cbranch_execz .LBB0_10 |
| ; CHECK-NEXT: ; %bb.15: ; %sgpr_loop_merge |
| ; CHECK-NEXT: ; in Loop: Header=BB0_11 Depth=4 |
| ; CHECK-NEXT: s_mov_b64 s[94:95], 0 |
| ; CHECK-NEXT: s_orn2_b64 s[92:93], s[22:23], exec |
| ; CHECK-NEXT: s_branch .LBB0_10 |
| ; CHECK-NEXT: .LBB0_16: ; %loop.exit.guard6 |
| ; CHECK-NEXT: ; in Loop: Header=BB0_8 Depth=3 |
| ; CHECK-NEXT: s_or_b64 exec, exec, s[90:91] |
| ; CHECK-NEXT: s_mov_b64 s[90:91], -1 |
| ; CHECK-NEXT: s_mov_b64 s[92:93], 0 |
| ; CHECK-NEXT: s_and_saveexec_b64 s[94:95], s[88:89] |
| ; CHECK-NEXT: s_xor_b64 s[88:89], exec, s[94:95] |
| ; CHECK-NEXT: s_cbranch_execz .LBB0_6 |
| ; CHECK-NEXT: ; %bb.17: ; %after_sgpr_loop |
| ; CHECK-NEXT: ; in Loop: Header=BB0_8 Depth=3 |
| ; CHECK-NEXT: s_mov_b64 s[92:93], exec |
| ; CHECK-NEXT: s_orn2_b64 s[90:91], s[18:19], exec |
| ; CHECK-NEXT: s_branch .LBB0_6 |
| ; CHECK-NEXT: .LBB0_18: ; %loop.exit.guard5 |
| ; CHECK-NEXT: ; in Loop: Header=BB0_4 Depth=2 |
| ; CHECK-NEXT: s_or_b64 exec, exec, s[62:63] |
| ; CHECK-NEXT: s_orn2_b64 s[62:63], s[72:73], exec |
| ; CHECK-NEXT: .LBB0_19: ; %Flow10 |
| ; CHECK-NEXT: ; in Loop: Header=BB0_4 Depth=2 |
| ; CHECK-NEXT: s_or_b64 exec, exec, s[60:61] |
| ; CHECK-NEXT: s_or_b64 s[56:57], s[56:57], exec |
| ; CHECK-NEXT: s_and_saveexec_b64 s[60:61], s[62:63] |
| ; CHECK-NEXT: s_cbranch_execz .LBB0_3 |
| ; CHECK-NEXT: ; %bb.20: ; %outer_exit |
| ; CHECK-NEXT: ; in Loop: Header=BB0_4 Depth=2 |
| ; CHECK-NEXT: s_andn2_b64 s[56:57], s[56:57], exec |
| ; CHECK-NEXT: s_orn2_b64 s[58:59], s[16:17], exec |
| ; CHECK-NEXT: s_branch .LBB0_3 |
| ; CHECK-NEXT: .LBB0_21: ; %DummyReturnBlock |
| ; CHECK-NEXT: s_or_b64 exec, exec, s[20:21] |
| ; CHECK-NEXT: v_readlane_b32 s30, v10, 0 |
| ; CHECK-NEXT: v_readlane_b32 s31, v10, 1 |
| ; CHECK-NEXT: s_xor_saveexec_b64 s[4:5], -1 |
| ; CHECK-NEXT: buffer_load_dword v10, off, s[0:3], s32 offset:4 ; 4-byte Folded Reload |
| ; CHECK-NEXT: s_mov_b64 exec, s[4:5] |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| entry: |
| %private_slot = alloca i8, align 1, addrspace(5) |
| br label %outer_latch |
| |
| outer_latch: ; preds = %outer_exit, %entry |
| br label %outer_header |
| |
| outer_header: ; preds = %outer_exit, %outer_latch |
| br i1 %enter_fma_path, label %fma_setup, label %outer_exit |
| |
| fma_setup: ; preds = %outer_header |
| %first_fma = call double @llvm.fma.f64(double %input, double f0x3FE62E42FEFA39EF, double 0.000000e+00) |
| %second_fma = call double @llvm.fma.f64(double 0.000000e+00, double f0x3C7ABC9E3B39803F, double %first_fma) |
| br label %sgpr_loop_header |
| |
| sgpr_loop_header: ; preds = %after_sgpr_loop, %fma_setup |
| br i1 %enter_sgpr_loop, label %sgpr_pressure_loop, label %outer_exit |
| |
| sgpr_pressure_loop: ; preds = %sgpr_loop_merge, %sgpr_loop_header |
| %carried_sgpr_vec = phi <2 x i32> [ %next_sgpr_vec, %sgpr_loop_merge ], [ zeroinitializer, %sgpr_loop_header ] |
| %selected_fma = select i1 %zero_fma_result, double 0.000000e+00, double %second_fma |
| %new_sgpr_vec = insertelement <2 x i32> zeroinitializer, i32 0, i32 0 |
| br i1 %enter_inner_loop, label %inner_stack_loop, label %sgpr_loop_merge |
| |
| inner_stack_loop: ; preds = %inner_stack_loop, %sgpr_pressure_loop |
| %stack_offset = phi i32 [ 0, %sgpr_pressure_loop ], [ 1, %inner_stack_loop ] |
| %selected_fp = select i1 %repeat_outer_loop, double 0.000000e+00, double %selected_fma |
| %inf_mul = fmul double +inf, %selected_fp |
| %scaled_mul = fmul double %inf_mul, f0x40417E50A9DC6553 |
| %nan_mul = fmul double %scaled_mul, +qnan |
| %private_gep = getelementptr [8 x i8], ptr addrspace(5) %private_slot, i32 %stack_offset |
| %private_load = load double, ptr addrspace(5) %private_gep, align 1 |
| %spill_value = fmul double %nan_mul, %private_load |
| store double %spill_value, ptr addrspace(5) null, align 1 |
| %indexed_null = getelementptr i8, ptr addrspace(5) null, i32 %stack_offset |
| store double 0.000000e+00, ptr addrspace(5) %indexed_null, align 1 |
| br i1 %exit_inner_loop, label %inner_done, label %inner_stack_loop |
| |
| inner_done: ; preds = %inner_stack_loop |
| br label %sgpr_loop_merge |
| |
| sgpr_loop_merge: ; preds = %inner_done, %sgpr_pressure_loop |
| %next_sgpr_vec = phi <2 x i32> [ %new_sgpr_vec, %inner_done ], [ %carried_sgpr_vec, %sgpr_pressure_loop ] |
| br i1 %enter_fma_path, label %sgpr_pressure_loop, label %after_sgpr_loop |
| |
| after_sgpr_loop: ; preds = %sgpr_loop_merge |
| br i1 %enter_sgpr_loop, label %sgpr_loop_header, label %outer_exit |
| |
| outer_exit: ; preds = %after_sgpr_loop, %sgpr_loop_header, %outer_header |
| br i1 %repeat_outer_loop, label %outer_header, label %outer_latch |
| } |
| |
| declare double @llvm.fma.f64(double, double, double) |