Matt Arsenault | a202538 | 2017-08-03 23:24:05 +0000 | [diff] [blame] | 1 | ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=fiji -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,VI %s |
| 2 | ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=hawaii -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,CI %s |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 3 | |
| 4 | %struct.ByValStruct = type { [4 x i32] } |
| 5 | |
| 6 | ; GCN-LABEL: {{^}}void_func_byval_struct: |
| 7 | ; GCN: s_mov_b32 s5, s32 |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 8 | ; GCN: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s5 offset:4{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 9 | ; GCN-NOT: s32 |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 10 | ; GCN: buffer_store_dword [[LOAD0]], off, s[0:3], s5 offset:4{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 11 | ; GCN-NOT: s32 |
| 12 | |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 13 | ; GCN: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s5 offset:20{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 14 | ; GCN-NOT: s32 |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 15 | ; GCN: buffer_store_dword [[LOAD1]], off, s[0:3], s5 offset:20{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 16 | ; GCN-NOT: s32 |
| 17 | define void @void_func_byval_struct(%struct.ByValStruct* byval noalias nocapture align 4 %arg0, %struct.ByValStruct* byval noalias nocapture align 4 %arg1) #1 { |
| 18 | entry: |
| 19 | %arrayidx = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg0, i32 0, i32 0, i32 0 |
| 20 | %tmp = load volatile i32, i32* %arrayidx, align 4 |
| 21 | %add = add nsw i32 %tmp, 1 |
| 22 | store volatile i32 %add, i32* %arrayidx, align 4 |
| 23 | %arrayidx2 = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg1, i32 0, i32 0, i32 0 |
| 24 | %tmp1 = load volatile i32, i32* %arrayidx2, align 4 |
| 25 | %add3 = add nsw i32 %tmp1, 2 |
| 26 | store volatile i32 %add3, i32* %arrayidx2, align 4 |
| 27 | store volatile i32 9, i32 addrspace(1)* null, align 4 |
| 28 | ret void |
| 29 | } |
| 30 | |
| 31 | ; GCN-LABEL: {{^}}void_func_byval_struct_non_leaf: |
| 32 | ; GCN: s_mov_b32 s5, s32 |
Matt Arsenault | 8e8f8f4 | 2017-08-02 01:52:45 +0000 | [diff] [blame] | 33 | ; GCN-DAG: buffer_store_dword v32 |
| 34 | ; GCN-DAG: buffer_store_dword v33 |
Matt Arsenault | ecb43ef | 2017-09-13 23:47:01 +0000 | [diff] [blame^] | 35 | ; GCN-NOT: v_writelane_b32 v{{[0-9]+}}, s32 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 36 | ; GCN: v_writelane_b32 |
| 37 | |
Matt Arsenault | 8e8f8f4 | 2017-08-02 01:52:45 +0000 | [diff] [blame] | 38 | ; GCN-DAG: s_add_u32 s32, s32, 0xb00{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 39 | |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 40 | ; GCN-DAG: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s5 offset:4{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 41 | ; GCN: v_add_i32_e32 [[ADD0:v[0-9]+]], vcc, 1, [[LOAD0]] |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 42 | ; GCN: buffer_store_dword [[ADD0]], off, s[0:3], s5 offset:4{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 43 | |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 44 | ; GCN: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s5 offset:20{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 45 | ; GCN: v_add_i32_e32 [[ADD1:v[0-9]+]], vcc, 2, [[LOAD1]] |
| 46 | |
| 47 | ; GCN: s_swappc_b64 |
| 48 | |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 49 | ; GCN: buffer_store_dword [[ADD1]], off, s[0:3], s5 offset:20{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 50 | |
| 51 | ; GCN: v_readlane_b32 |
Matt Arsenault | ecb43ef | 2017-09-13 23:47:01 +0000 | [diff] [blame^] | 52 | ; GCN-NOT: v_readlane_b32 s32 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 53 | ; GCN: buffer_load_dword v32, |
Matt Arsenault | 8e8f8f4 | 2017-08-02 01:52:45 +0000 | [diff] [blame] | 54 | ; GCN: buffer_load_dword v33, |
| 55 | ; GCN: s_sub_u32 s32, s32, 0xb00{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 56 | ; GCN: s_setpc_b64 |
| 57 | define void @void_func_byval_struct_non_leaf(%struct.ByValStruct* byval noalias nocapture align 4 %arg0, %struct.ByValStruct* byval noalias nocapture align 4 %arg1) #1 { |
| 58 | entry: |
| 59 | %arrayidx = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg0, i32 0, i32 0, i32 0 |
| 60 | %tmp = load volatile i32, i32* %arrayidx, align 4 |
| 61 | %add = add nsw i32 %tmp, 1 |
| 62 | store volatile i32 %add, i32* %arrayidx, align 4 |
| 63 | %arrayidx2 = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg1, i32 0, i32 0, i32 0 |
| 64 | %tmp1 = load volatile i32, i32* %arrayidx2, align 4 |
| 65 | %add3 = add nsw i32 %tmp1, 2 |
| 66 | call void @external_void_func_void() |
| 67 | store volatile i32 %add3, i32* %arrayidx2, align 4 |
| 68 | store volatile i32 9, i32 addrspace(1)* null, align 4 |
| 69 | ret void |
| 70 | } |
| 71 | |
| 72 | ; GCN-LABEL: {{^}}call_void_func_byval_struct_func: |
| 73 | ; GCN: s_mov_b32 s5, s32 |
Matt Arsenault | ecb43ef | 2017-09-13 23:47:01 +0000 | [diff] [blame^] | 74 | ; GCN-DAG: s_add_u32 s32, s32, 0xc00{{$}} |
| 75 | ; GCN-DAG: v_writelane_b32 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 76 | |
| 77 | ; GCN-DAG: s_add_u32 s32, s32, 0x800{{$}} |
| 78 | ; GCN-DAG: v_mov_b32_e32 [[NINE:v[0-9]+]], 9 |
| 79 | ; GCN-DAG: v_mov_b32_e32 [[THIRTEEN:v[0-9]+]], 13 |
| 80 | |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 81 | ; GCN-DAG: buffer_store_dword [[NINE]], off, s[0:3], s5 offset:8 |
| 82 | ; GCN-DAG: buffer_store_dword [[THIRTEEN]], off, s[0:3], s5 offset:24 |
| 83 | |
Matt Arsenault | acc5e82 | 2017-08-02 00:43:42 +0000 | [diff] [blame] | 84 | ; GCN: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s5 offset:8 |
| 85 | ; GCN: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s5 offset:12 |
| 86 | ; GCN: buffer_load_dword [[LOAD2:v[0-9]+]], off, s[0:3], s5 offset:16 |
| 87 | ; GCN: buffer_load_dword [[LOAD3:v[0-9]+]], off, s[0:3], s5 offset:20 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 88 | |
| 89 | |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 90 | ; GCN-DAG: buffer_store_dword [[LOAD0]], off, s[0:3], s32 offset:4{{$}} |
| 91 | ; GCN-DAG: buffer_store_dword [[LOAD1]], off, s[0:3], s32 offset:8 |
| 92 | ; GCN-DAG: buffer_store_dword [[LOAD2]], off, s[0:3], s32 offset:12 |
| 93 | ; GCN-DAG: buffer_store_dword [[LOAD3]], off, s[0:3], s32 offset:16 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 94 | |
Matt Arsenault | acc5e82 | 2017-08-02 00:43:42 +0000 | [diff] [blame] | 95 | ; GCN: buffer_load_dword [[LOAD4:v[0-9]+]], off, s[0:3], s5 offset:24 |
| 96 | ; GCN: buffer_load_dword [[LOAD5:v[0-9]+]], off, s[0:3], s5 offset:28 |
| 97 | ; GCN: buffer_load_dword [[LOAD6:v[0-9]+]], off, s[0:3], s5 offset:32 |
| 98 | ; GCN: buffer_load_dword [[LOAD7:v[0-9]+]], off, s[0:3], s5 offset:36 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 99 | |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 100 | ; GCN-DAG: buffer_store_dword [[LOAD4]], off, s[0:3], s32 offset:20 |
| 101 | ; GCN-DAG: buffer_store_dword [[LOAD5]], off, s[0:3], s32 offset:24 |
| 102 | ; GCN-DAG: buffer_store_dword [[LOAD6]], off, s[0:3], s32 offset:28 |
| 103 | ; GCN-DAG: buffer_store_dword [[LOAD7]], off, s[0:3], s32 offset:32 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 104 | |
| 105 | ; GCN: s_swappc_b64 |
Matt Arsenault | ecb43ef | 2017-09-13 23:47:01 +0000 | [diff] [blame^] | 106 | ; GCN-NOT: v_readlane_b32 s32 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 107 | ; GCN: v_readlane_b32 |
Matt Arsenault | ecb43ef | 2017-09-13 23:47:01 +0000 | [diff] [blame^] | 108 | ; GCN-NOT: v_readlane_b32 s32 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 109 | |
Matt Arsenault | ecb43ef | 2017-09-13 23:47:01 +0000 | [diff] [blame^] | 110 | ; GCN: s_sub_u32 s32, s32, 0x800{{$}} |
| 111 | ; GCN-NEXT: s_sub_u32 s32, s32, 0xc00{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 112 | ; GCN-NEXT: s_waitcnt |
| 113 | ; GCN-NEXT: s_setpc_b64 |
| 114 | define void @call_void_func_byval_struct_func() #0 { |
| 115 | entry: |
| 116 | %arg0 = alloca %struct.ByValStruct, align 4 |
| 117 | %arg1 = alloca %struct.ByValStruct, align 4 |
| 118 | %tmp = bitcast %struct.ByValStruct* %arg0 to i8* |
| 119 | call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp) |
| 120 | %tmp1 = bitcast %struct.ByValStruct* %arg1 to i8* |
| 121 | call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp1) |
| 122 | %arrayidx = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg0, i32 0, i32 0, i32 0 |
| 123 | store volatile i32 9, i32* %arrayidx, align 4 |
| 124 | %arrayidx2 = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg1, i32 0, i32 0, i32 0 |
| 125 | store volatile i32 13, i32* %arrayidx2, align 4 |
| 126 | call void @void_func_byval_struct(%struct.ByValStruct* byval nonnull align 4 %arg0, %struct.ByValStruct* byval nonnull align 4 %arg1) |
| 127 | call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp1) |
| 128 | call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp) |
| 129 | ret void |
| 130 | } |
| 131 | |
| 132 | ; GCN-LABEL: {{^}}call_void_func_byval_struct_kernel: |
Geoff Berry | 4e38e02 | 2017-08-17 04:04:11 +0000 | [diff] [blame] | 133 | ; GCN: s_mov_b32 s33, s7 |
| 134 | ; GCN: s_add_u32 s32, s33, 0xa00{{$}} |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 135 | |
| 136 | ; GCN-DAG: v_mov_b32_e32 [[NINE:v[0-9]+]], 9 |
| 137 | ; GCN-DAG: v_mov_b32_e32 [[THIRTEEN:v[0-9]+]], 13 |
Geoff Berry | 4e38e02 | 2017-08-17 04:04:11 +0000 | [diff] [blame] | 138 | ; GCN-DAG: buffer_store_dword [[NINE]], off, s[0:3], s33 offset:8 |
| 139 | ; GCN: buffer_store_dword [[THIRTEEN]], off, s[0:3], s33 offset:24 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 140 | |
| 141 | ; GCN-DAG: s_add_u32 s32, s32, 0x800{{$}} |
| 142 | |
Geoff Berry | 4e38e02 | 2017-08-17 04:04:11 +0000 | [diff] [blame] | 143 | ; GCN-DAG: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s33 offset:8 |
| 144 | ; GCN-DAG: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s33 offset:12 |
| 145 | ; GCN-DAG: buffer_load_dword [[LOAD2:v[0-9]+]], off, s[0:3], s33 offset:16 |
| 146 | ; GCN-DAG: buffer_load_dword [[LOAD3:v[0-9]+]], off, s[0:3], s33 offset:20 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 147 | |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 148 | ; GCN-DAG: buffer_store_dword [[LOAD0]], off, s[0:3], s32 offset:4{{$}} |
| 149 | ; GCN-DAG: buffer_store_dword [[LOAD1]], off, s[0:3], s32 offset:8 |
| 150 | ; GCN-DAG: buffer_store_dword [[LOAD2]], off, s[0:3], s32 offset:12 |
| 151 | ; GCN-DAG: buffer_store_dword [[LOAD3]], off, s[0:3], s32 offset:16 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 152 | |
Matt Arsenault | acc5e82 | 2017-08-02 00:43:42 +0000 | [diff] [blame] | 153 | ; GCN-DAG: buffer_load_dword [[LOAD4:v[0-9]+]], off, s[0:3], s33 offset:24 |
| 154 | ; GCN-DAG: buffer_load_dword [[LOAD5:v[0-9]+]], off, s[0:3], s33 offset:28 |
| 155 | ; GCN-DAG: buffer_load_dword [[LOAD6:v[0-9]+]], off, s[0:3], s33 offset:32 |
| 156 | ; GCN-DAG: buffer_load_dword [[LOAD7:v[0-9]+]], off, s[0:3], s33 offset:36 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 157 | |
Matt Arsenault | d1867c0 | 2017-08-02 00:59:51 +0000 | [diff] [blame] | 158 | ; GCN-DAG: buffer_store_dword [[LOAD4]], off, s[0:3], s32 offset:20 |
| 159 | ; GCN-DAG: buffer_store_dword [[LOAD5]], off, s[0:3], s32 offset:24 |
| 160 | ; GCN-DAG: buffer_store_dword [[LOAD6]], off, s[0:3], s32 offset:28 |
| 161 | ; GCN-DAG: buffer_store_dword [[LOAD7]], off, s[0:3], s32 offset:32 |
Matt Arsenault | b62a4eb | 2017-08-01 19:54:18 +0000 | [diff] [blame] | 162 | |
| 163 | |
| 164 | ; GCN: s_swappc_b64 |
| 165 | ; FIXME: Dead SP modfication |
| 166 | ; GCN-NEXT: s_sub_u32 s32, s32, 0x800{{$}} |
| 167 | ; GCN-NEXT: s_endpgm |
| 168 | define amdgpu_kernel void @call_void_func_byval_struct_kernel() #0 { |
| 169 | entry: |
| 170 | %arg0 = alloca %struct.ByValStruct, align 4 |
| 171 | %arg1 = alloca %struct.ByValStruct, align 4 |
| 172 | %tmp = bitcast %struct.ByValStruct* %arg0 to i8* |
| 173 | call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp) |
| 174 | %tmp1 = bitcast %struct.ByValStruct* %arg1 to i8* |
| 175 | call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp1) |
| 176 | %arrayidx = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg0, i32 0, i32 0, i32 0 |
| 177 | store volatile i32 9, i32* %arrayidx, align 4 |
| 178 | %arrayidx2 = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg1, i32 0, i32 0, i32 0 |
| 179 | store volatile i32 13, i32* %arrayidx2, align 4 |
| 180 | call void @void_func_byval_struct(%struct.ByValStruct* byval nonnull align 4 %arg0, %struct.ByValStruct* byval nonnull align 4 %arg1) |
| 181 | call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp1) |
| 182 | call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp) |
| 183 | ret void |
| 184 | } |
| 185 | |
| 186 | ; GCN-LABEL: {{^}}call_void_func_byval_struct_kernel_no_frame_pointer_elim: |
| 187 | define amdgpu_kernel void @call_void_func_byval_struct_kernel_no_frame_pointer_elim() #2 { |
| 188 | entry: |
| 189 | %arg0 = alloca %struct.ByValStruct, align 4 |
| 190 | %arg1 = alloca %struct.ByValStruct, align 4 |
| 191 | %tmp = bitcast %struct.ByValStruct* %arg0 to i8* |
| 192 | call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp) |
| 193 | %tmp1 = bitcast %struct.ByValStruct* %arg1 to i8* |
| 194 | call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp1) |
| 195 | %arrayidx = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg0, i32 0, i32 0, i32 0 |
| 196 | store volatile i32 9, i32* %arrayidx, align 4 |
| 197 | %arrayidx2 = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg1, i32 0, i32 0, i32 0 |
| 198 | store volatile i32 13, i32* %arrayidx2, align 4 |
| 199 | call void @void_func_byval_struct(%struct.ByValStruct* byval nonnull align 4 %arg0, %struct.ByValStruct* byval nonnull align 4 %arg1) |
| 200 | call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp1) |
| 201 | call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp) |
| 202 | ret void |
| 203 | } |
| 204 | |
| 205 | declare void @external_void_func_void() #0 |
| 206 | |
| 207 | declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #3 |
| 208 | declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #3 |
| 209 | |
| 210 | attributes #0 = { nounwind } |
| 211 | attributes #1 = { noinline norecurse nounwind } |
| 212 | attributes #2 = { nounwind norecurse "no-frame-pointer-elim"="true" } |