1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -mtriple=amdgcn-amd-amdhsa < %s -amdgpu-promote-kernel-arguments -infer-address-spaces | FileCheck %s 3; RUN: opt -S -mtriple=amdgcn-amd-amdhsa < %s -passes=amdgpu-promote-kernel-arguments,infer-address-spaces | FileCheck %s 4; RUN: opt -S -mtriple=amdgcn-amd-amdhsa < %s -amdgpu-promote-kernel-arguments -infer-address-spaces | llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 | FileCheck -check-prefix=GCN %s 5 6; GCN-LABEL: ptr_nest_3: 7; GCN-COUNT-2: global_load_dwordx2 8; GCN: global_store_dword 9define amdgpu_kernel void @ptr_nest_3(float** addrspace(1)* nocapture readonly %Arg) { 10; CHECK-LABEL: @ptr_nest_3( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 13; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float**, float** addrspace(1)* [[ARG:%.*]], i32 [[I]] 14; CHECK-NEXT: [[P1_CONST:%.*]] = addrspacecast float** addrspace(1)* [[P1]] to float** addrspace(4)* 15; CHECK-NEXT: [[P2:%.*]] = load float**, float** addrspace(4)* [[P1_CONST]], align 8 16; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float** [[P2]] to float* addrspace(1)* 17; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast float* addrspace(1)* [[TMP0]] to float** 18; CHECK-NEXT: [[P2_FLAT:%.*]] = addrspacecast float* addrspace(1)* [[TMP0]] to float** 19; CHECK-NEXT: [[P2_CONST:%.*]] = addrspacecast float** [[TMP1]] to float* addrspace(4)* 20; CHECK-NEXT: [[P3:%.*]] = load float*, float* addrspace(4)* [[P2_CONST]], align 8 21; CHECK-NEXT: [[TMP2:%.*]] = addrspacecast float* [[P3]] to float addrspace(1)* 22; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[TMP2]], align 4 23; CHECK-NEXT: ret void 24; 25entry: 26 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 27 %p1 = getelementptr inbounds float**, float** addrspace(1)* %Arg, i32 %i 28 %p2 = load float**, float** addrspace(1)* %p1, align 8 29 %p3 = load float*, float** %p2, align 8 30 store float 0.000000e+00, float* %p3, align 4 31 ret void 32} 33 34; GCN-LABEL: ptr_bitcast: 35; GCN: global_load_dwordx2 36; GCN: global_store_dword 37define amdgpu_kernel void @ptr_bitcast(float** nocapture readonly %Arg) { 38; CHECK-LABEL: @ptr_bitcast( 39; CHECK-NEXT: entry: 40; CHECK-NEXT: [[ARG_GLOBAL:%.*]] = addrspacecast float** [[ARG:%.*]] to float* addrspace(1)* 41; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 42; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG_GLOBAL]], i32 [[I]] 43; CHECK-NEXT: [[P1_CAST:%.*]] = bitcast float* addrspace(1)* [[P1]] to i32* addrspace(1)* 44; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast i32* addrspace(1)* [[P1_CAST]] to i32** 45; CHECK-NEXT: [[P1_CAST_CONST:%.*]] = addrspacecast i32** [[TMP0]] to i32* addrspace(4)* 46; CHECK-NEXT: [[P2:%.*]] = load i32*, i32* addrspace(4)* [[P1_CAST_CONST]], align 8 47; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast i32* [[P2]] to i32 addrspace(1)* 48; CHECK-NEXT: store i32 0, i32 addrspace(1)* [[TMP1]], align 4 49; CHECK-NEXT: ret void 50; 51entry: 52 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 53 %p1 = getelementptr inbounds float*, float** %Arg, i32 %i 54 %p1.cast = bitcast float** %p1 to i32** 55 %p2 = load i32*, i32** %p1.cast, align 8 56 store i32 0, i32* %p2, align 4 57 ret void 58} 59 60%struct.S = type { float* } 61 62; GCN-LABEL: ptr_in_struct: 63; GCN: s_load_dwordx2 64; GCN: global_store_dword 65define amdgpu_kernel void @ptr_in_struct(%struct.S addrspace(1)* nocapture readonly %Arg) { 66; CHECK-LABEL: @ptr_in_struct( 67; CHECK-NEXT: entry: 68; CHECK-NEXT: [[P:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], [[STRUCT_S]] addrspace(1)* [[ARG:%.*]], i64 0, i32 0 69; CHECK-NEXT: [[P_CONST:%.*]] = addrspacecast float* addrspace(1)* [[P]] to float* addrspace(4)* 70; CHECK-NEXT: [[P1:%.*]] = load float*, float* addrspace(4)* [[P_CONST]], align 8 71; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* [[P1]] to float addrspace(1)* 72; CHECK-NEXT: [[ID:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 73; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP0]], i32 [[ID]] 74; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[ARRAYIDX]], align 4 75; CHECK-NEXT: ret void 76; 77entry: 78 %p = getelementptr inbounds %struct.S, %struct.S addrspace(1)* %Arg, i64 0, i32 0 79 %p1 = load float*, float* addrspace(1)* %p, align 8 80 %id = tail call i32 @llvm.amdgcn.workitem.id.x() 81 %arrayidx = getelementptr inbounds float, float* %p1, i32 %id 82 store float 0.000000e+00, float* %arrayidx, align 4 83 ret void 84} 85 86@LDS = internal unnamed_addr addrspace(3) global [4 x float] undef, align 16 87 88; GCN-LABEL: flat_ptr_arg: 89; GCN-COUNT-2: global_load_dwordx2 90 91; FIXME: First load is in the constant address space and second is in global 92; because it is clobbered by store. GPU load store vectorizer cannot 93; combine them. Note, this does not happen with -O3 because loads are 94; vectorized in pairs earlier and stay in the global address space. 95 96; GCN: global_load_dword v{{[0-9]+}}, [[PTR:v\[[0-9:]+\]]], off{{$}} 97; GCN: global_load_dwordx3 v[{{[0-9:]+}}], [[PTR]], off offset:4 98; GCN: global_store_dword 99define amdgpu_kernel void @flat_ptr_arg(float** nocapture readonly noalias %Arg, float** nocapture noalias %Out, i32 %X) { 100; CHECK-LABEL: @flat_ptr_arg( 101; CHECK-NEXT: entry: 102; CHECK-NEXT: [[OUT_GLOBAL:%.*]] = addrspacecast float** [[OUT:%.*]] to float* addrspace(1)* 103; CHECK-NEXT: [[ARG_GLOBAL:%.*]] = addrspacecast float** [[ARG:%.*]] to float* addrspace(1)* 104; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 105; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[I]] to i64 106; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG_GLOBAL]], i64 [[IDXPROM]] 107; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* addrspace(1)* [[ARRAYIDX10]] to float** 108; CHECK-NEXT: [[ARRAYIDX10_CONST:%.*]] = addrspacecast float** [[TMP0]] to float* addrspace(4)* 109; CHECK-NEXT: [[I1:%.*]] = load float*, float* addrspace(4)* [[ARRAYIDX10_CONST]], align 8 110; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast float* [[I1]] to float addrspace(1)* 111; CHECK-NEXT: [[TMP2:%.*]] = addrspacecast float addrspace(1)* [[TMP1]] to float* 112; CHECK-NEXT: [[I1_CONST:%.*]] = addrspacecast float* [[TMP2]] to float addrspace(4)* 113; CHECK-NEXT: [[I2:%.*]] = load float, float addrspace(4)* [[I1_CONST]], align 4 114; CHECK-NEXT: [[ARRAYIDX512:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[X:%.*]] 115; CHECK-NEXT: store float [[I2]], float addrspace(3)* [[ARRAYIDX512]], align 4 116; CHECK-NEXT: [[ARRAYIDX3_1:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP1]], i64 1 117; CHECK-NEXT: [[I3:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_1]], align 4 118; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i32 [[X]], 1 119; CHECK-NEXT: [[ARRAYIDX512_1:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_1]] 120; CHECK-NEXT: store float [[I3]], float addrspace(3)* [[ARRAYIDX512_1]], align 4 121; CHECK-NEXT: [[ARRAYIDX3_2:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP1]], i64 2 122; CHECK-NEXT: [[I4:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_2]], align 4 123; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i32 [[X]], 2 124; CHECK-NEXT: [[ARRAYIDX512_2:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_2]] 125; CHECK-NEXT: store float [[I4]], float addrspace(3)* [[ARRAYIDX512_2]], align 4 126; CHECK-NEXT: [[ARRAYIDX3_3:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP1]], i64 3 127; CHECK-NEXT: [[I5:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_3]], align 4 128; CHECK-NEXT: [[ADD_3:%.*]] = add nsw i32 [[X]], 3 129; CHECK-NEXT: [[ARRAYIDX512_3:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_3]] 130; CHECK-NEXT: store float [[I5]], float addrspace(3)* [[ARRAYIDX512_3]], align 4 131; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[X]], -1 132; CHECK-NEXT: [[ARRAYIDX711:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[SUB]] 133; CHECK-NEXT: [[I6:%.*]] = load float, float addrspace(3)* [[ARRAYIDX711]], align 4 134; CHECK-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[OUT_GLOBAL]], i64 [[IDXPROM]] 135; CHECK-NEXT: [[TMP3:%.*]] = addrspacecast float* addrspace(1)* [[ARRAYIDX11]] to float** 136; CHECK-NEXT: [[ARRAYIDX11_CONST:%.*]] = addrspacecast float** [[TMP3]] to float* addrspace(4)* 137; CHECK-NEXT: [[I7:%.*]] = load float*, float* addrspace(4)* [[ARRAYIDX11_CONST]], align 8 138; CHECK-NEXT: [[TMP4:%.*]] = addrspacecast float* [[I7]] to float addrspace(1)* 139; CHECK-NEXT: [[IDXPROM8:%.*]] = sext i32 [[X]] to i64 140; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP4]], i64 [[IDXPROM8]] 141; CHECK-NEXT: store float [[I6]], float addrspace(1)* [[ARRAYIDX9]], align 4 142; CHECK-NEXT: ret void 143; 144entry: 145 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 146 %idxprom = zext i32 %i to i64 147 %arrayidx10 = getelementptr inbounds float*, float** %Arg, i64 %idxprom 148 %i1 = load float*, float** %arrayidx10, align 8 149 %i2 = load float, float* %i1, align 4 150 %arrayidx512 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %X 151 store float %i2, float addrspace(3)* %arrayidx512, align 4 152 %arrayidx3.1 = getelementptr inbounds float, float* %i1, i64 1 153 %i3 = load float, float* %arrayidx3.1, align 4 154 %add.1 = add nsw i32 %X, 1 155 %arrayidx512.1 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.1 156 store float %i3, float addrspace(3)* %arrayidx512.1, align 4 157 %arrayidx3.2 = getelementptr inbounds float, float* %i1, i64 2 158 %i4 = load float, float* %arrayidx3.2, align 4 159 %add.2 = add nsw i32 %X, 2 160 %arrayidx512.2 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.2 161 store float %i4, float addrspace(3)* %arrayidx512.2, align 4 162 %arrayidx3.3 = getelementptr inbounds float, float* %i1, i64 3 163 %i5 = load float, float* %arrayidx3.3, align 4 164 %add.3 = add nsw i32 %X, 3 165 %arrayidx512.3 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.3 166 store float %i5, float addrspace(3)* %arrayidx512.3, align 4 167 %sub = add nsw i32 %X, -1 168 %arrayidx711 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %sub 169 %i6 = load float, float addrspace(3)* %arrayidx711, align 4 170 %arrayidx11 = getelementptr inbounds float*, float** %Out, i64 %idxprom 171 %i7 = load float*, float** %arrayidx11, align 8 172 %idxprom8 = sext i32 %X to i64 173 %arrayidx9 = getelementptr inbounds float, float* %i7, i64 %idxprom8 174 store float %i6, float* %arrayidx9, align 4 175 ret void 176} 177 178; GCN-LABEL: global_ptr_arg: 179; GCN: global_load_dwordx2 180; GCN: global_load_dword v{{[0-9]+}}, [[PTR:v\[[0-9:]+\]]], off{{$}} 181; GCN: global_load_dwordx3 v[{{[0-9:]+}}], [[PTR]], off offset:4 182; GCN: global_store_dword 183define amdgpu_kernel void @global_ptr_arg(float* addrspace(1)* nocapture readonly %Arg, i32 %X) { 184; CHECK-LABEL: @global_ptr_arg( 185; CHECK-NEXT: entry: 186; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 187; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[I]] to i64 188; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG:%.*]], i64 [[IDXPROM]] 189; CHECK-NEXT: [[ARRAYIDX10_CONST:%.*]] = addrspacecast float* addrspace(1)* [[ARRAYIDX10]] to float* addrspace(4)* 190; CHECK-NEXT: [[I1:%.*]] = load float*, float* addrspace(4)* [[ARRAYIDX10_CONST]], align 8 191; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* [[I1]] to float addrspace(1)* 192; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast float addrspace(1)* [[TMP0]] to float* 193; CHECK-NEXT: [[I1_CONST:%.*]] = addrspacecast float* [[TMP1]] to float addrspace(4)* 194; CHECK-NEXT: [[I2:%.*]] = load float, float addrspace(4)* [[I1_CONST]], align 4 195; CHECK-NEXT: [[ARRAYIDX512:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[X:%.*]] 196; CHECK-NEXT: store float [[I2]], float addrspace(3)* [[ARRAYIDX512]], align 4 197; CHECK-NEXT: [[ARRAYIDX3_1:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP0]], i64 1 198; CHECK-NEXT: [[I3:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_1]], align 4 199; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i32 [[X]], 1 200; CHECK-NEXT: [[ARRAYIDX512_1:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_1]] 201; CHECK-NEXT: store float [[I3]], float addrspace(3)* [[ARRAYIDX512_1]], align 4 202; CHECK-NEXT: [[ARRAYIDX3_2:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP0]], i64 2 203; CHECK-NEXT: [[I4:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_2]], align 4 204; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i32 [[X]], 2 205; CHECK-NEXT: [[ARRAYIDX512_2:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_2]] 206; CHECK-NEXT: store float [[I4]], float addrspace(3)* [[ARRAYIDX512_2]], align 4 207; CHECK-NEXT: [[ARRAYIDX3_3:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP0]], i64 3 208; CHECK-NEXT: [[I5:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_3]], align 4 209; CHECK-NEXT: [[ADD_3:%.*]] = add nsw i32 [[X]], 3 210; CHECK-NEXT: [[ARRAYIDX512_3:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_3]] 211; CHECK-NEXT: store float [[I5]], float addrspace(3)* [[ARRAYIDX512_3]], align 4 212; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[X]], -1 213; CHECK-NEXT: [[ARRAYIDX711:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[SUB]] 214; CHECK-NEXT: [[I6:%.*]] = load float, float addrspace(3)* [[ARRAYIDX711]], align 4 215; CHECK-NEXT: [[IDXPROM8:%.*]] = sext i32 [[X]] to i64 216; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP0]], i64 [[IDXPROM8]] 217; CHECK-NEXT: store float [[I6]], float addrspace(1)* [[ARRAYIDX9]], align 4 218; CHECK-NEXT: ret void 219; 220entry: 221 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 222 %idxprom = zext i32 %i to i64 223 %arrayidx10 = getelementptr inbounds float*, float* addrspace(1)* %Arg, i64 %idxprom 224 %i1 = load float*, float* addrspace(1)* %arrayidx10, align 8 225 %i2 = load float, float* %i1, align 4 226 %arrayidx512 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %X 227 store float %i2, float addrspace(3)* %arrayidx512, align 4 228 %arrayidx3.1 = getelementptr inbounds float, float* %i1, i64 1 229 %i3 = load float, float* %arrayidx3.1, align 4 230 %add.1 = add nsw i32 %X, 1 231 %arrayidx512.1 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.1 232 store float %i3, float addrspace(3)* %arrayidx512.1, align 4 233 %arrayidx3.2 = getelementptr inbounds float, float* %i1, i64 2 234 %i4 = load float, float* %arrayidx3.2, align 4 235 %add.2 = add nsw i32 %X, 2 236 %arrayidx512.2 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.2 237 store float %i4, float addrspace(3)* %arrayidx512.2, align 4 238 %arrayidx3.3 = getelementptr inbounds float, float* %i1, i64 3 239 %i5 = load float, float* %arrayidx3.3, align 4 240 %add.3 = add nsw i32 %X, 3 241 %arrayidx512.3 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.3 242 store float %i5, float addrspace(3)* %arrayidx512.3, align 4 243 %sub = add nsw i32 %X, -1 244 %arrayidx711 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %sub 245 %i6 = load float, float addrspace(3)* %arrayidx711, align 4 246 %idxprom8 = sext i32 %X to i64 247 %arrayidx9 = getelementptr inbounds float, float* %i1, i64 %idxprom8 248 store float %i6, float* %arrayidx9, align 4 249 ret void 250} 251 252; GCN-LABEL: global_ptr_arg_clobbered: 253; GCN: global_store_dwordx2 254; GCN: global_load_dwordx2 255; GCN: flat_load_dword 256; GCN: flat_store_dword 257define amdgpu_kernel void @global_ptr_arg_clobbered(float* addrspace(1)* nocapture readonly %Arg, i32 %X) { 258; CHECK-LABEL: @global_ptr_arg_clobbered( 259; CHECK-NEXT: entry: 260; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 261; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[I]] to i64 262; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG:%.*]], i64 [[IDXPROM]] 263; CHECK-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARRAYIDX10]], i32 [[X:%.*]] 264; CHECK-NEXT: store float* null, float* addrspace(1)* [[ARRAYIDX11]], align 4 265; CHECK-NEXT: [[I1:%.*]] = load float*, float* addrspace(1)* [[ARRAYIDX10]], align 8 266; CHECK-NEXT: [[I2:%.*]] = load float, float* [[I1]], align 4 267; CHECK-NEXT: [[ARRAYIDX512:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[X]] 268; CHECK-NEXT: store float [[I2]], float addrspace(3)* [[ARRAYIDX512]], align 4 269; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[X]], -1 270; CHECK-NEXT: [[ARRAYIDX711:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[SUB]] 271; CHECK-NEXT: [[I6:%.*]] = load float, float addrspace(3)* [[ARRAYIDX711]], align 4 272; CHECK-NEXT: [[IDXPROM8:%.*]] = sext i32 [[X]] to i64 273; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float* [[I1]], i64 [[IDXPROM8]] 274; CHECK-NEXT: store float [[I6]], float* [[ARRAYIDX9]], align 4 275; CHECK-NEXT: ret void 276; 277entry: 278 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 279 %idxprom = zext i32 %i to i64 280 %arrayidx10 = getelementptr inbounds float*, float* addrspace(1)* %Arg, i64 %idxprom 281 %arrayidx11 = getelementptr inbounds float*, float* addrspace(1)* %arrayidx10, i32 %X 282 store float* null, float* addrspace(1)* %arrayidx11, align 4 283 %i1 = load float*, float* addrspace(1)* %arrayidx10, align 8 284 %i2 = load float, float* %i1, align 4 285 %arrayidx512 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %X 286 store float %i2, float addrspace(3)* %arrayidx512, align 4 287 %sub = add nsw i32 %X, -1 288 %arrayidx711 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %sub 289 %i6 = load float, float addrspace(3)* %arrayidx711, align 4 290 %idxprom8 = sext i32 %X to i64 291 %arrayidx9 = getelementptr inbounds float, float* %i1, i64 %idxprom8 292 store float %i6, float* %arrayidx9, align 4 293 ret void 294} 295 296; GCN-LABEL: global_ptr_arg_clobbered_after_load: 297; GCN: global_load_dwordx2 298; GCN: global_store_dwordx2 299; GCN: global_load_dword 300; GCN: global_store_dword 301define amdgpu_kernel void @global_ptr_arg_clobbered_after_load(float* addrspace(1)* nocapture readonly %Arg, i32 %X) { 302; CHECK-LABEL: @global_ptr_arg_clobbered_after_load( 303; CHECK-NEXT: entry: 304; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 305; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[I]] to i64 306; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG:%.*]], i64 [[IDXPROM]] 307; CHECK-NEXT: [[ARRAYIDX10_CONST:%.*]] = addrspacecast float* addrspace(1)* [[ARRAYIDX10]] to float* addrspace(4)* 308; CHECK-NEXT: [[I1:%.*]] = load float*, float* addrspace(4)* [[ARRAYIDX10_CONST]], align 8 309; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* [[I1]] to float addrspace(1)* 310; CHECK-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARRAYIDX10]], i32 [[X:%.*]] 311; CHECK-NEXT: store float* null, float* addrspace(1)* [[ARRAYIDX11]], align 4 312; CHECK-NEXT: [[I2:%.*]] = load float, float addrspace(1)* [[TMP0]], align 4 313; CHECK-NEXT: [[ARRAYIDX512:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[X]] 314; CHECK-NEXT: store float [[I2]], float addrspace(3)* [[ARRAYIDX512]], align 4 315; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[X]], -1 316; CHECK-NEXT: [[ARRAYIDX711:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[SUB]] 317; CHECK-NEXT: [[I6:%.*]] = load float, float addrspace(3)* [[ARRAYIDX711]], align 4 318; CHECK-NEXT: [[IDXPROM8:%.*]] = sext i32 [[X]] to i64 319; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP0]], i64 [[IDXPROM8]] 320; CHECK-NEXT: store float [[I6]], float addrspace(1)* [[ARRAYIDX9]], align 4 321; CHECK-NEXT: ret void 322; 323entry: 324 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 325 %idxprom = zext i32 %i to i64 326 %arrayidx10 = getelementptr inbounds float*, float* addrspace(1)* %Arg, i64 %idxprom 327 %i1 = load float*, float* addrspace(1)* %arrayidx10, align 8 328 %arrayidx11 = getelementptr inbounds float*, float* addrspace(1)* %arrayidx10, i32 %X 329 store float* null, float* addrspace(1)* %arrayidx11, align 4 330 %i2 = load float, float* %i1, align 4 331 %arrayidx512 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %X 332 store float %i2, float addrspace(3)* %arrayidx512, align 4 333 %sub = add nsw i32 %X, -1 334 %arrayidx711 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %sub 335 %i6 = load float, float addrspace(3)* %arrayidx711, align 4 336 %idxprom8 = sext i32 %X to i64 337 %arrayidx9 = getelementptr inbounds float, float* %i1, i64 %idxprom8 338 store float %i6, float* %arrayidx9, align 4 339 ret void 340} 341 342; GCN-LABEL: ptr_nest_3_barrier: 343; GCN-COUNT-2: global_load_dwordx2 344; GCN: global_store_dword 345define amdgpu_kernel void @ptr_nest_3_barrier(float** addrspace(1)* nocapture readonly %Arg) { 346; CHECK-LABEL: @ptr_nest_3_barrier( 347; CHECK-NEXT: entry: 348; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 349; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float**, float** addrspace(1)* [[ARG:%.*]], i32 [[I]] 350; CHECK-NEXT: tail call void @llvm.amdgcn.s.barrier() 351; CHECK-NEXT: [[P1_CONST:%.*]] = addrspacecast float** addrspace(1)* [[P1]] to float** addrspace(4)* 352; CHECK-NEXT: [[P2:%.*]] = load float**, float** addrspace(4)* [[P1_CONST]], align 8 353; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float** [[P2]] to float* addrspace(1)* 354; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast float* addrspace(1)* [[TMP0]] to float** 355; CHECK-NEXT: [[P2_FLAT:%.*]] = addrspacecast float* addrspace(1)* [[TMP0]] to float** 356; CHECK-NEXT: [[P2_CONST:%.*]] = addrspacecast float** [[TMP1]] to float* addrspace(4)* 357; CHECK-NEXT: [[P3:%.*]] = load float*, float* addrspace(4)* [[P2_CONST]], align 8 358; CHECK-NEXT: [[TMP2:%.*]] = addrspacecast float* [[P3]] to float addrspace(1)* 359; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[TMP2]], align 4 360; CHECK-NEXT: ret void 361; 362entry: 363 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 364 %p1 = getelementptr inbounds float**, float** addrspace(1)* %Arg, i32 %i 365 tail call void @llvm.amdgcn.s.barrier() 366 %p2 = load float**, float** addrspace(1)* %p1, align 8 367 %p3 = load float*, float** %p2, align 8 368 store float 0.000000e+00, float* %p3, align 4 369 ret void 370} 371 372; GCN-LABEL: flat_ptr_nest_2: 373; GCN: s_lshl_b64 374; GCN: s_load_dwordx2 375; GCN: global_store_dword 376define amdgpu_kernel void @flat_ptr_nest_2(float** nocapture readonly %Arg, i32 %i) { 377; CHECK-LABEL: @flat_ptr_nest_2( 378; CHECK-NEXT: entry: 379; CHECK-NEXT: [[ARG_GLOBAL:%.*]] = addrspacecast float** [[ARG:%.*]] to float* addrspace(1)* 380; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG_GLOBAL]], i32 [[I:%.*]] 381; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* addrspace(1)* [[P1]] to float** 382; CHECK-NEXT: [[P1_CONST:%.*]] = addrspacecast float** [[TMP0]] to float* addrspace(4)* 383; CHECK-NEXT: [[P2:%.*]] = load float*, float* addrspace(4)* [[P1_CONST]], align 8 384; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast float* [[P2]] to float addrspace(1)* 385; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[TMP1]], align 4 386; CHECK-NEXT: ret void 387; 388entry: 389 %p1 = getelementptr inbounds float*, float** %Arg, i32 %i 390 %p2 = load float*, float** %p1, align 8 391 store float 0.000000e+00, float* %p2, align 4 392 ret void 393} 394 395; GCN-LABEL: const_ptr_nest_3: 396; GCN: s_lshl_b64 397; GCN: s_load_dwordx2 398; GCN: s_load_dwordx2 399; GCN: global_store_dword 400define amdgpu_kernel void @const_ptr_nest_3(float* addrspace(4)* addrspace(4)* nocapture readonly %Arg, i32 %i) { 401; CHECK-LABEL: @const_ptr_nest_3( 402; CHECK-NEXT: entry: 403; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float* addrspace(4)*, float* addrspace(4)* addrspace(4)* [[ARG:%.*]], i32 [[I:%.*]] 404; CHECK-NEXT: [[P2:%.*]] = load float* addrspace(4)*, float* addrspace(4)* addrspace(4)* [[P1]], align 8 405; CHECK-NEXT: [[P3:%.*]] = load float*, float* addrspace(4)* [[P2]], align 8 406; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* [[P3]] to float addrspace(1)* 407; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[TMP0]], align 4 408; CHECK-NEXT: ret void 409; 410entry: 411 %p1 = getelementptr inbounds float* addrspace(4)*, float* addrspace(4)* addrspace(4)* %Arg, i32 %i 412 %p2 = load float* addrspace(4)*, float * addrspace(4)* addrspace(4)* %p1, align 8 413 %p3 = load float*, float* addrspace(4)* %p2, align 8 414 store float 0.000000e+00, float* %p3, align 4 415 ret void 416} 417 418; GCN-LABEL: cast_from_const_const_ptr_nest_3: 419; GCN: s_lshl_b64 420; GCN: s_load_dwordx2 421; GCN: s_load_dwordx2 422; GCN: global_store_dword 423define amdgpu_kernel void @cast_from_const_const_ptr_nest_3(float* addrspace(4)* addrspace(4)* nocapture readonly %Arg, i32 %i) { 424; CHECK-LABEL: @cast_from_const_const_ptr_nest_3( 425; CHECK-NEXT: entry: 426; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float* addrspace(4)*, float* addrspace(4)* addrspace(4)* [[ARG:%.*]], i32 [[I:%.*]] 427; CHECK-NEXT: [[P2:%.*]] = load float* addrspace(4)*, float* addrspace(4)* addrspace(4)* [[P1]], align 8 428; CHECK-NEXT: [[P3:%.*]] = load float*, float* addrspace(4)* [[P2]], align 8 429; CHECK-NEXT: [[P3_GLOBAL:%.*]] = addrspacecast float* [[P3]] to float addrspace(1)* 430; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[P3_GLOBAL]], align 4 431; CHECK-NEXT: ret void 432; 433entry: 434 %p1 = getelementptr inbounds float* addrspace(4)*, float* addrspace(4)* addrspace(4)* %Arg, i32 %i 435 %a1 = addrspacecast float* addrspace(4)* addrspace(4)* %p1 to float* addrspace(4)** 436 %p2 = load float* addrspace(4)*, float* addrspace(4)** %a1, align 8 437 %a2 = addrspacecast float* addrspace(4)* %p2 to float** 438 %p3 = load float*, float** %a2, align 8 439 store float 0.000000e+00, float* %p3, align 4 440 ret void 441} 442 443; GCN-LABEL: flat_ptr_volatile_load: 444; GCN: s_lshl_b64 445; GCN: flat_load_dwordx2 446; GCN: global_store_dword 447define amdgpu_kernel void @flat_ptr_volatile_load(float** nocapture readonly %Arg, i32 %i) { 448; CHECK-LABEL: @flat_ptr_volatile_load( 449; CHECK-NEXT: entry: 450; CHECK-NEXT: [[ARG_GLOBAL:%.*]] = addrspacecast float** [[ARG:%.*]] to float* addrspace(1)* 451; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG_GLOBAL]], i32 [[I:%.*]] 452; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* addrspace(1)* [[P1]] to float** 453; CHECK-NEXT: [[P2:%.*]] = load volatile float*, float** [[TMP0]], align 8 454; CHECK-NEXT: [[P2_GLOBAL:%.*]] = addrspacecast float* [[P2]] to float addrspace(1)* 455; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[P2_GLOBAL]], align 4 456; CHECK-NEXT: ret void 457; 458entry: 459 %p1 = getelementptr inbounds float*, float** %Arg, i32 %i 460 %p2 = load volatile float*, float** %p1, align 8 461 store float 0.000000e+00, float* %p2, align 4 462 ret void 463} 464 465; GCN-LABEL: flat_ptr_atomic_load: 466; GCN: s_lshl_b64 467; GCN: global_load_dwordx2 468; GCN: global_store_dword 469define amdgpu_kernel void @flat_ptr_atomic_load(float** nocapture readonly %Arg, i32 %i) { 470; CHECK-LABEL: @flat_ptr_atomic_load( 471; CHECK-NEXT: entry: 472; CHECK-NEXT: [[ARG_GLOBAL:%.*]] = addrspacecast float** [[ARG:%.*]] to float* addrspace(1)* 473; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG_GLOBAL]], i32 [[I:%.*]] 474; CHECK-NEXT: [[P2:%.*]] = load atomic float*, float* addrspace(1)* [[P1]] monotonic, align 8 475; CHECK-NEXT: [[P2_GLOBAL:%.*]] = addrspacecast float* [[P2]] to float addrspace(1)* 476; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[P2_GLOBAL]], align 4 477; CHECK-NEXT: ret void 478; 479entry: 480 %p1 = getelementptr inbounds float*, float** %Arg, i32 %i 481 %p2 = load atomic float*, float** %p1 monotonic, align 8 482 store float 0.000000e+00, float* %p2, align 4 483 ret void 484} 485 486; GCN-LABEL: cast_changing_pointee_type: 487; GCN: s_lshl_b64 488; GCN: s_load_dwordx2 489; GCN: s_load_dwordx2 490; GCN: global_store_dword 491define amdgpu_kernel void @cast_changing_pointee_type(float* addrspace(1)* addrspace(1)* nocapture readonly %Arg, i32 %i) { 492; CHECK-LABEL: @cast_changing_pointee_type( 493; CHECK-NEXT: entry: 494; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float* addrspace(1)*, float* addrspace(1)* addrspace(1)* [[ARG:%.*]], i32 [[I:%.*]] 495; CHECK-NEXT: [[A1:%.*]] = bitcast float* addrspace(1)* addrspace(1)* [[P1]] to i32* addrspace(1)* addrspace(1)* 496; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* addrspace(1)* addrspace(1)* [[P1]] to i32* addrspace(1)** 497; CHECK-NEXT: [[A1_CONST:%.*]] = addrspacecast i32* addrspace(1)** [[TMP0]] to i32* addrspace(1)* addrspace(4)* 498; CHECK-NEXT: [[P2:%.*]] = load i32* addrspace(1)*, i32* addrspace(1)* addrspace(4)* [[A1_CONST]], align 8 499; CHECK-NEXT: [[A2:%.*]] = bitcast i32* addrspace(1)* [[P2]] to float* addrspace(1)* 500; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast i32* addrspace(1)* [[P2]] to float** 501; CHECK-NEXT: [[A2_CONST:%.*]] = addrspacecast float** [[TMP1]] to float* addrspace(4)* 502; CHECK-NEXT: [[P3:%.*]] = load float*, float* addrspace(4)* [[A2_CONST]], align 8 503; CHECK-NEXT: [[TMP2:%.*]] = addrspacecast float* [[P3]] to float addrspace(1)* 504; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[TMP2]], align 4 505; CHECK-NEXT: ret void 506; 507entry: 508 %p1 = getelementptr inbounds float* addrspace(1)*, float* addrspace(1)* addrspace(1)* %Arg, i32 %i 509 %a1 = addrspacecast float* addrspace(1)* addrspace(1)* %p1 to i32* addrspace(1)** 510 %p2 = load i32* addrspace(1)*, i32* addrspace(1)** %a1, align 8 511 %a2 = addrspacecast i32* addrspace(1)* %p2 to float** 512 %p3 = load float*, float** %a2, align 8 513 store float 0.000000e+00, float* %p3, align 4 514 ret void 515} 516 517declare i32 @llvm.amdgcn.workitem.id.x() 518declare void @llvm.amdgcn.s.barrier() 519