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; GCN: global_load_dwordx4 91; GCN: global_store_dword 92define amdgpu_kernel void @flat_ptr_arg(float** nocapture readonly noalias %Arg, float** nocapture noalias %Out, i32 %X) { 93; CHECK-LABEL: @flat_ptr_arg( 94; CHECK-NEXT: entry: 95; CHECK-NEXT: [[OUT_GLOBAL:%.*]] = addrspacecast float** [[OUT:%.*]] to float* addrspace(1)* 96; CHECK-NEXT: [[ARG_GLOBAL:%.*]] = addrspacecast float** [[ARG:%.*]] to float* addrspace(1)* 97; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 98; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[I]] to i64 99; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG_GLOBAL]], i64 [[IDXPROM]] 100; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* addrspace(1)* [[ARRAYIDX10]] to float** 101; CHECK-NEXT: [[ARRAYIDX10_CONST:%.*]] = addrspacecast float** [[TMP0]] to float* addrspace(4)* 102; CHECK-NEXT: [[I1:%.*]] = load float*, float* addrspace(4)* [[ARRAYIDX10_CONST]], align 8 103; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast float* [[I1]] to float addrspace(1)* 104; CHECK-NEXT: [[TMP2:%.*]] = addrspacecast float addrspace(1)* [[TMP1]] to float* 105; CHECK-NEXT: [[I1_CONST:%.*]] = addrspacecast float* [[TMP2]] to float addrspace(4)* 106; CHECK-NEXT: [[I2:%.*]] = load float, float addrspace(4)* [[I1_CONST]], align 4 107; CHECK-NEXT: [[ARRAYIDX512:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[X:%.*]] 108; CHECK-NEXT: store float [[I2]], float addrspace(3)* [[ARRAYIDX512]], align 4 109; CHECK-NEXT: [[ARRAYIDX3_1:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP1]], i64 1 110; CHECK-NEXT: [[I3:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_1]], align 4 111; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i32 [[X]], 1 112; CHECK-NEXT: [[ARRAYIDX512_1:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_1]] 113; CHECK-NEXT: store float [[I3]], float addrspace(3)* [[ARRAYIDX512_1]], align 4 114; CHECK-NEXT: [[ARRAYIDX3_2:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP1]], i64 2 115; CHECK-NEXT: [[I4:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_2]], align 4 116; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i32 [[X]], 2 117; CHECK-NEXT: [[ARRAYIDX512_2:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_2]] 118; CHECK-NEXT: store float [[I4]], float addrspace(3)* [[ARRAYIDX512_2]], align 4 119; CHECK-NEXT: [[ARRAYIDX3_3:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP1]], i64 3 120; CHECK-NEXT: [[I5:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_3]], align 4 121; CHECK-NEXT: [[ADD_3:%.*]] = add nsw i32 [[X]], 3 122; CHECK-NEXT: [[ARRAYIDX512_3:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_3]] 123; CHECK-NEXT: store float [[I5]], float addrspace(3)* [[ARRAYIDX512_3]], align 4 124; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[X]], -1 125; CHECK-NEXT: [[ARRAYIDX711:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[SUB]] 126; CHECK-NEXT: [[I6:%.*]] = load float, float addrspace(3)* [[ARRAYIDX711]], align 4 127; CHECK-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[OUT_GLOBAL]], i64 [[IDXPROM]] 128; CHECK-NEXT: [[TMP3:%.*]] = addrspacecast float* addrspace(1)* [[ARRAYIDX11]] to float** 129; CHECK-NEXT: [[ARRAYIDX11_CONST:%.*]] = addrspacecast float** [[TMP3]] to float* addrspace(4)* 130; CHECK-NEXT: [[I7:%.*]] = load float*, float* addrspace(4)* [[ARRAYIDX11_CONST]], align 8 131; CHECK-NEXT: [[TMP4:%.*]] = addrspacecast float* [[I7]] to float addrspace(1)* 132; CHECK-NEXT: [[IDXPROM8:%.*]] = sext i32 [[X]] to i64 133; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP4]], i64 [[IDXPROM8]] 134; CHECK-NEXT: store float [[I6]], float addrspace(1)* [[ARRAYIDX9]], align 4 135; CHECK-NEXT: ret void 136; 137entry: 138 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 139 %idxprom = zext i32 %i to i64 140 %arrayidx10 = getelementptr inbounds float*, float** %Arg, i64 %idxprom 141 %i1 = load float*, float** %arrayidx10, align 8 142 %i2 = load float, float* %i1, align 4 143 %arrayidx512 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %X 144 store float %i2, float addrspace(3)* %arrayidx512, align 4 145 %arrayidx3.1 = getelementptr inbounds float, float* %i1, i64 1 146 %i3 = load float, float* %arrayidx3.1, align 4 147 %add.1 = add nsw i32 %X, 1 148 %arrayidx512.1 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.1 149 store float %i3, float addrspace(3)* %arrayidx512.1, align 4 150 %arrayidx3.2 = getelementptr inbounds float, float* %i1, i64 2 151 %i4 = load float, float* %arrayidx3.2, align 4 152 %add.2 = add nsw i32 %X, 2 153 %arrayidx512.2 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.2 154 store float %i4, float addrspace(3)* %arrayidx512.2, align 4 155 %arrayidx3.3 = getelementptr inbounds float, float* %i1, i64 3 156 %i5 = load float, float* %arrayidx3.3, align 4 157 %add.3 = add nsw i32 %X, 3 158 %arrayidx512.3 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.3 159 store float %i5, float addrspace(3)* %arrayidx512.3, align 4 160 %sub = add nsw i32 %X, -1 161 %arrayidx711 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %sub 162 %i6 = load float, float addrspace(3)* %arrayidx711, align 4 163 %arrayidx11 = getelementptr inbounds float*, float** %Out, i64 %idxprom 164 %i7 = load float*, float** %arrayidx11, align 8 165 %idxprom8 = sext i32 %X to i64 166 %arrayidx9 = getelementptr inbounds float, float* %i7, i64 %idxprom8 167 store float %i6, float* %arrayidx9, align 4 168 ret void 169} 170 171; GCN-LABEL: global_ptr_arg: 172; GCN: global_load_dwordx2 173; GCN: global_load_dwordx4 174; GCN: global_store_dword 175define amdgpu_kernel void @global_ptr_arg(float* addrspace(1)* nocapture readonly %Arg, i32 %X) { 176; CHECK-LABEL: @global_ptr_arg( 177; CHECK-NEXT: entry: 178; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 179; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[I]] to i64 180; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG:%.*]], i64 [[IDXPROM]] 181; CHECK-NEXT: [[ARRAYIDX10_CONST:%.*]] = addrspacecast float* addrspace(1)* [[ARRAYIDX10]] to float* addrspace(4)* 182; CHECK-NEXT: [[I1:%.*]] = load float*, float* addrspace(4)* [[ARRAYIDX10_CONST]], align 8 183; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* [[I1]] to float addrspace(1)* 184; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast float addrspace(1)* [[TMP0]] to float* 185; CHECK-NEXT: [[I1_CONST:%.*]] = addrspacecast float* [[TMP1]] to float addrspace(4)* 186; CHECK-NEXT: [[I2:%.*]] = load float, float addrspace(4)* [[I1_CONST]], align 4 187; CHECK-NEXT: [[ARRAYIDX512:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[X:%.*]] 188; CHECK-NEXT: store float [[I2]], float addrspace(3)* [[ARRAYIDX512]], align 4 189; CHECK-NEXT: [[ARRAYIDX3_1:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP0]], i64 1 190; CHECK-NEXT: [[I3:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_1]], align 4 191; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i32 [[X]], 1 192; CHECK-NEXT: [[ARRAYIDX512_1:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_1]] 193; CHECK-NEXT: store float [[I3]], float addrspace(3)* [[ARRAYIDX512_1]], align 4 194; CHECK-NEXT: [[ARRAYIDX3_2:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP0]], i64 2 195; CHECK-NEXT: [[I4:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_2]], align 4 196; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i32 [[X]], 2 197; CHECK-NEXT: [[ARRAYIDX512_2:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_2]] 198; CHECK-NEXT: store float [[I4]], float addrspace(3)* [[ARRAYIDX512_2]], align 4 199; CHECK-NEXT: [[ARRAYIDX3_3:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP0]], i64 3 200; CHECK-NEXT: [[I5:%.*]] = load float, float addrspace(1)* [[ARRAYIDX3_3]], align 4 201; CHECK-NEXT: [[ADD_3:%.*]] = add nsw i32 [[X]], 3 202; CHECK-NEXT: [[ARRAYIDX512_3:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[ADD_3]] 203; CHECK-NEXT: store float [[I5]], float addrspace(3)* [[ARRAYIDX512_3]], align 4 204; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[X]], -1 205; CHECK-NEXT: [[ARRAYIDX711:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[SUB]] 206; CHECK-NEXT: [[I6:%.*]] = load float, float addrspace(3)* [[ARRAYIDX711]], align 4 207; CHECK-NEXT: [[IDXPROM8:%.*]] = sext i32 [[X]] to i64 208; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP0]], i64 [[IDXPROM8]] 209; CHECK-NEXT: store float [[I6]], float addrspace(1)* [[ARRAYIDX9]], align 4 210; CHECK-NEXT: ret void 211; 212entry: 213 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 214 %idxprom = zext i32 %i to i64 215 %arrayidx10 = getelementptr inbounds float*, float* addrspace(1)* %Arg, i64 %idxprom 216 %i1 = load float*, float* addrspace(1)* %arrayidx10, align 8 217 %i2 = load float, float* %i1, align 4 218 %arrayidx512 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %X 219 store float %i2, float addrspace(3)* %arrayidx512, align 4 220 %arrayidx3.1 = getelementptr inbounds float, float* %i1, i64 1 221 %i3 = load float, float* %arrayidx3.1, align 4 222 %add.1 = add nsw i32 %X, 1 223 %arrayidx512.1 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.1 224 store float %i3, float addrspace(3)* %arrayidx512.1, align 4 225 %arrayidx3.2 = getelementptr inbounds float, float* %i1, i64 2 226 %i4 = load float, float* %arrayidx3.2, align 4 227 %add.2 = add nsw i32 %X, 2 228 %arrayidx512.2 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.2 229 store float %i4, float addrspace(3)* %arrayidx512.2, align 4 230 %arrayidx3.3 = getelementptr inbounds float, float* %i1, i64 3 231 %i5 = load float, float* %arrayidx3.3, align 4 232 %add.3 = add nsw i32 %X, 3 233 %arrayidx512.3 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %add.3 234 store float %i5, float addrspace(3)* %arrayidx512.3, align 4 235 %sub = add nsw i32 %X, -1 236 %arrayidx711 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %sub 237 %i6 = load float, float addrspace(3)* %arrayidx711, align 4 238 %idxprom8 = sext i32 %X to i64 239 %arrayidx9 = getelementptr inbounds float, float* %i1, i64 %idxprom8 240 store float %i6, float* %arrayidx9, align 4 241 ret void 242} 243 244; GCN-LABEL: global_ptr_arg_clobbered: 245; GCN: global_store_dwordx2 246; GCN: global_load_dwordx2 247; GCN: flat_load_dword 248; GCN: flat_store_dword 249define amdgpu_kernel void @global_ptr_arg_clobbered(float* addrspace(1)* nocapture readonly %Arg, i32 %X) { 250; CHECK-LABEL: @global_ptr_arg_clobbered( 251; CHECK-NEXT: entry: 252; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 253; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[I]] to i64 254; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG:%.*]], i64 [[IDXPROM]] 255; CHECK-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARRAYIDX10]], i32 [[X:%.*]] 256; CHECK-NEXT: store float* null, float* addrspace(1)* [[ARRAYIDX11]], align 4 257; CHECK-NEXT: [[I1:%.*]] = load float*, float* addrspace(1)* [[ARRAYIDX10]], align 8 258; CHECK-NEXT: [[I2:%.*]] = load float, float* [[I1]], align 4 259; CHECK-NEXT: [[ARRAYIDX512:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[X]] 260; CHECK-NEXT: store float [[I2]], float addrspace(3)* [[ARRAYIDX512]], align 4 261; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[X]], -1 262; CHECK-NEXT: [[ARRAYIDX711:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[SUB]] 263; CHECK-NEXT: [[I6:%.*]] = load float, float addrspace(3)* [[ARRAYIDX711]], align 4 264; CHECK-NEXT: [[IDXPROM8:%.*]] = sext i32 [[X]] to i64 265; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float* [[I1]], i64 [[IDXPROM8]] 266; CHECK-NEXT: store float [[I6]], float* [[ARRAYIDX9]], align 4 267; CHECK-NEXT: ret void 268; 269entry: 270 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 271 %idxprom = zext i32 %i to i64 272 %arrayidx10 = getelementptr inbounds float*, float* addrspace(1)* %Arg, i64 %idxprom 273 %arrayidx11 = getelementptr inbounds float*, float* addrspace(1)* %arrayidx10, i32 %X 274 store float* null, float* addrspace(1)* %arrayidx11, align 4 275 %i1 = load float*, float* addrspace(1)* %arrayidx10, align 8 276 %i2 = load float, float* %i1, align 4 277 %arrayidx512 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %X 278 store float %i2, float addrspace(3)* %arrayidx512, align 4 279 %sub = add nsw i32 %X, -1 280 %arrayidx711 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %sub 281 %i6 = load float, float addrspace(3)* %arrayidx711, align 4 282 %idxprom8 = sext i32 %X to i64 283 %arrayidx9 = getelementptr inbounds float, float* %i1, i64 %idxprom8 284 store float %i6, float* %arrayidx9, align 4 285 ret void 286} 287 288; GCN-LABEL: global_ptr_arg_clobbered_after_load: 289; GCN: global_load_dwordx2 290; GCN: global_store_dwordx2 291; GCN: global_load_dword 292; GCN: global_store_dword 293define amdgpu_kernel void @global_ptr_arg_clobbered_after_load(float* addrspace(1)* nocapture readonly %Arg, i32 %X) { 294; CHECK-LABEL: @global_ptr_arg_clobbered_after_load( 295; CHECK-NEXT: entry: 296; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 297; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[I]] to i64 298; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG:%.*]], i64 [[IDXPROM]] 299; CHECK-NEXT: [[ARRAYIDX10_CONST:%.*]] = addrspacecast float* addrspace(1)* [[ARRAYIDX10]] to float* addrspace(4)* 300; CHECK-NEXT: [[I1:%.*]] = load float*, float* addrspace(4)* [[ARRAYIDX10_CONST]], align 8 301; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* [[I1]] to float addrspace(1)* 302; CHECK-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARRAYIDX10]], i32 [[X:%.*]] 303; CHECK-NEXT: store float* null, float* addrspace(1)* [[ARRAYIDX11]], align 4 304; CHECK-NEXT: [[I2:%.*]] = load float, float addrspace(1)* [[TMP0]], align 4 305; CHECK-NEXT: [[ARRAYIDX512:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[X]] 306; CHECK-NEXT: store float [[I2]], float addrspace(3)* [[ARRAYIDX512]], align 4 307; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[X]], -1 308; CHECK-NEXT: [[ARRAYIDX711:%.*]] = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 [[SUB]] 309; CHECK-NEXT: [[I6:%.*]] = load float, float addrspace(3)* [[ARRAYIDX711]], align 4 310; CHECK-NEXT: [[IDXPROM8:%.*]] = sext i32 [[X]] to i64 311; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float addrspace(1)* [[TMP0]], i64 [[IDXPROM8]] 312; CHECK-NEXT: store float [[I6]], float addrspace(1)* [[ARRAYIDX9]], align 4 313; CHECK-NEXT: ret void 314; 315entry: 316 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 317 %idxprom = zext i32 %i to i64 318 %arrayidx10 = getelementptr inbounds float*, float* addrspace(1)* %Arg, i64 %idxprom 319 %i1 = load float*, float* addrspace(1)* %arrayidx10, align 8 320 %arrayidx11 = getelementptr inbounds float*, float* addrspace(1)* %arrayidx10, i32 %X 321 store float* null, float* addrspace(1)* %arrayidx11, align 4 322 %i2 = load float, float* %i1, align 4 323 %arrayidx512 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %X 324 store float %i2, float addrspace(3)* %arrayidx512, align 4 325 %sub = add nsw i32 %X, -1 326 %arrayidx711 = getelementptr inbounds [4 x float], [4 x float] addrspace(3)* @LDS, i32 0, i32 %sub 327 %i6 = load float, float addrspace(3)* %arrayidx711, align 4 328 %idxprom8 = sext i32 %X to i64 329 %arrayidx9 = getelementptr inbounds float, float* %i1, i64 %idxprom8 330 store float %i6, float* %arrayidx9, align 4 331 ret void 332} 333 334; GCN-LABEL: ptr_nest_3_barrier: 335; GCN-COUNT-2: global_load_dwordx2 336; GCN: global_store_dword 337define amdgpu_kernel void @ptr_nest_3_barrier(float** addrspace(1)* nocapture readonly %Arg) { 338; CHECK-LABEL: @ptr_nest_3_barrier( 339; CHECK-NEXT: entry: 340; CHECK-NEXT: [[I:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x() 341; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float**, float** addrspace(1)* [[ARG:%.*]], i32 [[I]] 342; CHECK-NEXT: tail call void @llvm.amdgcn.s.barrier() 343; CHECK-NEXT: [[P1_CONST:%.*]] = addrspacecast float** addrspace(1)* [[P1]] to float** addrspace(4)* 344; CHECK-NEXT: [[P2:%.*]] = load float**, float** addrspace(4)* [[P1_CONST]], align 8 345; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float** [[P2]] to float* addrspace(1)* 346; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast float* addrspace(1)* [[TMP0]] to float** 347; CHECK-NEXT: [[P2_FLAT:%.*]] = addrspacecast float* addrspace(1)* [[TMP0]] to float** 348; CHECK-NEXT: [[P2_CONST:%.*]] = addrspacecast float** [[TMP1]] to float* addrspace(4)* 349; CHECK-NEXT: [[P3:%.*]] = load float*, float* addrspace(4)* [[P2_CONST]], align 8 350; CHECK-NEXT: [[TMP2:%.*]] = addrspacecast float* [[P3]] to float addrspace(1)* 351; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[TMP2]], align 4 352; CHECK-NEXT: ret void 353; 354entry: 355 %i = tail call i32 @llvm.amdgcn.workitem.id.x() 356 %p1 = getelementptr inbounds float**, float** addrspace(1)* %Arg, i32 %i 357 tail call void @llvm.amdgcn.s.barrier() 358 %p2 = load float**, float** addrspace(1)* %p1, align 8 359 %p3 = load float*, float** %p2, align 8 360 store float 0.000000e+00, float* %p3, align 4 361 ret void 362} 363 364; GCN-LABEL: flat_ptr_nest_2: 365; GCN: s_lshl_b64 366; GCN: s_load_dwordx2 367; GCN: global_store_dword 368define amdgpu_kernel void @flat_ptr_nest_2(float** nocapture readonly %Arg, i32 %i) { 369; CHECK-LABEL: @flat_ptr_nest_2( 370; CHECK-NEXT: entry: 371; CHECK-NEXT: [[ARG_GLOBAL:%.*]] = addrspacecast float** [[ARG:%.*]] to float* addrspace(1)* 372; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG_GLOBAL]], i32 [[I:%.*]] 373; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* addrspace(1)* [[P1]] to float** 374; CHECK-NEXT: [[P1_CONST:%.*]] = addrspacecast float** [[TMP0]] to float* addrspace(4)* 375; CHECK-NEXT: [[P2:%.*]] = load float*, float* addrspace(4)* [[P1_CONST]], align 8 376; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast float* [[P2]] to float addrspace(1)* 377; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[TMP1]], align 4 378; CHECK-NEXT: ret void 379; 380entry: 381 %p1 = getelementptr inbounds float*, float** %Arg, i32 %i 382 %p2 = load float*, float** %p1, align 8 383 store float 0.000000e+00, float* %p2, align 4 384 ret void 385} 386 387; GCN-LABEL: const_ptr_nest_3: 388; GCN: s_lshl_b64 389; GCN: s_load_dwordx2 390; GCN: s_load_dwordx2 391; GCN: global_store_dword 392define amdgpu_kernel void @const_ptr_nest_3(float* addrspace(4)* addrspace(4)* nocapture readonly %Arg, i32 %i) { 393; CHECK-LABEL: @const_ptr_nest_3( 394; CHECK-NEXT: entry: 395; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float* addrspace(4)*, float* addrspace(4)* addrspace(4)* [[ARG:%.*]], i32 [[I:%.*]] 396; CHECK-NEXT: [[P2:%.*]] = load float* addrspace(4)*, float* addrspace(4)* addrspace(4)* [[P1]], align 8 397; CHECK-NEXT: [[P3:%.*]] = load float*, float* addrspace(4)* [[P2]], align 8 398; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* [[P3]] to float addrspace(1)* 399; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[TMP0]], align 4 400; CHECK-NEXT: ret void 401; 402entry: 403 %p1 = getelementptr inbounds float* addrspace(4)*, float* addrspace(4)* addrspace(4)* %Arg, i32 %i 404 %p2 = load float* addrspace(4)*, float * addrspace(4)* addrspace(4)* %p1, align 8 405 %p3 = load float*, float* addrspace(4)* %p2, align 8 406 store float 0.000000e+00, float* %p3, align 4 407 ret void 408} 409 410; GCN-LABEL: cast_from_const_const_ptr_nest_3: 411; GCN: s_lshl_b64 412; GCN: s_load_dwordx2 413; GCN: s_load_dwordx2 414; GCN: global_store_dword 415define amdgpu_kernel void @cast_from_const_const_ptr_nest_3(float* addrspace(4)* addrspace(4)* nocapture readonly %Arg, i32 %i) { 416; CHECK-LABEL: @cast_from_const_const_ptr_nest_3( 417; CHECK-NEXT: entry: 418; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float* addrspace(4)*, float* addrspace(4)* addrspace(4)* [[ARG:%.*]], i32 [[I:%.*]] 419; CHECK-NEXT: [[P2:%.*]] = load float* addrspace(4)*, float* addrspace(4)* addrspace(4)* [[P1]], align 8 420; CHECK-NEXT: [[P3:%.*]] = load float*, float* addrspace(4)* [[P2]], align 8 421; CHECK-NEXT: [[P3_GLOBAL:%.*]] = addrspacecast float* [[P3]] to float addrspace(1)* 422; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[P3_GLOBAL]], align 4 423; CHECK-NEXT: ret void 424; 425entry: 426 %p1 = getelementptr inbounds float* addrspace(4)*, float* addrspace(4)* addrspace(4)* %Arg, i32 %i 427 %a1 = addrspacecast float* addrspace(4)* addrspace(4)* %p1 to float* addrspace(4)** 428 %p2 = load float* addrspace(4)*, float* addrspace(4)** %a1, align 8 429 %a2 = addrspacecast float* addrspace(4)* %p2 to float** 430 %p3 = load float*, float** %a2, align 8 431 store float 0.000000e+00, float* %p3, align 4 432 ret void 433} 434 435; GCN-LABEL: flat_ptr_volatile_load: 436; GCN: s_lshl_b64 437; GCN: flat_load_dwordx2 438; GCN: global_store_dword 439define amdgpu_kernel void @flat_ptr_volatile_load(float** nocapture readonly %Arg, i32 %i) { 440; CHECK-LABEL: @flat_ptr_volatile_load( 441; CHECK-NEXT: entry: 442; CHECK-NEXT: [[ARG_GLOBAL:%.*]] = addrspacecast float** [[ARG:%.*]] to float* addrspace(1)* 443; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG_GLOBAL]], i32 [[I:%.*]] 444; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* addrspace(1)* [[P1]] to float** 445; CHECK-NEXT: [[P2:%.*]] = load volatile float*, float** [[TMP0]], align 8 446; CHECK-NEXT: [[P2_GLOBAL:%.*]] = addrspacecast float* [[P2]] to float addrspace(1)* 447; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[P2_GLOBAL]], align 4 448; CHECK-NEXT: ret void 449; 450entry: 451 %p1 = getelementptr inbounds float*, float** %Arg, i32 %i 452 %p2 = load volatile float*, float** %p1, align 8 453 store float 0.000000e+00, float* %p2, align 4 454 ret void 455} 456 457; GCN-LABEL: flat_ptr_atomic_load: 458; GCN: s_lshl_b64 459; GCN: global_load_dwordx2 460; GCN: global_store_dword 461define amdgpu_kernel void @flat_ptr_atomic_load(float** nocapture readonly %Arg, i32 %i) { 462; CHECK-LABEL: @flat_ptr_atomic_load( 463; CHECK-NEXT: entry: 464; CHECK-NEXT: [[ARG_GLOBAL:%.*]] = addrspacecast float** [[ARG:%.*]] to float* addrspace(1)* 465; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float*, float* addrspace(1)* [[ARG_GLOBAL]], i32 [[I:%.*]] 466; CHECK-NEXT: [[P2:%.*]] = load atomic float*, float* addrspace(1)* [[P1]] monotonic, align 8 467; CHECK-NEXT: [[P2_GLOBAL:%.*]] = addrspacecast float* [[P2]] to float addrspace(1)* 468; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[P2_GLOBAL]], align 4 469; CHECK-NEXT: ret void 470; 471entry: 472 %p1 = getelementptr inbounds float*, float** %Arg, i32 %i 473 %p2 = load atomic float*, float** %p1 monotonic, align 8 474 store float 0.000000e+00, float* %p2, align 4 475 ret void 476} 477 478; GCN-LABEL: cast_changing_pointee_type: 479; GCN: s_lshl_b64 480; GCN: s_load_dwordx2 481; GCN: s_load_dwordx2 482; GCN: global_store_dword 483define amdgpu_kernel void @cast_changing_pointee_type(float* addrspace(1)* addrspace(1)* nocapture readonly %Arg, i32 %i) { 484; CHECK-LABEL: @cast_changing_pointee_type( 485; CHECK-NEXT: entry: 486; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float* addrspace(1)*, float* addrspace(1)* addrspace(1)* [[ARG:%.*]], i32 [[I:%.*]] 487; CHECK-NEXT: [[A1:%.*]] = bitcast float* addrspace(1)* addrspace(1)* [[P1]] to i32* addrspace(1)* addrspace(1)* 488; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float* addrspace(1)* addrspace(1)* [[P1]] to i32* addrspace(1)** 489; CHECK-NEXT: [[A1_CONST:%.*]] = addrspacecast i32* addrspace(1)** [[TMP0]] to i32* addrspace(1)* addrspace(4)* 490; CHECK-NEXT: [[P2:%.*]] = load i32* addrspace(1)*, i32* addrspace(1)* addrspace(4)* [[A1_CONST]], align 8 491; CHECK-NEXT: [[A2:%.*]] = bitcast i32* addrspace(1)* [[P2]] to float* addrspace(1)* 492; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast i32* addrspace(1)* [[P2]] to float** 493; CHECK-NEXT: [[A2_CONST:%.*]] = addrspacecast float** [[TMP1]] to float* addrspace(4)* 494; CHECK-NEXT: [[P3:%.*]] = load float*, float* addrspace(4)* [[A2_CONST]], align 8 495; CHECK-NEXT: [[TMP2:%.*]] = addrspacecast float* [[P3]] to float addrspace(1)* 496; CHECK-NEXT: store float 0.000000e+00, float addrspace(1)* [[TMP2]], align 4 497; CHECK-NEXT: ret void 498; 499entry: 500 %p1 = getelementptr inbounds float* addrspace(1)*, float* addrspace(1)* addrspace(1)* %Arg, i32 %i 501 %a1 = addrspacecast float* addrspace(1)* addrspace(1)* %p1 to i32* addrspace(1)** 502 %p2 = load i32* addrspace(1)*, i32* addrspace(1)** %a1, align 8 503 %a2 = addrspacecast i32* addrspace(1)* %p2 to float** 504 %p3 = load float*, float** %a2, align 8 505 store float 0.000000e+00, float* %p3, align 4 506 ret void 507} 508 509declare i32 @llvm.amdgcn.workitem.id.x() 510declare void @llvm.amdgcn.s.barrier() 511