415 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=sroa,amdgpu-promote-alloca < %s | FileCheck %s3 4; Make sure that array alloca loaded and stored as multi-element aggregates are handled correctly5; Strictly the promote-alloca pass shouldn't have to deal with this case as it is non-canonical, but6; the pass should handle it gracefully if it is7; The checks look for lines that previously caused issues in PromoteAlloca (non-canonical). Opt8; should now leave these unchanged9 10%Block = type { [1 x float], i32 }11%gl_PerVertex = type { <4 x float>, float, [1 x float], [1 x float] }12%struct = type { i32, i32 }13 14@block = external addrspace(1) global %Block15@pv = external addrspace(1) global %gl_PerVertex16 17define amdgpu_vs void @promote_1d_aggr() #0 {18; CHECK-LABEL: @promote_1d_aggr(19; CHECK-NEXT: [[F1:%.*]] = alloca [1 x float], align 4, addrspace(5)20; CHECK-NEXT: [[FOO:%.*]] = getelementptr [[BLOCK:%.*]], ptr addrspace(1) @block, i32 0, i32 121; CHECK-NEXT: [[FOO1:%.*]] = load i32, ptr addrspace(1) [[FOO]], align 422; CHECK-NEXT: [[FOO3:%.*]] = load [1 x float], ptr addrspace(1) @block, align 423; CHECK-NEXT: [[FOO3_FCA_0_EXTRACT:%.*]] = extractvalue [1 x float] [[FOO3]], 024; CHECK-NEXT: [[FOO3_FCA_0_GEP:%.*]] = getelementptr inbounds [1 x float], ptr addrspace(5) [[F1]], i32 0, i32 025; CHECK-NEXT: store float [[FOO3_FCA_0_EXTRACT]], ptr addrspace(5) [[FOO3_FCA_0_GEP]], align 426; CHECK-NEXT: [[FOO5:%.*]] = getelementptr [1 x float], ptr addrspace(5) [[F1]], i32 0, i32 [[FOO1]]27; CHECK-NEXT: [[FOO6:%.*]] = load float, ptr addrspace(5) [[FOO5]], align 428; CHECK-NEXT: [[FOO9:%.*]] = insertelement <4 x float> undef, float [[FOO6]], i32 029; CHECK-NEXT: [[FOO10:%.*]] = insertelement <4 x float> [[FOO9]], float [[FOO6]], i32 130; CHECK-NEXT: [[FOO11:%.*]] = insertelement <4 x float> [[FOO10]], float [[FOO6]], i32 231; CHECK-NEXT: [[FOO12:%.*]] = insertelement <4 x float> [[FOO11]], float [[FOO6]], i32 332; CHECK-NEXT: store <4 x float> [[FOO12]], ptr addrspace(1) @pv, align 1633; CHECK-NEXT: ret void34;35 %i = alloca i32, addrspace(5)36 %f1 = alloca [1 x float], addrspace(5)37 %foo = getelementptr %Block, ptr addrspace(1) @block, i32 0, i32 138 %foo1 = load i32, ptr addrspace(1) %foo39 store i32 %foo1, ptr addrspace(5) %i40 %foo3 = load [1 x float], ptr addrspace(1) @block41 store [1 x float] %foo3, ptr addrspace(5) %f142 %foo4 = load i32, ptr addrspace(5) %i43 %foo5 = getelementptr [1 x float], ptr addrspace(5) %f1, i32 0, i32 %foo444 %foo6 = load float, ptr addrspace(5) %foo545 %foo7 = alloca <4 x float>, addrspace(5)46 %foo8 = load <4 x float>, ptr addrspace(5) %foo747 %foo9 = insertelement <4 x float> %foo8, float %foo6, i32 048 %foo10 = insertelement <4 x float> %foo9, float %foo6, i32 149 %foo11 = insertelement <4 x float> %foo10, float %foo6, i32 250 %foo12 = insertelement <4 x float> %foo11, float %foo6, i32 351 store <4 x float> %foo12, ptr addrspace(1) @pv52 ret void53}54 55%Block2 = type { i32, [2 x float] }56@block2 = external addrspace(1) global %Block257 58define amdgpu_vs void @promote_store_aggr() #0 {59; CHECK-LABEL: @promote_store_aggr(60; CHECK-NEXT: [[FOO1:%.*]] = load i32, ptr addrspace(1) @block2, align 461; CHECK-NEXT: [[FOO3:%.*]] = sitofp i32 [[FOO1]] to float62; CHECK-NEXT: [[FOO6_FCA_0_INSERT:%.*]] = insertvalue [2 x float] poison, float [[FOO3]], 063; CHECK-NEXT: [[FOO6_FCA_1_INSERT:%.*]] = insertvalue [2 x float] [[FOO6_FCA_0_INSERT]], float 2.000000e+00, 164; CHECK-NEXT: [[FOO7:%.*]] = getelementptr [[BLOCK2:%.*]], ptr addrspace(1) @block2, i32 0, i32 165; CHECK-NEXT: store [2 x float] [[FOO6_FCA_1_INSERT]], ptr addrspace(1) [[FOO7]], align 466; CHECK-NEXT: store <4 x float> splat (float 1.000000e+00), ptr addrspace(1) @pv, align 1667; CHECK-NEXT: ret void68;69 %i = alloca i32, addrspace(5)70 %f1 = alloca [2 x float], addrspace(5)71 %foo1 = load i32, ptr addrspace(1) @block272 store i32 %foo1, ptr addrspace(5) %i73 %foo2 = load i32, ptr addrspace(5) %i74 %foo3 = sitofp i32 %foo2 to float75 store float %foo3, ptr addrspace(5) %f176 %foo5 = getelementptr [2 x float], ptr addrspace(5) %f1, i32 0, i32 177 store float 2.000000e+00, ptr addrspace(5) %foo578 %foo6 = load [2 x float], ptr addrspace(5) %f179 %foo7 = getelementptr %Block2, ptr addrspace(1) @block2, i32 0, i32 180 store [2 x float] %foo6, ptr addrspace(1) %foo781 store <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, ptr addrspace(1) @pv82 ret void83}84 85%Block3 = type { [2 x float], i32 }86@block3 = external addrspace(1) global %Block387 88define amdgpu_vs void @promote_load_from_store_aggr() #0 {89; CHECK-LABEL: @promote_load_from_store_aggr(90; CHECK-NEXT: [[F1:%.*]] = freeze <2 x float> poison91; CHECK-NEXT: [[FOO:%.*]] = getelementptr [[BLOCK3:%.*]], ptr addrspace(1) @block3, i32 0, i32 192; CHECK-NEXT: [[FOO1:%.*]] = load i32, ptr addrspace(1) [[FOO]], align 493; CHECK-NEXT: [[FOO3:%.*]] = load [2 x float], ptr addrspace(1) @block3, align 494; CHECK-NEXT: [[FOO3_FCA_0_EXTRACT:%.*]] = extractvalue [2 x float] [[FOO3]], 095; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x float> [[F1]], float [[FOO3_FCA_0_EXTRACT]], i32 096; CHECK-NEXT: [[FOO3_FCA_1_EXTRACT:%.*]] = extractvalue [2 x float] [[FOO3]], 197; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x float> [[TMP1]], float [[FOO3_FCA_1_EXTRACT]], i32 198; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x float> [[TMP2]], i32 [[FOO1]]99; CHECK-NEXT: [[FOO9:%.*]] = insertelement <4 x float> undef, float [[TMP3]], i32 0100; CHECK-NEXT: [[FOO10:%.*]] = insertelement <4 x float> [[FOO9]], float [[TMP3]], i32 1101; CHECK-NEXT: [[FOO11:%.*]] = insertelement <4 x float> [[FOO10]], float [[TMP3]], i32 2102; CHECK-NEXT: [[FOO12:%.*]] = insertelement <4 x float> [[FOO11]], float [[TMP3]], i32 3103; CHECK-NEXT: store <4 x float> [[FOO12]], ptr addrspace(1) @pv, align 16104; CHECK-NEXT: ret void105;106 %i = alloca i32, addrspace(5)107 %f1 = alloca [2 x float], addrspace(5)108 %foo = getelementptr %Block3, ptr addrspace(1) @block3, i32 0, i32 1109 %foo1 = load i32, ptr addrspace(1) %foo110 store i32 %foo1, ptr addrspace(5) %i111 %foo3 = load [2 x float], ptr addrspace(1) @block3112 store [2 x float] %foo3, ptr addrspace(5) %f1113 %foo4 = load i32, ptr addrspace(5) %i114 %foo5 = getelementptr [2 x float], ptr addrspace(5) %f1, i32 0, i32 %foo4115 %foo6 = load float, ptr addrspace(5) %foo5116 %foo7 = alloca <4 x float>, addrspace(5)117 %foo8 = load <4 x float>, ptr addrspace(5) %foo7118 %foo9 = insertelement <4 x float> %foo8, float %foo6, i32 0119 %foo10 = insertelement <4 x float> %foo9, float %foo6, i32 1120 %foo11 = insertelement <4 x float> %foo10, float %foo6, i32 2121 %foo12 = insertelement <4 x float> %foo11, float %foo6, i32 3122 store <4 x float> %foo12, ptr addrspace(1) @pv123 ret void124}125 126%Block4 = type { [2 x i32], i32 }127@block4 = external addrspace(1) global %Block4128%gl_PV = type { <4 x i32>, i32, [1 x i32], [1 x i32] }129@pv1 = external addrspace(1) global %gl_PV130 131; This should not crash on an aliased variable offset that can be132; optimized out (variable %aliasTofoo3 in the test)133define amdgpu_vs void @promote_load_from_store_aggr_varoff(<4 x i32> %input) {134; CHECK-LABEL: @promote_load_from_store_aggr_varoff(135; CHECK-NEXT: [[F1:%.*]] = freeze <3 x i32> poison136; CHECK-NEXT: [[FOO3_UNPACK2:%.*]] = load i32, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) @block4, i64 8), align 4137; CHECK-NEXT: [[TMP1:%.*]] = insertelement <3 x i32> [[F1]], i32 [[FOO3_UNPACK2]], i32 2138; CHECK-NEXT: [[TMP2:%.*]] = extractelement <3 x i32> [[TMP1]], i32 [[FOO3_UNPACK2]]139; CHECK-NEXT: [[FOO12:%.*]] = insertelement <4 x i32> [[INPUT:%.*]], i32 [[TMP2]], i64 3140; CHECK-NEXT: store <4 x i32> [[FOO12]], ptr addrspace(1) @pv1, align 16141; CHECK-NEXT: ret void142;143 %f1 = alloca [3 x i32], align 4, addrspace(5)144 %G1 = getelementptr inbounds i8, ptr addrspace(5) %f1, i32 8145 %foo3.unpack2 = load i32, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) @block4, i64 8), align 4146 store i32 %foo3.unpack2, ptr addrspace(5) %G1, align 4147 %aliasTofoo3 = load i32, ptr addrspace(5) %G1, align 4148 %foo5 = getelementptr [3 x i32], ptr addrspace(5) %f1, i32 0, i32 %aliasTofoo3149 %foo6 = load i32, ptr addrspace(5) %foo5, align 4150 %foo12 = insertelement <4 x i32> %input, i32 %foo6, i64 3151 store <4 x i32> %foo12, ptr addrspace(1) @pv1, align 16152 ret void153}154 155define amdgpu_vs void @promote_memmove_aggr() #0 {156; CHECK-LABEL: @promote_memmove_aggr(157; CHECK-NEXT: [[F1:%.*]] = freeze <5 x float> poison158; CHECK-NEXT: [[TMP1:%.*]] = insertelement <5 x float> [[F1]], float 0.000000e+00, i32 0159; CHECK-NEXT: [[TMP2:%.*]] = insertelement <5 x float> [[TMP1]], float 0.000000e+00, i32 1160; CHECK-NEXT: [[TMP3:%.*]] = insertelement <5 x float> [[TMP2]], float 0.000000e+00, i32 2161; CHECK-NEXT: [[TMP4:%.*]] = insertelement <5 x float> [[TMP3]], float 0.000000e+00, i32 3162; CHECK-NEXT: [[TMP5:%.*]] = insertelement <5 x float> [[TMP4]], float 0.000000e+00, i32 4163; CHECK-NEXT: [[TMP6:%.*]] = insertelement <5 x float> [[TMP5]], float 1.000000e+00, i32 1164; CHECK-NEXT: [[TMP7:%.*]] = insertelement <5 x float> [[TMP6]], float 2.000000e+00, i32 3165; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <5 x float> [[TMP7]], <5 x float> poison, <5 x i32> <i32 1, i32 2, i32 3, i32 4, i32 4>166; CHECK-NEXT: store float 1.000000e+00, ptr addrspace(1) @pv, align 4167; CHECK-NEXT: ret void168;169 %f1 = alloca [5 x float], addrspace(5)170 store [5 x float] zeroinitializer, ptr addrspace(5) %f1171 %foo1 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 1172 store float 1.0, ptr addrspace(5) %foo1173 %foo2 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 3174 store float 2.0, ptr addrspace(5) %foo2175 call void @llvm.memmove.p5.p5.i32(ptr addrspace(5) align 4 %f1, ptr addrspace(5) align 4 %foo1, i32 16, i1 false)176 %foo3 = load float, ptr addrspace(5) %f1177 store float %foo3, ptr addrspace(1) @pv178 ret void179}180 181define amdgpu_vs void @promote_memcpy_aggr() #0 {182; CHECK-LABEL: @promote_memcpy_aggr(183; CHECK-NEXT: [[F1:%.*]] = freeze <5 x float> poison184; CHECK-NEXT: [[TMP7:%.*]] = insertelement <5 x float> [[F1]], float 0.000000e+00, i32 0185; CHECK-NEXT: [[TMP8:%.*]] = insertelement <5 x float> [[TMP7]], float 0.000000e+00, i32 1186; CHECK-NEXT: [[TMP9:%.*]] = insertelement <5 x float> [[TMP8]], float 0.000000e+00, i32 2187; CHECK-NEXT: [[TMP4:%.*]] = insertelement <5 x float> [[TMP9]], float 0.000000e+00, i32 3188; CHECK-NEXT: [[TMP5:%.*]] = insertelement <5 x float> [[TMP4]], float 0.000000e+00, i32 4189; CHECK-NEXT: [[TMP6:%.*]] = insertelement <5 x float> [[TMP5]], float 2.000000e+00, i32 3190; CHECK-NEXT: [[FOO3:%.*]] = getelementptr [[BLOCK3:%.*]], ptr addrspace(1) @block3, i32 0, i32 0191; CHECK-NEXT: [[FOO4:%.*]] = load i32, ptr addrspace(1) [[FOO3]], align 4192; CHECK-NEXT: [[TMP1:%.*]] = insertelement <5 x float> [[TMP6]], float 3.000000e+00, i32 [[FOO4]]193; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <5 x float> [[TMP1]], <5 x float> poison, <5 x i32> <i32 3, i32 4, i32 2, i32 3, i32 4>194; CHECK-NEXT: [[TMP3:%.*]] = extractelement <5 x float> [[TMP2]], i32 0195; CHECK-NEXT: store float [[TMP3]], ptr addrspace(1) @pv, align 4196; CHECK-NEXT: ret void197;198 %f1 = alloca [5 x float], addrspace(5)199 store [5 x float] zeroinitializer, ptr addrspace(5) %f1200 201 %foo2 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 3202 store float 2.0, ptr addrspace(5) %foo2203 204 %foo3 = getelementptr %Block3, ptr addrspace(1) @block3, i32 0, i32 0205 %foo4 = load i32, ptr addrspace(1) %foo3206 %foo5 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 %foo4207 store float 3.0, ptr addrspace(5) %foo5208 209 call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) align 4 %f1, ptr addrspace(5) align 4 %foo2, i32 8, i1 false)210 %foo6 = load float, ptr addrspace(5) %f1211 store float %foo6, ptr addrspace(1) @pv212 ret void213}214 215define amdgpu_vs void @promote_memcpy_identity_aggr() #0 {216; CHECK-LABEL: @promote_memcpy_identity_aggr(217; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(1) @pv, align 4218; CHECK-NEXT: ret void219;220 %f1 = alloca [5 x float], addrspace(5)221 store [5 x float] zeroinitializer, ptr addrspace(5) %f1222 %foo1 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 1223 store float 1.0, ptr addrspace(5) %foo1224 %foo2 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 3225 store float 2.0, ptr addrspace(5) %foo2226 call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) align 4 %f1, ptr addrspace(5) align 4 %f1, i32 20, i1 false)227 %foo3 = load float, ptr addrspace(5) %f1228 store float %foo3, ptr addrspace(1) @pv229 ret void230}231 232; TODO: promote alloca even there is a memcpy between different alloca233define amdgpu_vs void @promote_memcpy_two_aggrs() #0 {234; CHECK-LABEL: @promote_memcpy_two_aggrs(235; CHECK-NEXT: [[F1:%.*]] = alloca [5 x float], align 4, addrspace(5)236; CHECK-NEXT: [[F2:%.*]] = alloca [5 x float], align 4, addrspace(5)237; CHECK-NEXT: [[DOTFCA_0_GEP1:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 0238; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_0_GEP1]], align 4239; CHECK-NEXT: [[DOTFCA_1_GEP2:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 1240; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_1_GEP2]], align 4241; CHECK-NEXT: [[DOTFCA_2_GEP3:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 2242; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_2_GEP3]], align 4243; CHECK-NEXT: [[DOTFCA_3_GEP4:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 3244; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_3_GEP4]], align 4245; CHECK-NEXT: [[DOTFCA_4_GEP5:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 4246; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_4_GEP5]], align 4247; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 0248; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_0_GEP]], align 4249; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 1250; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_1_GEP]], align 4251; CHECK-NEXT: [[DOTFCA_2_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 2252; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_2_GEP]], align 4253; CHECK-NEXT: [[DOTFCA_3_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 3254; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_3_GEP]], align 4255; CHECK-NEXT: [[DOTFCA_4_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 4256; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_4_GEP]], align 4257; CHECK-NEXT: [[FOO3:%.*]] = getelementptr [[BLOCK3:%.*]], ptr addrspace(1) @block3, i32 0, i32 0258; CHECK-NEXT: [[FOO4:%.*]] = load i32, ptr addrspace(1) [[FOO3]], align 4259; CHECK-NEXT: [[FOO5:%.*]] = getelementptr [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 [[FOO4]]260; CHECK-NEXT: store float 3.000000e+00, ptr addrspace(5) [[FOO5]], align 4261; CHECK-NEXT: call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) align 4 [[F2]], ptr addrspace(5) align 4 [[F1]], i32 8, i1 false)262; CHECK-NEXT: [[FOO6:%.*]] = getelementptr [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 [[FOO4]]263; CHECK-NEXT: [[FOO7:%.*]] = load float, ptr addrspace(5) [[FOO6]], align 4264; CHECK-NEXT: store float [[FOO7]], ptr addrspace(1) @pv, align 4265; CHECK-NEXT: ret void266;267 %f1 = alloca [5 x float], addrspace(5)268 %f2 = alloca [5 x float], addrspace(5)269 270 store [5 x float] zeroinitializer, ptr addrspace(5) %f1271 store [5 x float] zeroinitializer, ptr addrspace(5) %f2272 273 %foo3 = getelementptr %Block3, ptr addrspace(1) @block3, i32 0, i32 0274 %foo4 = load i32, ptr addrspace(1) %foo3275 %foo5 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 %foo4276 store float 3.0, ptr addrspace(5) %foo5277 278 call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) align 4 %f2, ptr addrspace(5) align 4 %f1, i32 8, i1 false)279 280 %foo6 = getelementptr [5 x float], ptr addrspace(5) %f2, i32 0, i32 %foo4281 %foo7 = load float, ptr addrspace(5) %foo6282 store float %foo7, ptr addrspace(1) @pv283 ret void284}285 286; TODO: promote alloca even there is a memcpy between the alloca and other memory space.287define amdgpu_vs void @promote_memcpy_p1p5_aggr(ptr addrspace(1) inreg %src) #0 {288; CHECK-LABEL: @promote_memcpy_p1p5_aggr(289; CHECK-NEXT: [[F1:%.*]] = alloca [5 x float], align 4, addrspace(5)290; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 0291; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_0_GEP]], align 4292; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 1293; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_1_GEP]], align 4294; CHECK-NEXT: [[DOTFCA_2_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 2295; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_2_GEP]], align 4296; CHECK-NEXT: [[DOTFCA_3_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 3297; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_3_GEP]], align 4298; CHECK-NEXT: [[DOTFCA_4_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 4299; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_4_GEP]], align 4300; CHECK-NEXT: [[FOO3:%.*]] = getelementptr [[BLOCK3:%.*]], ptr addrspace(1) @block3, i32 0, i32 0301; CHECK-NEXT: [[FOO4:%.*]] = load i32, ptr addrspace(1) [[FOO3]], align 4302; CHECK-NEXT: [[FOO5:%.*]] = getelementptr [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 [[FOO4]]303; CHECK-NEXT: store float 3.000000e+00, ptr addrspace(5) [[FOO5]], align 4304; CHECK-NEXT: call void @llvm.memcpy.p1.p5.i32(ptr addrspace(1) align 4 @pv, ptr addrspace(5) align 4 [[F1]], i32 8, i1 false)305; CHECK-NEXT: ret void306;307 %f1 = alloca [5 x float], addrspace(5)308 store [5 x float] zeroinitializer, ptr addrspace(5) %f1309 310 %foo3 = getelementptr %Block3, ptr addrspace(1) @block3, i32 0, i32 0311 %foo4 = load i32, ptr addrspace(1) %foo3312 %foo5 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 %foo4313 store float 3.0, ptr addrspace(5) %foo5314 315 call void @llvm.memcpy.p1.p5.i32(ptr addrspace(1) align 4 @pv, ptr addrspace(5) align 4 %f1, i32 8, i1 false)316 ret void317}318 319define amdgpu_vs void @promote_memcpy_inline_aggr() #0 {320; CHECK-LABEL: @promote_memcpy_inline_aggr(321; CHECK-NEXT: [[F1:%.*]] = freeze <5 x float> poison322; CHECK-NEXT: [[TMP6:%.*]] = insertelement <5 x float> [[F1]], float 0.000000e+00, i32 0323; CHECK-NEXT: [[TMP7:%.*]] = insertelement <5 x float> [[TMP6]], float 0.000000e+00, i32 1324; CHECK-NEXT: [[TMP8:%.*]] = insertelement <5 x float> [[TMP7]], float 0.000000e+00, i32 2325; CHECK-NEXT: [[TMP4:%.*]] = insertelement <5 x float> [[TMP8]], float 0.000000e+00, i32 3326; CHECK-NEXT: [[TMP5:%.*]] = insertelement <5 x float> [[TMP4]], float 0.000000e+00, i32 4327; CHECK-NEXT: [[FOO3:%.*]] = getelementptr [[BLOCK3:%.*]], ptr addrspace(1) @block3, i32 0, i32 0328; CHECK-NEXT: [[FOO4:%.*]] = load i32, ptr addrspace(1) [[FOO3]], align 4329; CHECK-NEXT: [[TMP1:%.*]] = insertelement <5 x float> [[TMP5]], float 3.000000e+00, i32 [[FOO4]]330; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <5 x float> [[TMP1]], <5 x float> poison, <5 x i32> <i32 3, i32 4, i32 2, i32 3, i32 4>331; CHECK-NEXT: [[TMP3:%.*]] = extractelement <5 x float> [[TMP2]], i32 0332; CHECK-NEXT: store float [[TMP3]], ptr addrspace(1) @pv, align 4333; CHECK-NEXT: ret void334;335 %f1 = alloca [5 x float], addrspace(5)336 store [5 x float] zeroinitializer, ptr addrspace(5) %f1337 338 %foo2 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 3339 %foo3 = getelementptr %Block3, ptr addrspace(1) @block3, i32 0, i32 0340 %foo4 = load i32, ptr addrspace(1) %foo3341 %foo5 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 %foo4342 store float 3.0, ptr addrspace(5) %foo5343 344 call void @llvm.memcpy.inline.p5.p5.i32(ptr addrspace(5) align 4 %f1, ptr addrspace(5) align 4 %foo2, i32 8, i1 false)345 %foo6 = load float, ptr addrspace(5) %f1346 store float %foo6, ptr addrspace(1) @pv347 ret void348}349 350declare void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) nocapture writeonly, ptr addrspace(5) nocapture readonly, i32, i1 immarg)351declare void @llvm.memcpy.p1.p5.i32(ptr addrspace(1) nocapture writeonly, ptr addrspace(5) nocapture readonly, i32, i1 immarg)352declare void @llvm.memcpy.inline.p5.p5.i32(ptr addrspace(5) nocapture writeonly, ptr addrspace(5) nocapture readonly, i32, i1 immarg)353declare void @llvm.memmove.p5.p5.i32(ptr addrspace(5) nocapture writeonly, ptr addrspace(5) nocapture readonly, i32, i1 immarg)354 355@tmp_g = external addrspace(1) global { [4 x double], <2 x double>, <3 x double>, <4 x double> }356@frag_color = external addrspace(1) global <4 x float>357 358define amdgpu_ps void @promote_double_aggr() #0 {359; CHECK-LABEL: @promote_double_aggr(360; CHECK-NEXT: [[FOO:%.*]] = getelementptr { [4 x double], <2 x double>, <3 x double>, <4 x double> }, ptr addrspace(1) @tmp_g, i32 0, i32 0, i32 0361; CHECK-NEXT: [[FOO1:%.*]] = load double, ptr addrspace(1) [[FOO]], align 8362; CHECK-NEXT: [[FOO2:%.*]] = getelementptr { [4 x double], <2 x double>, <3 x double>, <4 x double> }, ptr addrspace(1) @tmp_g, i32 0, i32 0, i32 1363; CHECK-NEXT: [[FOO3:%.*]] = load double, ptr addrspace(1) [[FOO2]], align 8364; CHECK-NEXT: [[FOO4:%.*]] = insertvalue [2 x double] poison, double [[FOO1]], 0365; CHECK-NEXT: [[FOO5:%.*]] = insertvalue [2 x double] [[FOO4]], double [[FOO3]], 1366; CHECK-NEXT: [[FOO5_FCA_0_EXTRACT:%.*]] = extractvalue [2 x double] [[FOO5]], 0367; CHECK-NEXT: [[FOO5_FCA_1_EXTRACT:%.*]] = extractvalue [2 x double] [[FOO5]], 1368; CHECK-NEXT: [[FOO10:%.*]] = fadd double [[FOO5_FCA_1_EXTRACT]], [[FOO5_FCA_1_EXTRACT]]369; CHECK-NEXT: [[FOO16:%.*]] = fadd double [[FOO10]], [[FOO5_FCA_1_EXTRACT]]370; CHECK-NEXT: [[FOO17:%.*]] = fptrunc double [[FOO16]] to float371; CHECK-NEXT: [[FOO18:%.*]] = insertelement <4 x float> poison, float [[FOO17]], i32 0372; CHECK-NEXT: [[FOO19:%.*]] = insertelement <4 x float> [[FOO18]], float [[FOO17]], i32 1373; CHECK-NEXT: [[FOO20:%.*]] = insertelement <4 x float> [[FOO19]], float [[FOO17]], i32 2374; CHECK-NEXT: [[FOO21:%.*]] = insertelement <4 x float> [[FOO20]], float [[FOO17]], i32 3375; CHECK-NEXT: store <4 x float> [[FOO21]], ptr addrspace(1) @frag_color, align 16376; CHECK-NEXT: ret void377;378 %s = alloca [2 x double], addrspace(5)379 %foo = getelementptr { [4 x double], <2 x double>, <3 x double>, <4 x double> }, ptr addrspace(1) @tmp_g, i32 0, i32 0, i32 0380 %foo1 = load double, ptr addrspace(1) %foo381 %foo2 = getelementptr { [4 x double], <2 x double>, <3 x double>, <4 x double> }, ptr addrspace(1) @tmp_g, i32 0, i32 0, i32 1382 %foo3 = load double, ptr addrspace(1) %foo2383 %foo4 = insertvalue [2 x double] poison, double %foo1, 0384 %foo5 = insertvalue [2 x double] %foo4, double %foo3, 1385 store [2 x double] %foo5, ptr addrspace(5) %s386 %foo6 = getelementptr [2 x double], ptr addrspace(5) %s, i32 0, i32 1387 %foo7 = load double, ptr addrspace(5) %foo6388 %foo8 = getelementptr [2 x double], ptr addrspace(5) %s, i32 0, i32 1389 %foo9 = load double, ptr addrspace(5) %foo8390 %foo10 = fadd double %foo7, %foo9391 store double %foo10, ptr addrspace(5) %s392 %foo13 = load double, ptr addrspace(5) %s393 %foo14 = getelementptr [2 x double], ptr addrspace(5) %s, i32 0, i32 1394 %foo15 = load double, ptr addrspace(5) %foo14395 %foo16 = fadd double %foo13, %foo15396 %foo17 = fptrunc double %foo16 to float397 %foo18 = insertelement <4 x float> poison, float %foo17, i32 0398 %foo19 = insertelement <4 x float> %foo18, float %foo17, i32 1399 %foo20 = insertelement <4 x float> %foo19, float %foo17, i32 2400 %foo21 = insertelement <4 x float> %foo20, float %foo17, i32 3401 store <4 x float> %foo21, ptr addrspace(1) @frag_color402 ret void403}404 405; Don't crash on a type that isn't a valid vector element.406define amdgpu_kernel void @alloca_struct() #0 {407; CHECK-LABEL: @alloca_struct(408; CHECK-NEXT: entry:409; CHECK-NEXT: ret void410;411entry:412 %alloca = alloca [2 x %struct], align 4, addrspace(5)413 ret void414}415