239 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -mtriple=amdgcn-amd-amdhsa -S -amdgpu-aa-wrapper -amdgpu-aa -instcombine -o - %s | FileCheck %s3 4; Make sure the optimization from memcpy-from-global.ll happens, but5; the constant source is not a global variable.6 7; Simple memcpy to alloca from constant address space argument.8define i8 @memcpy_constant_arg_ptr_to_alloca(ptr addrspace(4) noalias readonly align 4 dereferenceable(32) %arg, i32 %idx) {9; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca(10; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i6411; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr addrspace(4) [[ARG:%.*]], i64 [[TMP1]]12; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(4) [[GEP]], align 113; CHECK-NEXT: ret i8 [[LOAD]]14;15 %alloca = alloca [32 x i8], align 4, addrspace(5)16 call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) %alloca, ptr addrspace(4) %arg, i64 32, i1 false)17 %gep = getelementptr inbounds [32 x i8], ptr addrspace(5) %alloca, i32 0, i32 %idx18 %load = load i8, ptr addrspace(5) %gep19 ret i8 %load20}21 22define i8 @memcpy_constant_arg_ptr_to_alloca_load_metadata(ptr addrspace(4) noalias readonly align 4 dereferenceable(32) %arg, i32 %idx) {23; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca_load_metadata(24; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i6425; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr addrspace(4) [[ARG:%.*]], i64 [[TMP1]]26; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(4) [[GEP]], align 1, !noalias [[META0:![0-9]+]]27; CHECK-NEXT: ret i8 [[LOAD]]28;29 %alloca = alloca [32 x i8], align 4, addrspace(5)30 call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) %alloca, ptr addrspace(4) %arg, i64 32, i1 false)31 %gep = getelementptr inbounds [32 x i8], ptr addrspace(5) %alloca, i32 0, i32 %idx32 %load = load i8, ptr addrspace(5) %gep, !noalias !033 ret i8 %load34}35 36define i64 @memcpy_constant_arg_ptr_to_alloca_load_alignment(ptr addrspace(4) noalias readonly align 4 dereferenceable(256) %arg, i32 %idx) {37; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca_load_alignment(38; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i6439; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i64, ptr addrspace(4) [[ARG:%.*]], i64 [[TMP1]]40; CHECK-NEXT: [[LOAD:%.*]] = load i64, ptr addrspace(4) [[GEP]], align 1641; CHECK-NEXT: ret i64 [[LOAD]]42;43 %alloca = alloca [32 x i64], align 4, addrspace(5)44 call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) %alloca, ptr addrspace(4) %arg, i64 256, i1 false)45 %gep = getelementptr inbounds [32 x i64], ptr addrspace(5) %alloca, i32 0, i32 %idx46 %load = load i64, ptr addrspace(5) %gep, align 1647 ret i64 %load48}49 50define i64 @memcpy_constant_arg_ptr_to_alloca_load_atomic(ptr addrspace(4) noalias readonly align 8 dereferenceable(256) %arg, i32 %idx) {51; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca_load_atomic(52; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i64], align 8, addrspace(5)53; CHECK-NEXT: call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) noundef align 8 dereferenceable(256) [[ALLOCA]], ptr addrspace(4) noundef align 8 dereferenceable(256) [[ARG:%.*]], i64 256, i1 false)54; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i64, ptr addrspace(5) [[ALLOCA]], i32 [[IDX:%.*]]55; CHECK-NEXT: [[LOAD:%.*]] = load atomic i64, ptr addrspace(5) [[GEP]] syncscope("somescope") acquire, align 856; CHECK-NEXT: ret i64 [[LOAD]]57;58 %alloca = alloca [32 x i64], align 8, addrspace(5)59 call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) %alloca, ptr addrspace(4) %arg, i64 256, i1 false)60 %gep = getelementptr inbounds [32 x i64], ptr addrspace(5) %alloca, i32 0, i32 %idx61 %load = load atomic i64, ptr addrspace(5) %gep syncscope("somescope") acquire, align 862 ret i64 %load63}64 65; Simple memmove to alloca from constant address space argument.66define i8 @memmove_constant_arg_ptr_to_alloca(ptr addrspace(4) noalias readonly align 4 dereferenceable(32) %arg, i32 %idx) {67; CHECK-LABEL: @memmove_constant_arg_ptr_to_alloca(68; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i6469; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr addrspace(4) [[ARG:%.*]], i64 [[TMP1]]70; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(4) [[GEP]], align 171; CHECK-NEXT: ret i8 [[LOAD]]72;73 %alloca = alloca [32 x i8], align 4, addrspace(5)74 call void @llvm.memmove.p5.p4.i32(ptr addrspace(5) %alloca, ptr addrspace(4) %arg, i32 32, i1 false)75 %gep = getelementptr inbounds [32 x i8], ptr addrspace(5) %alloca, i32 0, i32 %idx76 %load = load i8, ptr addrspace(5) %gep77 ret i8 %load78}79 80; Simple memcpy to alloca from byref constant address space argument.81define amdgpu_kernel void @memcpy_constant_byref_arg_ptr_to_alloca(ptr addrspace(4) noalias readonly align 4 byref([32 x i8]) %arg, ptr addrspace(1) %out, i32 %idx) {82; CHECK-LABEL: @memcpy_constant_byref_arg_ptr_to_alloca(83; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i6484; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr addrspace(4) [[ARG:%.*]], i64 [[TMP1]]85; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(4) [[GEP]], align 186; CHECK-NEXT: store i8 [[LOAD]], ptr addrspace(1) [[OUT:%.*]], align 187; CHECK-NEXT: ret void88;89 %alloca = alloca [32 x i8], align 4, addrspace(5)90 call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) %alloca, ptr addrspace(4) %arg, i64 32, i1 false)91 %gep = getelementptr inbounds [32 x i8], ptr addrspace(5) %alloca, i32 0, i32 %idx92 %load = load i8, ptr addrspace(5) %gep93 store i8 %load, ptr addrspace(1) %out94 ret void95}96 97; Simple memcpy to alloca from byref constant address space argument, but not enough bytes are dereferenceable98define amdgpu_kernel void @memcpy_constant_byref_arg_ptr_to_alloca_too_many_bytes(ptr addrspace(4) noalias readonly align 4 byref([31 x i8]) %arg, ptr addrspace(1) %out, i32 %idx) {99; CHECK-LABEL: @memcpy_constant_byref_arg_ptr_to_alloca_too_many_bytes(100; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i8], align 4, addrspace(5)101; CHECK-NEXT: call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) noundef align 4 dereferenceable(31) [[ALLOCA]], ptr addrspace(4) noundef align 4 dereferenceable(31) [[ARG:%.*]], i64 31, i1 false)102; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[ALLOCA]], i32 [[IDX:%.*]]103; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(5) [[GEP]], align 1104; CHECK-NEXT: store i8 [[LOAD]], ptr addrspace(1) [[OUT:%.*]], align 1105; CHECK-NEXT: ret void106;107 %alloca = alloca [32 x i8], align 4, addrspace(5)108 call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) %alloca, ptr addrspace(4) %arg, i64 31, i1 false)109 %gep = getelementptr inbounds [32 x i8], ptr addrspace(5) %alloca, i32 0, i32 %idx110 %load = load i8, ptr addrspace(5) %gep111 store i8 %load, ptr addrspace(1) %out112 ret void113}114 115; Simple memcpy to alloca from constant address space intrinsic call116define amdgpu_kernel void @memcpy_constant_intrinsic_ptr_to_alloca(ptr addrspace(1) %out, i32 %idx) {117; CHECK-LABEL: @memcpy_constant_intrinsic_ptr_to_alloca(118; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i8], align 4, addrspace(5)119; CHECK-NEXT: [[KERNARG_SEGMENT_PTR:%.*]] = call align 16 dereferenceable(32) ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr()120; CHECK-NEXT: call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) noundef align 4 dereferenceable(32) [[ALLOCA]], ptr addrspace(4) noundef align 16 dereferenceable(32) [[KERNARG_SEGMENT_PTR]], i64 32, i1 false)121; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[ALLOCA]], i32 [[IDX:%.*]]122; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(5) [[GEP]], align 1123; CHECK-NEXT: store i8 [[LOAD]], ptr addrspace(1) [[OUT:%.*]], align 1124; CHECK-NEXT: ret void125;126 %alloca = alloca [32 x i8], align 4, addrspace(5)127 %kernarg.segment.ptr = call dereferenceable(32) align 16 ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr()128 call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) %alloca, ptr addrspace(4) %kernarg.segment.ptr, i64 32, i1 false)129 %gep = getelementptr inbounds [32 x i8], ptr addrspace(5) %alloca, i32 0, i32 %idx130 %load = load i8, ptr addrspace(5) %gep131 store i8 %load, ptr addrspace(1) %out132 ret void133}134 135; Alloca is written through a flat pointer136define i8 @memcpy_constant_arg_ptr_to_alloca_addrspacecast_to_flat(ptr addrspace(4) noalias readonly align 4 dereferenceable(32) %arg, i32 %idx) {137; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca_addrspacecast_to_flat(138; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64139; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr addrspace(4) [[ARG:%.*]], i64 [[TMP1]]140; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(4) [[GEP]], align 1141; CHECK-NEXT: ret i8 [[LOAD]]142;143 %alloca = alloca [32 x i8], align 4, addrspace(5)144 %alloca.cast.asc = addrspacecast ptr addrspace(5) %alloca to ptr145 call void @llvm.memcpy.p0.p4.i64(ptr %alloca.cast.asc, ptr addrspace(4) %arg, i64 31, i1 false)146 %gep = getelementptr inbounds [32 x i8], ptr addrspace(5) %alloca, i32 0, i32 %idx147 %load = load i8, ptr addrspace(5) %gep148 ret i8 %load149}150 151; Alloca is only addressed through flat pointer.152define i8 @memcpy_constant_arg_ptr_to_alloca_addrspacecast_to_flat2(ptr addrspace(4) noalias readonly align 4 dereferenceable(32) %arg, i32 %idx) {153; CHECK-LABEL: @memcpy_constant_arg_ptr_to_alloca_addrspacecast_to_flat2(154; CHECK-NEXT: [[ALLOCA_CAST_ASC:%.*]] = addrspacecast ptr addrspace(4) [[ARG:%.*]] to ptr155; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64156; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[ALLOCA_CAST_ASC]], i64 [[TMP1]]157; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr [[GEP]], align 1158; CHECK-NEXT: ret i8 [[LOAD]]159;160 %alloca = alloca [32 x i8], align 4, addrspace(5)161 %alloca.cast.asc = addrspacecast ptr addrspace(5) %alloca to ptr162 call void @llvm.memcpy.p0.p4.i64(ptr %alloca.cast.asc, ptr addrspace(4) %arg, i64 32, i1 false)163 %gep = getelementptr inbounds [32 x i8], ptr %alloca.cast.asc, i32 0, i32 %idx164 %load = load i8, ptr %gep165 ret i8 %load166}167 168%struct.ty = type { [4 x i32] }169 170define amdgpu_kernel void @byref_infloop(ptr %scratch, ptr addrspace(4) byref(%struct.ty) align 4 %arg) local_unnamed_addr #1 {171; CHECK-LABEL: @byref_infloop(172; CHECK-NEXT: bb:173; CHECK-NEXT: call void @llvm.memcpy.p0.p4.i32(ptr noundef nonnull align 4 dereferenceable(16) [[SCRATCH:%.*]], ptr addrspace(4) noundef align 4 dereferenceable(16) [[ARG:%.*]], i32 16, i1 false)174; CHECK-NEXT: ret void175;176bb:177 %alloca = alloca [4 x i32], align 4, addrspace(5)178 call void @llvm.memcpy.p5.p4.i32(ptr addrspace(5) align 4 %alloca, ptr addrspace(4) align 4 %arg, i32 16, i1 false)179 call void @llvm.memcpy.p0.p5.i32(ptr align 4 %scratch, ptr addrspace(5) align 4 %alloca, i32 16, i1 false)180 ret void181}182 183define amdgpu_kernel void @byref_infloop_metadata(ptr %scratch, ptr addrspace(4) byref(%struct.ty) align 4 %arg) local_unnamed_addr #1 {184; CHECK-LABEL: @byref_infloop_metadata(185; CHECK-NEXT: bb:186; CHECK-NEXT: call void @llvm.memcpy.p0.p4.i32(ptr noundef nonnull align 4 dereferenceable(16) [[SCRATCH:%.*]], ptr addrspace(4) noundef align 4 dereferenceable(16) [[ARG:%.*]], i32 16, i1 false), !noalias [[META0]]187; CHECK-NEXT: ret void188;189bb:190 %alloca = alloca [4 x i32], align 4, addrspace(5)191 call void @llvm.memcpy.p5.p4.i32(ptr addrspace(5) align 4 %alloca, ptr addrspace(4) align 4 %arg, i32 16, i1 false), !noalias !0192 call void @llvm.memcpy.p0.p5.i32(ptr align 4 %scratch, ptr addrspace(5) align 4 %alloca, i32 16, i1 false), !noalias !0193 ret void194}195 196define amdgpu_kernel void @byref_infloop_addrspacecast(ptr %scratch, ptr addrspace(4) byref(%struct.ty) align 4 %arg) local_unnamed_addr #1 {197; CHECK-LABEL: @byref_infloop_addrspacecast(198; CHECK-NEXT: bb:199; CHECK-NEXT: [[ADDRSPACECAST_ALLOCA:%.*]] = addrspacecast ptr addrspace(4) [[ARG:%.*]] to ptr200; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(16) [[SCRATCH:%.*]], ptr noundef nonnull align 4 dereferenceable(16) [[ADDRSPACECAST_ALLOCA]], i64 16, i1 false)201; CHECK-NEXT: ret void202;203bb:204 %alloca = alloca [4 x i32], align 4, addrspace(5)205 %addrspacecast.alloca = addrspacecast ptr addrspace(5) %alloca to ptr206 call void @llvm.memcpy.p0.p4.i64(ptr nonnull align 4 dereferenceable(16) %addrspacecast.alloca, ptr addrspace(4) align 4 dereferenceable(16) %arg, i64 16, i1 false)207 call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 4 dereferenceable(16) %scratch, ptr nonnull align 4 dereferenceable(16) %addrspacecast.alloca, i64 16, i1 false)208 ret void209}210 211define amdgpu_kernel void @byref_infloop_memmove(ptr %scratch, ptr addrspace(4) byref(%struct.ty) align 4 %arg) local_unnamed_addr #1 {212; CHECK-LABEL: @byref_infloop_memmove(213; CHECK-NEXT: bb:214; CHECK-NEXT: call void @llvm.memmove.p0.p4.i32(ptr noundef nonnull align 4 dereferenceable(16) [[SCRATCH:%.*]], ptr addrspace(4) noundef align 4 dereferenceable(16) [[ARG:%.*]], i32 16, i1 false)215; CHECK-NEXT: ret void216;217bb:218 %alloca = alloca [4 x i32], align 4, addrspace(5)219 call void @llvm.memmove.p5.p4.i32(ptr addrspace(5) align 4 %alloca, ptr addrspace(4) align 4 %arg, i32 16, i1 false)220 call void @llvm.memmove.p0.p5.i32(ptr align 4 %scratch, ptr addrspace(5) align 4 %alloca, i32 16, i1 false)221 ret void222}223 224declare void @llvm.memcpy.p0.p5.i32(ptr noalias nocapture writeonly, ptr addrspace(5) noalias nocapture readonly, i32, i1 immarg) #0225declare void @llvm.memcpy.p5.p4.i32(ptr addrspace(5) nocapture, ptr addrspace(4) nocapture, i32, i1) #0226declare void @llvm.memcpy.p0.p4.i64(ptr nocapture, ptr addrspace(4) nocapture, i64, i1) #0227declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #0228declare void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) nocapture, ptr addrspace(4) nocapture, i64, i1) #0229declare void @llvm.memmove.p5.p4.i32(ptr addrspace(5) nocapture, ptr addrspace(4) nocapture, i32, i1) #0230declare void @llvm.memmove.p0.p5.i32(ptr nocapture, ptr addrspace(5) nocapture, i32, i1) #0231declare ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() #1232 233attributes #0 = { argmemonly nounwind willreturn }234attributes #1 = { nounwind readnone speculatable }235 236!0 = !{!1}237!1 = !{!1, !2}238!2 = !{!2}239