1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck -enable-var-scope -check-prefix=GCN %s 3 4; Load argument depends on waitcnt which should be skipped. 5define amdgpu_kernel void @call_memory_arg_load(i32 addrspace(3)* %ptr, i32) #0 { 6; GCN-LABEL: call_memory_arg_load: 7; GCN: ; %bb.0: 8; GCN-NEXT: s_add_u32 flat_scratch_lo, s12, s17 9; GCN-NEXT: s_mov_b32 s12, s14 10; GCN-NEXT: s_load_dword s14, s[8:9], 0x0 11; GCN-NEXT: s_addc_u32 flat_scratch_hi, s13, 0 12; GCN-NEXT: s_add_u32 s0, s0, s17 13; GCN-NEXT: s_addc_u32 s1, s1, 0 14; GCN-NEXT: s_add_u32 s8, s8, 8 15; GCN-NEXT: s_waitcnt lgkmcnt(0) 16; GCN-NEXT: v_mov_b32_e32 v3, s14 17; GCN-NEXT: ds_read_b32 v3, v3 18; GCN-NEXT: v_lshlrev_b32_e32 v2, 20, v2 19; GCN-NEXT: v_lshlrev_b32_e32 v1, 10, v1 20; GCN-NEXT: s_addc_u32 s9, s9, 0 21; GCN-NEXT: v_or3_b32 v31, v0, v1, v2 22; GCN-NEXT: s_mov_b32 s13, s15 23; GCN-NEXT: s_mov_b32 s14, s16 24; GCN-NEXT: s_waitcnt lgkmcnt(0) 25; GCN-NEXT: v_mov_b32_e32 v0, v3 26; GCN-NEXT: s_getpc_b64 s[18:19] 27; GCN-NEXT: s_add_u32 s18, s18, func@rel32@lo+4 28; GCN-NEXT: s_addc_u32 s19, s19, func@rel32@hi+12 29; GCN-NEXT: s_mov_b32 s32, 0 30; GCN-NEXT: s_swappc_b64 s[30:31], s[18:19] 31; GCN-NEXT: s_endpgm 32 %vgpr = load volatile i32, i32 addrspace(3)* %ptr 33 call void @func(i32 %vgpr) 34 ret void 35} 36 37; Memory waitcnt with no register dependence on the call 38define amdgpu_kernel void @call_memory_no_dep(i32 addrspace(1)* %ptr, i32) #0 { 39; GCN-LABEL: call_memory_no_dep: 40; GCN: ; %bb.0: 41; GCN-NEXT: s_add_u32 flat_scratch_lo, s12, s17 42; GCN-NEXT: s_addc_u32 flat_scratch_hi, s13, 0 43; GCN-NEXT: s_mov_b32 s13, s15 44; GCN-NEXT: s_mov_b32 s12, s14 45; GCN-NEXT: s_load_dwordx2 s[14:15], s[8:9], 0x0 46; GCN-NEXT: s_add_u32 s0, s0, s17 47; GCN-NEXT: s_addc_u32 s1, s1, 0 48; GCN-NEXT: s_add_u32 s8, s8, 16 49; GCN-NEXT: v_mov_b32_e32 v3, 0 50; GCN-NEXT: v_lshlrev_b32_e32 v2, 20, v2 51; GCN-NEXT: v_lshlrev_b32_e32 v1, 10, v1 52; GCN-NEXT: s_addc_u32 s9, s9, 0 53; GCN-NEXT: s_waitcnt lgkmcnt(0) 54; GCN-NEXT: global_store_dword v3, v3, s[14:15] 55; GCN-NEXT: v_or3_b32 v31, v0, v1, v2 56; GCN-NEXT: s_mov_b32 s14, s16 57; GCN-NEXT: v_mov_b32_e32 v0, 0 58; GCN-NEXT: s_getpc_b64 s[18:19] 59; GCN-NEXT: s_add_u32 s18, s18, func@rel32@lo+4 60; GCN-NEXT: s_addc_u32 s19, s19, func@rel32@hi+12 61; GCN-NEXT: s_mov_b32 s32, 0 62; GCN-NEXT: s_swappc_b64 s[30:31], s[18:19] 63; GCN-NEXT: s_endpgm 64 store i32 0, i32 addrspace(1)* %ptr 65 call void @func(i32 0) 66 ret void 67} 68 69; Should not wait after the call before memory 70define amdgpu_kernel void @call_no_wait_after_call(i32 addrspace(1)* %ptr, i32) #0 { 71; GCN-LABEL: call_no_wait_after_call: 72; GCN: %bb.0: 73; GCN-NEXT: s_add_u32 flat_scratch_lo, s12, s17 74; GCN-NEXT: s_addc_u32 flat_scratch_hi, s13, 0 75; GCN-NEXT: s_add_u32 s0, s0, s17 76; GCN-NEXT: s_load_dwordx2 s[34:35], s[8:9], 0x0 77; GCN-NEXT: s_addc_u32 s1, s1, 0 78; GCN-NEXT: s_add_u32 s8, s8, 16 79; GCN-NEXT: v_lshlrev_b32_e32 v2, 20, v2 80; GCN-NEXT: v_lshlrev_b32_e32 v1, 10, v1 81; GCN-NEXT: s_addc_u32 s9, s9, 0 82; GCN-NEXT: s_mov_b32 s12, s14 83; GCN-NEXT: v_or3_b32 v31, v0, v1, v2 84; GCN-NEXT: s_mov_b32 s13, s15 85; GCN-NEXT: s_mov_b32 s14, s16 86; GCN-NEXT: v_mov_b32_e32 v0, 0 87; GCN-NEXT: s_getpc_b64 s[18:19] 88; GCN-NEXT: s_add_u32 s18, s18, func@rel32@lo+4 89; GCN-NEXT: s_addc_u32 s19, s19, func@rel32@hi+12 90; GCN-NEXT: s_mov_b32 s32, 0 91; GCN-NEXT: v_mov_b32_e32 v40, 0 92; GCN-NEXT: s_swappc_b64 s[30:31], s[18:19] 93; GCN-NEXT: global_store_dword v40, v40, s[34:35] 94; GCN-NEXT: s_endpgm 95 call void @func(i32 0) 96 store i32 0, i32 addrspace(1)* %ptr 97 ret void 98} 99 100define amdgpu_kernel void @call_no_wait_after_call_return_val(i32 addrspace(1)* %ptr, i32) #0 { 101; GCN-LABEL: call_no_wait_after_call_return_val: 102; GCN: ; %bb.0: 103; GCN-NEXT: s_add_u32 flat_scratch_lo, s12, s17 104; GCN-NEXT: s_addc_u32 flat_scratch_hi, s13, 0 105; GCN-NEXT: s_add_u32 s0, s0, s17 106; GCN-NEXT: s_load_dwordx2 s[34:35], s[8:9], 0x0 107; GCN-NEXT: s_addc_u32 s1, s1, 0 108; GCN-NEXT: s_add_u32 s8, s8, 16 109; GCN-NEXT: v_lshlrev_b32_e32 v2, 20, v2 110; GCN-NEXT: v_lshlrev_b32_e32 v1, 10, v1 111; GCN-NEXT: s_addc_u32 s9, s9, 0 112; GCN-NEXT: s_mov_b32 s12, s14 113; GCN-NEXT: v_or3_b32 v31, v0, v1, v2 114; GCN-NEXT: s_mov_b32 s13, s15 115; GCN-NEXT: s_mov_b32 s14, s16 116; GCN-NEXT: v_mov_b32_e32 v0, 0 117; GCN-NEXT: s_getpc_b64 s[18:19] 118; GCN-NEXT: s_add_u32 s18, s18, func.return@rel32@lo+4 119; GCN-NEXT: s_addc_u32 s19, s19, func.return@rel32@hi+12 120; GCN-NEXT: s_mov_b32 s32, 0 121; GCN-NEXT: v_mov_b32_e32 v40, 0 122; GCN-NEXT: s_swappc_b64 s[30:31], s[18:19] 123; GCN-NEXT: global_store_dword v40, v0, s[34:35] 124; GCN-NEXT: s_endpgm 125 %rv = call i32 @func.return(i32 0) 126 store i32 %rv, i32 addrspace(1)* %ptr 127 ret void 128} 129 130; Need to wait for the address dependency 131define amdgpu_kernel void @call_got_load(i32 addrspace(1)* %ptr, i32) #0 { 132; GCN-LABEL: call_got_load: 133; GCN: ; %bb.0: 134; GCN-NEXT: s_add_u32 flat_scratch_lo, s12, s17 135; GCN-NEXT: s_addc_u32 flat_scratch_hi, s13, 0 136; GCN-NEXT: s_add_u32 s0, s0, s17 137; GCN-NEXT: s_addc_u32 s1, s1, 0 138; GCN-NEXT: s_add_u32 s8, s8, 16 139; GCN-NEXT: s_addc_u32 s9, s9, 0 140; GCN-NEXT: s_mov_b32 s13, s15 141; GCN-NEXT: s_mov_b32 s12, s14 142; GCN-NEXT: s_getpc_b64 s[14:15] 143; GCN-NEXT: s_add_u32 s14, s14, got.func@gotpcrel32@lo+4 144; GCN-NEXT: s_addc_u32 s15, s15, got.func@gotpcrel32@hi+12 145; GCN-NEXT: s_load_dwordx2 s[18:19], s[14:15], 0x0 146; GCN-NEXT: v_lshlrev_b32_e32 v2, 20, v2 147; GCN-NEXT: v_lshlrev_b32_e32 v1, 10, v1 148; GCN-NEXT: v_or3_b32 v31, v0, v1, v2 149; GCN-NEXT: s_mov_b32 s14, s16 150; GCN-NEXT: v_mov_b32_e32 v0, 0 151; GCN-NEXT: s_mov_b32 s32, 0 152; GCN-NEXT: s_waitcnt lgkmcnt(0) 153; GCN-NEXT: s_swappc_b64 s[30:31], s[18:19] 154; GCN-NEXT: s_endpgm 155 call void @got.func(i32 0) 156 ret void 157} 158 159; Need to wait for the address dependency 160define void @tailcall_got_load(i32 addrspace(1)* %ptr, i32) #0 { 161; GCN-LABEL: tailcall_got_load: 162; GCN: ; %bb.0: 163; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 164; GCN-NEXT: s_getpc_b64 s[16:17] 165; GCN-NEXT: s_add_u32 s16, s16, got.func@gotpcrel32@lo+4 166; GCN-NEXT: s_addc_u32 s17, s17, got.func@gotpcrel32@hi+12 167; GCN-NEXT: s_load_dwordx2 s[16:17], s[16:17], 0x0 168; GCN-NEXT: v_mov_b32_e32 v0, 0 169; GCN-NEXT: s_waitcnt lgkmcnt(0) 170; GCN-NEXT: s_setpc_b64 s[16:17] 171 tail call void @got.func(i32 0) 172 ret void 173} 174 175; No need to wait for the load. 176define void @tail_call_memory_arg_load(i32 addrspace(3)* %ptr, i32) #0 { 177; GCN-LABEL: tail_call_memory_arg_load: 178; GCN: ; %bb.0: 179; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 180; GCN-NEXT: ds_read_b32 v0, v0 181; GCN-NEXT: s_getpc_b64 s[16:17] 182; GCN-NEXT: s_add_u32 s16, s16, func@rel32@lo+4 183; GCN-NEXT: s_addc_u32 s17, s17, func@rel32@hi+12 184; GCN-NEXT: s_setpc_b64 s[16:17] 185 %vgpr = load volatile i32, i32 addrspace(3)* %ptr 186 tail call void @func(i32 %vgpr) 187 ret void 188} 189 190declare hidden void @func(i32) #0 191declare hidden i32 @func.return(i32) #0 192declare void @got.func(i32) #0 193 194attributes #0 = { nounwind } 195