[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / AMDGPU / memcpy-from-constant.ll
blobc6028267aae6f795cfc0ae356cd5e9ae8920b67f
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -mtriple=amdgcn-amd-amdhsa -S -amdgpu-aa-wrapper -amdgpu-aa -instcombine -o - %s | FileCheck %s
4 ; Make sure the optimization from memcpy-from-global.ll happens, but
5 ; the constant source is not a global variable.
7 target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
9 ; Simple memcpy to alloca from constant address space argument.
10 define i8 @memcpy_constant_arg_ptr_to_alloca([32 x i8] addrspace(4)* noalias readonly align 4 dereferenceable(32) %arg, i32 %idx) {
11 ; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca(
12 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64
13 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [32 x i8], [32 x i8] addrspace(4)* [[ARG:%.*]], i64 0, i64 [[TMP1]]
14 ; CHECK-NEXT:    [[LOAD:%.*]] = load i8, i8 addrspace(4)* [[GEP]], align 1
15 ; CHECK-NEXT:    ret i8 [[LOAD]]
17   %alloca = alloca [32 x i8], align 4, addrspace(5)
18   %alloca.cast = bitcast [32 x i8] addrspace(5)* %alloca to i8 addrspace(5)*
19   %arg.cast = bitcast [32 x i8] addrspace(4)* %arg to i8 addrspace(4)*
20   call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* %alloca.cast, i8 addrspace(4)* %arg.cast, i64 32, i1 false)
21   %gep = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* %alloca, i32 0, i32 %idx
22   %load = load i8, i8 addrspace(5)* %gep
23   ret i8 %load
26 define i8 @memcpy_constant_arg_ptr_to_alloca_load_metadata([32 x i8] addrspace(4)* noalias readonly align 4 dereferenceable(32) %arg, i32 %idx) {
27 ; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca_load_metadata(
28 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64
29 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [32 x i8], [32 x i8] addrspace(4)* [[ARG:%.*]], i64 0, i64 [[TMP1]]
30 ; CHECK-NEXT:    [[LOAD:%.*]] = load i8, i8 addrspace(4)* [[GEP]], align 1, !noalias !0
31 ; CHECK-NEXT:    ret i8 [[LOAD]]
33   %alloca = alloca [32 x i8], align 4, addrspace(5)
34   %alloca.cast = bitcast [32 x i8] addrspace(5)* %alloca to i8 addrspace(5)*
35   %arg.cast = bitcast [32 x i8] addrspace(4)* %arg to i8 addrspace(4)*
36   call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* %alloca.cast, i8 addrspace(4)* %arg.cast, i64 32, i1 false)
37   %gep = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* %alloca, i32 0, i32 %idx
38   %load = load i8, i8 addrspace(5)* %gep, !noalias !0
39   ret i8 %load
42 define i64 @memcpy_constant_arg_ptr_to_alloca_load_alignment([32 x i64] addrspace(4)* noalias readonly align 4 dereferenceable(256) %arg, i32 %idx) {
43 ; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca_load_alignment(
44 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64
45 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [32 x i64], [32 x i64] addrspace(4)* [[ARG:%.*]], i64 0, i64 [[TMP1]]
46 ; CHECK-NEXT:    [[LOAD:%.*]] = load i64, i64 addrspace(4)* [[GEP]], align 16
47 ; CHECK-NEXT:    ret i64 [[LOAD]]
49   %alloca = alloca [32 x i64], align 4, addrspace(5)
50   %alloca.cast = bitcast [32 x i64] addrspace(5)* %alloca to i8 addrspace(5)*
51   %arg.cast = bitcast [32 x i64] addrspace(4)* %arg to i8 addrspace(4)*
52   call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* %alloca.cast, i8 addrspace(4)* %arg.cast, i64 256, i1 false)
53   %gep = getelementptr inbounds [32 x i64], [32 x i64] addrspace(5)* %alloca, i32 0, i32 %idx
54   %load = load i64, i64 addrspace(5)* %gep, align 16
55   ret i64 %load
58 define i64 @memcpy_constant_arg_ptr_to_alloca_load_atomic([32 x i64] addrspace(4)* noalias readonly align 8 dereferenceable(256) %arg, i32 %idx) {
59 ; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca_load_atomic(
60 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [32 x i64], align 8, addrspace(5)
61 ; CHECK-NEXT:    [[ALLOCA_CAST:%.*]] = bitcast [32 x i64] addrspace(5)* [[ALLOCA]] to i8 addrspace(5)*
62 ; CHECK-NEXT:    [[ARG_CAST:%.*]] = bitcast [32 x i64] addrspace(4)* [[ARG:%.*]] to i8 addrspace(4)*
63 ; CHECK-NEXT:    call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* noundef align 8 dereferenceable(256) [[ALLOCA_CAST]], i8 addrspace(4)* noundef align 8 dereferenceable(256) [[ARG_CAST]], i64 256, i1 false)
64 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace(5)* [[ALLOCA]], i32 0, i32 [[IDX:%.*]]
65 ; CHECK-NEXT:    [[LOAD:%.*]] = load atomic i64, i64 addrspace(5)* [[GEP]] syncscope("somescope") acquire, align 8
66 ; CHECK-NEXT:    ret i64 [[LOAD]]
68   %alloca = alloca [32 x i64], align 8, addrspace(5)
69   %alloca.cast = bitcast [32 x i64] addrspace(5)* %alloca to i8 addrspace(5)*
70   %arg.cast = bitcast [32 x i64] addrspace(4)* %arg to i8 addrspace(4)*
71   call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* %alloca.cast, i8 addrspace(4)* %arg.cast, i64 256, i1 false)
72   %gep = getelementptr inbounds [32 x i64], [32 x i64] addrspace(5)* %alloca, i32 0, i32 %idx
73   %load = load atomic i64, i64 addrspace(5)* %gep syncscope("somescope") acquire, align 8
74   ret i64 %load
77 ; Simple memmove to alloca from constant address space argument.
78 define i8 @memmove_constant_arg_ptr_to_alloca([32 x i8] addrspace(4)* noalias readonly align 4 dereferenceable(32) %arg, i32 %idx) {
79 ; CHECK-LABEL: @memmove_constant_arg_ptr_to_alloca(
80 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64
81 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [32 x i8], [32 x i8] addrspace(4)* [[ARG:%.*]], i64 0, i64 [[TMP1]]
82 ; CHECK-NEXT:    [[LOAD:%.*]] = load i8, i8 addrspace(4)* [[GEP]], align 1
83 ; CHECK-NEXT:    ret i8 [[LOAD]]
85   %alloca = alloca [32 x i8], align 4, addrspace(5)
86   %alloca.cast = bitcast [32 x i8] addrspace(5)* %alloca to i8 addrspace(5)*
87   %arg.cast = bitcast [32 x i8] addrspace(4)* %arg to i8 addrspace(4)*
88   call void @llvm.memmove.p5i8.p4i8.i32(i8 addrspace(5)* %alloca.cast, i8 addrspace(4)* %arg.cast, i32 32, i1 false)
89   %gep = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* %alloca, i32 0, i32 %idx
90   %load = load i8, i8 addrspace(5)* %gep
91   ret i8 %load
94 ; Simple memcpy to alloca from byref constant address space argument.
95 define amdgpu_kernel void @memcpy_constant_byref_arg_ptr_to_alloca([32 x i8] addrspace(4)* noalias readonly align 4 byref([32 x i8]) %arg, i8 addrspace(1)* %out, i32 %idx) {
96 ; CHECK-LABEL: @memcpy_constant_byref_arg_ptr_to_alloca(
97 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64
98 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [32 x i8], [32 x i8] addrspace(4)* [[ARG:%.*]], i64 0, i64 [[TMP1]]
99 ; CHECK-NEXT:    [[LOAD:%.*]] = load i8, i8 addrspace(4)* [[GEP]], align 1
100 ; CHECK-NEXT:    store i8 [[LOAD]], i8 addrspace(1)* [[OUT:%.*]], align 1
101 ; CHECK-NEXT:    ret void
103   %alloca = alloca [32 x i8], align 4, addrspace(5)
104   %alloca.cast = bitcast [32 x i8] addrspace(5)* %alloca to i8 addrspace(5)*
105   %arg.cast = bitcast [32 x i8] addrspace(4)* %arg to i8 addrspace(4)*
106   call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* %alloca.cast, i8 addrspace(4)* %arg.cast, i64 32, i1 false)
107   %gep = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* %alloca, i32 0, i32 %idx
108   %load = load i8, i8 addrspace(5)* %gep
109   store i8 %load, i8 addrspace(1)* %out
110   ret void
113 ; Simple memcpy to alloca from byref constant address space argument, but not enough bytes are dereferenceable
114 define amdgpu_kernel void @memcpy_constant_byref_arg_ptr_to_alloca_too_many_bytes([31 x i8] addrspace(4)* noalias readonly align 4 byref([31 x i8]) %arg, i8 addrspace(1)* %out, i32 %idx) {
115 ; CHECK-LABEL: @memcpy_constant_byref_arg_ptr_to_alloca_too_many_bytes(
116 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [32 x i8], align 4, addrspace(5)
117 ; CHECK-NEXT:    [[ALLOCA_CAST:%.*]] = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* [[ALLOCA]], i32 0, i32 0
118 ; CHECK-NEXT:    [[ARG_CAST:%.*]] = getelementptr inbounds [31 x i8], [31 x i8] addrspace(4)* [[ARG:%.*]], i64 0, i64 0
119 ; CHECK-NEXT:    call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* noundef align 4 dereferenceable(31) [[ALLOCA_CAST]], i8 addrspace(4)* noundef align 4 dereferenceable(31) [[ARG_CAST]], i64 31, i1 false)
120 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* [[ALLOCA]], i32 0, i32 [[IDX:%.*]]
121 ; CHECK-NEXT:    [[LOAD:%.*]] = load i8, i8 addrspace(5)* [[GEP]], align 1
122 ; CHECK-NEXT:    store i8 [[LOAD]], i8 addrspace(1)* [[OUT:%.*]], align 1
123 ; CHECK-NEXT:    ret void
125   %alloca = alloca [32 x i8], align 4, addrspace(5)
126   %alloca.cast = bitcast [32 x i8] addrspace(5)* %alloca to i8 addrspace(5)*
127   %arg.cast = bitcast [31 x i8] addrspace(4)* %arg to i8 addrspace(4)*
128   call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* %alloca.cast, i8 addrspace(4)* %arg.cast, i64 31, i1 false)
129   %gep = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* %alloca, i32 0, i32 %idx
130   %load = load i8, i8 addrspace(5)* %gep
131   store i8 %load, i8 addrspace(1)* %out
132   ret void
135 ; Simple memcpy to alloca from constant address space intrinsic call
136 define amdgpu_kernel void @memcpy_constant_intrinsic_ptr_to_alloca(i8 addrspace(1)* %out, i32 %idx) {
137 ; CHECK-LABEL: @memcpy_constant_intrinsic_ptr_to_alloca(
138 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [32 x i8], align 4, addrspace(5)
139 ; CHECK-NEXT:    [[ALLOCA_CAST:%.*]] = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* [[ALLOCA]], i32 0, i32 0
140 ; CHECK-NEXT:    [[KERNARG_SEGMENT_PTR:%.*]] = call align 16 dereferenceable(32) i8 addrspace(4)* @llvm.amdgcn.kernarg.segment.ptr()
141 ; CHECK-NEXT:    call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* noundef align 4 dereferenceable(32) [[ALLOCA_CAST]], i8 addrspace(4)* noundef align 16 dereferenceable(32) [[KERNARG_SEGMENT_PTR]], i64 32, i1 false)
142 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* [[ALLOCA]], i32 0, i32 [[IDX:%.*]]
143 ; CHECK-NEXT:    [[LOAD:%.*]] = load i8, i8 addrspace(5)* [[GEP]], align 1
144 ; CHECK-NEXT:    store i8 [[LOAD]], i8 addrspace(1)* [[OUT:%.*]], align 1
145 ; CHECK-NEXT:    ret void
147   %alloca = alloca [32 x i8], align 4, addrspace(5)
148   %alloca.cast = bitcast [32 x i8] addrspace(5)* %alloca to i8 addrspace(5)*
149   %kernarg.segment.ptr = call dereferenceable(32) align 16 i8 addrspace(4)* @llvm.amdgcn.kernarg.segment.ptr()
150   call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* %alloca.cast, i8 addrspace(4)* %kernarg.segment.ptr, i64 32, i1 false)
151   %gep = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* %alloca, i32 0, i32 %idx
152   %load = load i8, i8 addrspace(5)* %gep
153   store i8 %load, i8 addrspace(1)* %out
154   ret void
157 ; Alloca is written through a flat pointer
158 define i8 @memcpy_constant_arg_ptr_to_alloca_addrspacecast_to_flat([31 x i8] addrspace(4)* noalias readonly align 4 dereferenceable(32) %arg, i32 %idx) {
159 ; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca_addrspacecast_to_flat(
160 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [32 x i8], align 4, addrspace(5)
161 ; CHECK-NEXT:    [[ALLOCA_CAST:%.*]] = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* [[ALLOCA]], i32 0, i32 0
162 ; CHECK-NEXT:    [[ALLOCA_CAST_ASC:%.*]] = addrspacecast i8 addrspace(5)* [[ALLOCA_CAST]] to i8*
163 ; CHECK-NEXT:    [[ARG_CAST:%.*]] = getelementptr inbounds [31 x i8], [31 x i8] addrspace(4)* [[ARG:%.*]], i64 0, i64 0
164 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p4i8.i64(i8* noundef nonnull align 1 dereferenceable(31) [[ALLOCA_CAST_ASC]], i8 addrspace(4)* noundef align 4 dereferenceable(31) [[ARG_CAST]], i64 31, i1 false)
165 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* [[ALLOCA]], i32 0, i32 [[IDX:%.*]]
166 ; CHECK-NEXT:    [[LOAD:%.*]] = load i8, i8 addrspace(5)* [[GEP]], align 1
167 ; CHECK-NEXT:    ret i8 [[LOAD]]
169   %alloca = alloca [32 x i8], align 4, addrspace(5)
170   %alloca.cast = bitcast [32 x i8] addrspace(5)* %alloca to i8 addrspace(5)*
171   %alloca.cast.asc = addrspacecast i8 addrspace(5)* %alloca.cast to i8*
172   %arg.cast = bitcast [31 x i8] addrspace(4)* %arg to i8 addrspace(4)*
173   call void @llvm.memcpy.p0i8.p4i8.i64(i8* %alloca.cast.asc, i8 addrspace(4)* %arg.cast, i64 31, i1 false)
174   %gep = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* %alloca, i32 0, i32 %idx
175   %load = load i8, i8 addrspace(5)* %gep
176   ret i8 %load
179 ; Alloca is only addressed through flat pointer.
180 define i8 @memcpy_constant_arg_ptr_to_alloca_addrspacecast_to_flat2([32 x i8] addrspace(4)* noalias readonly align 4 dereferenceable(32) %arg, i32 %idx) {
181 ; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca_addrspacecast_to_flat2(
182 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [32 x i8], align 4, addrspace(5)
183 ; CHECK-NEXT:    [[ALLOCA_CAST1:%.*]] = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* [[ALLOCA]], i32 0, i32 0
184 ; CHECK-NEXT:    [[ALLOCA_CAST:%.*]] = addrspacecast i8 addrspace(5)* [[ALLOCA_CAST1]] to i8*
185 ; CHECK-NEXT:    [[ARG_CAST:%.*]] = getelementptr inbounds [32 x i8], [32 x i8] addrspace(4)* [[ARG:%.*]], i64 0, i64 0
186 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p4i8.i64(i8* noundef nonnull align 1 dereferenceable(32) [[ALLOCA_CAST]], i8 addrspace(4)* noundef align 4 dereferenceable(32) [[ARG_CAST]], i64 32, i1 false)
187 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* [[ALLOCA]], i32 0, i32 [[IDX:%.*]]
188 ; CHECK-NEXT:    [[GEP:%.*]] = addrspacecast i8 addrspace(5)* [[GEP2]] to i8*
189 ; CHECK-NEXT:    [[LOAD:%.*]] = load i8, i8* [[GEP]], align 1
190 ; CHECK-NEXT:    ret i8 [[LOAD]]
192   %alloca = alloca [32 x i8], align 4, addrspace(5)
193   %alloca.cast.asc = addrspacecast [32 x i8] addrspace(5)* %alloca to [32 x i8]*
194   %alloca.cast = bitcast [32 x i8]* %alloca.cast.asc to i8*
195   %arg.cast = bitcast [32 x i8] addrspace(4)* %arg to i8 addrspace(4)*
196   call void @llvm.memcpy.p0i8.p4i8.i64(i8* %alloca.cast, i8 addrspace(4)* %arg.cast, i64 32, i1 false)
197   %gep = getelementptr inbounds [32 x i8], [32 x i8]* %alloca.cast.asc, i32 0, i32 %idx
198   %load = load i8, i8* %gep
199   ret i8 %load
202 %struct.ty = type { [4 x i32] }
204 define amdgpu_kernel void @byref_infloop(i8* %scratch, %struct.ty addrspace(4)* byref(%struct.ty) align 4 %arg) local_unnamed_addr #1 {
205 ; CHECK-LABEL: @byref_infloop(
206 ; CHECK-NEXT:  bb:
207 ; CHECK-NEXT:    [[CAST_ALLOCA:%.*]] = bitcast [[STRUCT_TY:%.*]] addrspace(4)* [[ARG:%.*]] to i8 addrspace(4)*
208 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p4i8.i32(i8* noundef nonnull align 4 dereferenceable(16) [[SCRATCH:%.*]], i8 addrspace(4)* noundef align 4 dereferenceable(16) [[CAST_ALLOCA]], i32 16, i1 false)
209 ; CHECK-NEXT:    ret void
212   %alloca = alloca [4 x i32], align 4, addrspace(5)
213   %cast.arg = bitcast %struct.ty addrspace(4)* %arg to i8 addrspace(4)*
214   %cast.alloca = bitcast [4 x i32] addrspace(5)* %alloca to i8 addrspace(5)*
215   call void @llvm.memcpy.p5i8.p4i8.i32(i8 addrspace(5)* align 4 %cast.alloca, i8 addrspace(4)* align 4 %cast.arg, i32 16, i1 false)
216   call void @llvm.memcpy.p0i8.p5i8.i32(i8* align 4 %scratch, i8 addrspace(5)* align 4 %cast.alloca, i32 16, i1 false)
217   ret void
220 define amdgpu_kernel void @byref_infloop_metadata(i8* %scratch, %struct.ty addrspace(4)* byref(%struct.ty) align 4 %arg) local_unnamed_addr #1 {
221 ; CHECK-LABEL: @byref_infloop_metadata(
222 ; CHECK-NEXT:  bb:
223 ; CHECK-NEXT:    [[CAST_ALLOCA:%.*]] = bitcast [[STRUCT_TY:%.*]] addrspace(4)* [[ARG:%.*]] to i8 addrspace(4)*
224 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p4i8.i32(i8* noundef nonnull align 4 dereferenceable(16) [[SCRATCH:%.*]], i8 addrspace(4)* noundef align 4 dereferenceable(16) [[CAST_ALLOCA]], i32 16, i1 false), !noalias !1
225 ; CHECK-NEXT:    ret void
228   %alloca = alloca [4 x i32], align 4, addrspace(5)
229   %cast.arg = bitcast %struct.ty addrspace(4)* %arg to i8 addrspace(4)*
230   %cast.alloca = bitcast [4 x i32] addrspace(5)* %alloca to i8 addrspace(5)*
231   call void @llvm.memcpy.p5i8.p4i8.i32(i8 addrspace(5)* align 4 %cast.alloca, i8 addrspace(4)* align 4 %cast.arg, i32 16, i1 false), !noalias !0
232   call void @llvm.memcpy.p0i8.p5i8.i32(i8* align 4 %scratch, i8 addrspace(5)* align 4 %cast.alloca, i32 16, i1 false), !noalias !1
233   ret void
236 define amdgpu_kernel void @byref_infloop_addrspacecast(i8* %scratch, %struct.ty addrspace(4)* byref(%struct.ty) align 4 %arg) local_unnamed_addr #1 {
237 ; CHECK-LABEL: @byref_infloop_addrspacecast(
238 ; CHECK-NEXT:  bb:
239 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [4 x i32], align 4, addrspace(5)
240 ; CHECK-NEXT:    [[CAST_ARG:%.*]] = bitcast [[STRUCT_TY:%.*]] addrspace(4)* [[ARG:%.*]] to i8 addrspace(4)*
241 ; CHECK-NEXT:    [[CAST_ALLOCA:%.*]] = bitcast [4 x i32] addrspace(5)* [[ALLOCA]] to i8 addrspace(5)*
242 ; CHECK-NEXT:    [[ADDRSPACECAST_ALLOCA:%.*]] = addrspacecast i8 addrspace(5)* [[CAST_ALLOCA]] to i8*
243 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p4i8.i64(i8* noundef nonnull align 4 dereferenceable(16) [[ADDRSPACECAST_ALLOCA]], i8 addrspace(4)* noundef align 4 dereferenceable(16) [[CAST_ARG]], i64 16, i1 false)
244 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 4 dereferenceable(16) [[SCRATCH:%.*]], i8* noundef nonnull align 4 dereferenceable(16) [[ADDRSPACECAST_ALLOCA]], i64 16, i1 false)
245 ; CHECK-NEXT:    ret void
248   %alloca = alloca [4 x i32], align 4, addrspace(5)
249   %cast.arg = bitcast %struct.ty addrspace(4)* %arg to i8 addrspace(4)*
250   %cast.alloca = bitcast [4 x i32] addrspace(5)* %alloca to i8 addrspace(5)*
251   %addrspacecast.alloca = addrspacecast i8 addrspace(5)* %cast.alloca to i8*
252   call void @llvm.memcpy.p0i8.p4i8.i64(i8* nonnull align 4 dereferenceable(16) %addrspacecast.alloca, i8 addrspace(4)* align 4 dereferenceable(16) %cast.arg, i64 16, i1 false)
253   call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(16) %scratch, i8* nonnull align 4 dereferenceable(16) %addrspacecast.alloca, i64 16, i1 false)
254   ret void
257 define amdgpu_kernel void @byref_infloop_memmove(i8* %scratch, %struct.ty addrspace(4)* byref(%struct.ty) align 4 %arg) local_unnamed_addr #1 {
258 ; CHECK-LABEL: @byref_infloop_memmove(
259 ; CHECK-NEXT:  bb:
260 ; CHECK-NEXT:    [[CAST_ALLOCA:%.*]] = bitcast [[STRUCT_TY:%.*]] addrspace(4)* [[ARG:%.*]] to i8 addrspace(4)*
261 ; CHECK-NEXT:    call void @llvm.memmove.p0i8.p4i8.i32(i8* noundef nonnull align 4 dereferenceable(16) [[SCRATCH:%.*]], i8 addrspace(4)* noundef align 4 dereferenceable(16) [[CAST_ALLOCA]], i32 16, i1 false)
262 ; CHECK-NEXT:    ret void
265   %alloca = alloca [4 x i32], align 4, addrspace(5)
266   %cast.arg = bitcast %struct.ty addrspace(4)* %arg to i8 addrspace(4)*
267   %cast.alloca = bitcast [4 x i32] addrspace(5)* %alloca to i8 addrspace(5)*
268   call void @llvm.memmove.p5i8.p4i8.i32(i8 addrspace(5)* align 4 %cast.alloca, i8 addrspace(4)* align 4 %cast.arg, i32 16, i1 false)
269   call void @llvm.memmove.p0i8.p5i8.i32(i8* align 4 %scratch, i8 addrspace(5)* align 4 %cast.alloca, i32 16, i1 false)
270   ret void
273 declare void @llvm.memcpy.p0i8.p5i8.i32(i8* noalias nocapture writeonly, i8 addrspace(5)* noalias nocapture readonly, i32, i1 immarg) #0
274 declare void @llvm.memcpy.p5i8.p4i8.i32(i8 addrspace(5)* nocapture, i8 addrspace(4)* nocapture, i32, i1) #0
275 declare void @llvm.memcpy.p0i8.p4i8.i64(i8* nocapture, i8 addrspace(4)* nocapture, i64, i1) #0
276 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #0
277 declare void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* nocapture, i8 addrspace(4)* nocapture, i64, i1) #0
278 declare void @llvm.memmove.p5i8.p4i8.i32(i8 addrspace(5)* nocapture, i8 addrspace(4)* nocapture, i32, i1) #0
279 declare void @llvm.memmove.p0i8.p5i8.i32(i8* nocapture, i8 addrspace(5)* nocapture, i32, i1) #0
280 declare i8 addrspace(4)* @llvm.amdgcn.kernarg.segment.ptr() #1
282 attributes #0 = { argmemonly nounwind willreturn }
283 attributes #1 = { nounwind readnone speculatable }
285 !0 = !{!0}
286 !1 = !{!1}