Index: lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -426,6 +426,13 @@ if (!User->getType()->isPointerTy()) continue; + if (GetElementPtrInst *GEP = dyn_cast(UseInst)) { + // Be conservative if an address could be computed outside the bounds of + // the alloca. + if (!GEP->isInBounds()) + return false; + } + WorkList.push_back(User); Success = collectUsesWithPtrTypes(User, WorkList); } Index: test/CodeGen/AMDGPU/array-ptr-calc-i32.ll =================================================================== --- test/CodeGen/AMDGPU/array-ptr-calc-i32.ll +++ test/CodeGen/AMDGPU/array-ptr-calc-i32.ll @@ -20,24 +20,24 @@ ; FIXME: The AMDGPUPromoteAlloca pass should be able to convert this ; alloca to a vector. It currently fails because it does not know how ; to interpret: -; getelementptr [4 x i32], [4 x i32]* %alloca, i32 1, i32 %b +; getelementptr inbounds [4 x i32], [4 x i32]* %alloca, i32 1, i32 %b ; SI-PROMOTE: v_add_i32_e32 [[PTRREG:v[0-9]+]], vcc, 16 ; SI-PROMOTE: ds_write_b32 [[PTRREG]] define void @test_private_array_ptr_calc(i32 addrspace(1)* noalias %out, i32 addrspace(1)* noalias %inA, i32 addrspace(1)* noalias %inB) { %alloca = alloca [4 x i32], i32 4, align 16 %tid = call i32 @llvm.SI.tid() readnone - %a_ptr = getelementptr i32, i32 addrspace(1)* %inA, i32 %tid - %b_ptr = getelementptr i32, i32 addrspace(1)* %inB, i32 %tid + %a_ptr = getelementptr inbounds i32, i32 addrspace(1)* %inA, i32 %tid + %b_ptr = getelementptr inbounds i32, i32 addrspace(1)* %inB, i32 %tid %a = load i32, i32 addrspace(1)* %a_ptr %b = load i32, i32 addrspace(1)* %b_ptr %result = add i32 %a, %b - %alloca_ptr = getelementptr [4 x i32], [4 x i32]* %alloca, i32 1, i32 %b + %alloca_ptr = getelementptr inbounds [4 x i32], [4 x i32]* %alloca, i32 1, i32 %b store i32 %result, i32* %alloca_ptr, align 4 ; Dummy call call void @llvm.AMDGPU.barrier.local() nounwind convergent %reload = load i32, i32* %alloca_ptr, align 4 - %out_ptr = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %out_ptr = getelementptr inbounds i32, i32 addrspace(1)* %out, i32 %tid store i32 %reload, i32 addrspace(1)* %out_ptr, align 4 ret void } Index: test/CodeGen/AMDGPU/indirect-private-64.ll =================================================================== --- test/CodeGen/AMDGPU/indirect-private-64.ll +++ test/CodeGen/AMDGPU/indirect-private-64.ll @@ -16,7 +16,7 @@ define void @private_access_f64_alloca(double addrspace(1)* noalias %out, double addrspace(1)* noalias %in, i32 %b) nounwind { %val = load double, double addrspace(1)* %in, align 8 %array = alloca double, i32 16, align 8 - %ptr = getelementptr double, double* %array, i32 %b + %ptr = getelementptr inbounds double, double* %array, i32 %b store double %val, double* %ptr, align 8 call void @llvm.AMDGPU.barrier.local() convergent nounwind %result = load double, double* %ptr, align 8 @@ -36,7 +36,7 @@ define void @private_access_v2f64_alloca(<2 x double> addrspace(1)* noalias %out, <2 x double> addrspace(1)* noalias %in, i32 %b) nounwind { %val = load <2 x double>, <2 x double> addrspace(1)* %in, align 16 %array = alloca <2 x double>, i32 16, align 16 - %ptr = getelementptr <2 x double>, <2 x double>* %array, i32 %b + %ptr = getelementptr inbounds <2 x double>, <2 x double>* %array, i32 %b store <2 x double> %val, <2 x double>* %ptr, align 16 call void @llvm.AMDGPU.barrier.local() convergent nounwind %result = load <2 x double>, <2 x double>* %ptr, align 16 @@ -54,7 +54,7 @@ define void @private_access_i64_alloca(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %in, i32 %b) nounwind { %val = load i64, i64 addrspace(1)* %in, align 8 %array = alloca i64, i32 16, align 8 - %ptr = getelementptr i64, i64* %array, i32 %b + %ptr = getelementptr inbounds i64, i64* %array, i32 %b store i64 %val, i64* %ptr, align 8 call void @llvm.AMDGPU.barrier.local() convergent nounwind %result = load i64, i64* %ptr, align 8 @@ -74,7 +74,7 @@ define void @private_access_v2i64_alloca(<2 x i64> addrspace(1)* noalias %out, <2 x i64> addrspace(1)* noalias %in, i32 %b) nounwind { %val = load <2 x i64>, <2 x i64> addrspace(1)* %in, align 16 %array = alloca <2 x i64>, i32 16, align 16 - %ptr = getelementptr <2 x i64>, <2 x i64>* %array, i32 %b + %ptr = getelementptr inbounds <2 x i64>, <2 x i64>* %array, i32 %b store <2 x i64> %val, <2 x i64>* %ptr, align 16 call void @llvm.AMDGPU.barrier.local() convergent nounwind %result = load <2 x i64>, <2 x i64>* %ptr, align 16 Index: test/CodeGen/AMDGPU/private-memory-atomics.ll =================================================================== --- test/CodeGen/AMDGPU/private-memory-atomics.ll +++ test/CodeGen/AMDGPU/private-memory-atomics.ll @@ -7,11 +7,11 @@ define void @atomicrmw_private(i32 addrspace(1)* %out, i32 %in) nounwind { entry: %tmp = alloca [2 x i32] - %tmp1 = getelementptr [2 x i32], [2 x i32]* %tmp, i32 0, i32 0 - %tmp2 = getelementptr [2 x i32], [2 x i32]* %tmp, i32 0, i32 1 + %tmp1 = getelementptr inbounds [2 x i32], [2 x i32]* %tmp, i32 0, i32 0 + %tmp2 = getelementptr inbounds [2 x i32], [2 x i32]* %tmp, i32 0, i32 1 store i32 0, i32* %tmp1 store i32 1, i32* %tmp2 - %tmp3 = getelementptr [2 x i32], [2 x i32]* %tmp, i32 0, i32 %in + %tmp3 = getelementptr inbounds [2 x i32], [2 x i32]* %tmp, i32 0, i32 %in %tmp4 = atomicrmw add i32* %tmp3, i32 7 acq_rel store i32 %tmp4, i32 addrspace(1)* %out ret void @@ -20,11 +20,11 @@ define void @cmpxchg_private(i32 addrspace(1)* %out, i32 %in) nounwind { entry: %tmp = alloca [2 x i32] - %tmp1 = getelementptr [2 x i32], [2 x i32]* %tmp, i32 0, i32 0 - %tmp2 = getelementptr [2 x i32], [2 x i32]* %tmp, i32 0, i32 1 + %tmp1 = getelementptr inbounds [2 x i32], [2 x i32]* %tmp, i32 0, i32 0 + %tmp2 = getelementptr inbounds [2 x i32], [2 x i32]* %tmp, i32 0, i32 1 store i32 0, i32* %tmp1 store i32 1, i32* %tmp2 - %tmp3 = getelementptr [2 x i32], [2 x i32]* %tmp, i32 0, i32 %in + %tmp3 = getelementptr inbounds [2 x i32], [2 x i32]* %tmp, i32 0, i32 %in %tmp4 = cmpxchg i32* %tmp3, i32 0, i32 1 acq_rel monotonic %val = extractvalue { i32, i1 } %tmp4, 0 store i32 %val, i32 addrspace(1)* %out Index: test/CodeGen/AMDGPU/private-memory-r600.ll =================================================================== --- test/CodeGen/AMDGPU/private-memory-r600.ll +++ test/CodeGen/AMDGPU/private-memory-r600.ll @@ -51,16 +51,16 @@ entry: %a = alloca %struct.point %b = alloca %struct.point - %a.x.ptr = getelementptr %struct.point, %struct.point* %a, i32 0, i32 0 - %a.y.ptr = getelementptr %struct.point, %struct.point* %a, i32 0, i32 1 - %b.x.ptr = getelementptr %struct.point, %struct.point* %b, i32 0, i32 0 - %b.y.ptr = getelementptr %struct.point, %struct.point* %b, i32 0, i32 1 + %a.x.ptr = getelementptr inbounds %struct.point, %struct.point* %a, i32 0, i32 0 + %a.y.ptr = getelementptr inbounds %struct.point, %struct.point* %a, i32 0, i32 1 + %b.x.ptr = getelementptr inbounds %struct.point, %struct.point* %b, i32 0, i32 0 + %b.y.ptr = getelementptr inbounds %struct.point, %struct.point* %b, i32 0, i32 1 store i32 0, i32* %a.x.ptr store i32 1, i32* %a.y.ptr store i32 2, i32* %b.x.ptr store i32 3, i32* %b.y.ptr - %a.indirect.ptr = getelementptr %struct.point, %struct.point* %a, i32 0, i32 0 - %b.indirect.ptr = getelementptr %struct.point, %struct.point* %b, i32 0, i32 0 + %a.indirect.ptr = getelementptr inbounds %struct.point, %struct.point* %a, i32 0, i32 0 + %b.indirect.ptr = getelementptr inbounds %struct.point, %struct.point* %b, i32 0, i32 0 %a.indirect = load i32, i32* %a.indirect.ptr %b.indirect = load i32, i32* %b.indirect.ptr %0 = add i32 %a.indirect, %b.indirect @@ -80,19 +80,19 @@ %prv_array_const = alloca [2 x i32] %prv_array = alloca [2 x i32] %a = load i32, i32 addrspace(1)* %in - %b_src_ptr = getelementptr i32, i32 addrspace(1)* %in, i32 1 + %b_src_ptr = getelementptr inbounds i32, i32 addrspace(1)* %in, i32 1 %b = load i32, i32 addrspace(1)* %b_src_ptr - %a_dst_ptr = getelementptr [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 0 + %a_dst_ptr = getelementptr inbounds [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 0 store i32 %a, i32* %a_dst_ptr - %b_dst_ptr = getelementptr [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 1 + %b_dst_ptr = getelementptr inbounds [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 1 store i32 %b, i32* %b_dst_ptr br label %for.body for.body: %inc = phi i32 [0, %entry], [%count, %for.body] - %x_ptr = getelementptr [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 0 + %x_ptr = getelementptr inbounds [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 0 %x = load i32, i32* %x_ptr - %y_ptr = getelementptr [2 x i32], [2 x i32]* %prv_array, i32 0, i32 0 + %y_ptr = getelementptr inbounds [2 x i32], [2 x i32]* %prv_array, i32 0, i32 0 %y = load i32, i32* %y_ptr %xy = add i32 %x, %y store i32 %xy, i32* %y_ptr @@ -101,7 +101,7 @@ br i1 %done, label %for.end, label %for.body for.end: - %value_ptr = getelementptr [2 x i32], [2 x i32]* %prv_array, i32 0, i32 0 + %value_ptr = getelementptr inbounds [2 x i32], [2 x i32]* %prv_array, i32 0, i32 0 %value = load i32, i32* %value_ptr store i32 %value, i32 addrspace(1)* %out ret void @@ -113,11 +113,11 @@ define void @short_array(i32 addrspace(1)* %out, i32 %index) { entry: %0 = alloca [2 x i16] - %1 = getelementptr [2 x i16], [2 x i16]* %0, i32 0, i32 0 - %2 = getelementptr [2 x i16], [2 x i16]* %0, i32 0, i32 1 + %1 = getelementptr inbounds [2 x i16], [2 x i16]* %0, i32 0, i32 0 + %2 = getelementptr inbounds [2 x i16], [2 x i16]* %0, i32 0, i32 1 store i16 0, i16* %1 store i16 1, i16* %2 - %3 = getelementptr [2 x i16], [2 x i16]* %0, i32 0, i32 %index + %3 = getelementptr inbounds [2 x i16], [2 x i16]* %0, i32 0, i32 %index %4 = load i16, i16* %3 %5 = sext i16 %4 to i32 store i32 %5, i32 addrspace(1)* %out @@ -130,11 +130,11 @@ define void @char_array(i32 addrspace(1)* %out, i32 %index) { entry: %0 = alloca [2 x i8] - %1 = getelementptr [2 x i8], [2 x i8]* %0, i32 0, i32 0 - %2 = getelementptr [2 x i8], [2 x i8]* %0, i32 0, i32 1 + %1 = getelementptr inbounds [2 x i8], [2 x i8]* %0, i32 0, i32 0 + %2 = getelementptr inbounds [2 x i8], [2 x i8]* %0, i32 0, i32 1 store i8 0, i8* %1 store i8 1, i8* %2 - %3 = getelementptr [2 x i8], [2 x i8]* %0, i32 0, i32 %index + %3 = getelementptr inbounds [2 x i8], [2 x i8]* %0, i32 0, i32 %index %4 = load i8, i8* %3 %5 = sext i8 %4 to i32 store i32 %5, i32 addrspace(1)* %out @@ -151,11 +151,11 @@ define void @work_item_info(i32 addrspace(1)* %out, i32 %in) { entry: %0 = alloca [2 x i32] - %1 = getelementptr [2 x i32], [2 x i32]* %0, i32 0, i32 0 - %2 = getelementptr [2 x i32], [2 x i32]* %0, i32 0, i32 1 + %1 = getelementptr inbounds [2 x i32], [2 x i32]* %0, i32 0, i32 0 + %2 = getelementptr inbounds [2 x i32], [2 x i32]* %0, i32 0, i32 1 store i32 0, i32* %1 store i32 1, i32* %2 - %3 = getelementptr [2 x i32], [2 x i32]* %0, i32 0, i32 %in + %3 = getelementptr inbounds [2 x i32], [2 x i32]* %0, i32 0, i32 %in %4 = load i32, i32* %3 %5 = call i32 @llvm.r600.read.tidig.x() %6 = add i32 %4, %5 @@ -173,18 +173,18 @@ entry: %0 = alloca [3 x i8], align 1 %1 = alloca [2 x i8], align 1 - %2 = getelementptr [3 x i8], [3 x i8]* %0, i32 0, i32 0 - %3 = getelementptr [3 x i8], [3 x i8]* %0, i32 0, i32 1 - %4 = getelementptr [3 x i8], [3 x i8]* %0, i32 0, i32 2 - %5 = getelementptr [2 x i8], [2 x i8]* %1, i32 0, i32 0 - %6 = getelementptr [2 x i8], [2 x i8]* %1, i32 0, i32 1 + %2 = getelementptr inbounds [3 x i8], [3 x i8]* %0, i32 0, i32 0 + %3 = getelementptr inbounds [3 x i8], [3 x i8]* %0, i32 0, i32 1 + %4 = getelementptr inbounds [3 x i8], [3 x i8]* %0, i32 0, i32 2 + %5 = getelementptr inbounds [2 x i8], [2 x i8]* %1, i32 0, i32 0 + %6 = getelementptr inbounds [2 x i8], [2 x i8]* %1, i32 0, i32 1 store i8 0, i8* %2 store i8 1, i8* %3 store i8 2, i8* %4 store i8 1, i8* %5 store i8 0, i8* %6 - %7 = getelementptr [3 x i8], [3 x i8]* %0, i32 0, i32 %in - %8 = getelementptr [2 x i8], [2 x i8]* %1, i32 0, i32 %in + %7 = getelementptr inbounds [3 x i8], [3 x i8]* %0, i32 0, i32 %in + %8 = getelementptr inbounds [2 x i8], [2 x i8]* %1, i32 0, i32 %in %9 = load i8, i8* %7 %10 = load i8, i8* %8 %11 = add i8 %9, %10 @@ -196,11 +196,11 @@ define void @char_array_array(i32 addrspace(1)* %out, i32 %index) { entry: %alloca = alloca [2 x [2 x i8]] - %gep0 = getelementptr [2 x [2 x i8]], [2 x [2 x i8]]* %alloca, i32 0, i32 0, i32 0 - %gep1 = getelementptr [2 x [2 x i8]], [2 x [2 x i8]]* %alloca, i32 0, i32 0, i32 1 + %gep0 = getelementptr inbounds [2 x [2 x i8]], [2 x [2 x i8]]* %alloca, i32 0, i32 0, i32 0 + %gep1 = getelementptr inbounds [2 x [2 x i8]], [2 x [2 x i8]]* %alloca, i32 0, i32 0, i32 1 store i8 0, i8* %gep0 store i8 1, i8* %gep1 - %gep2 = getelementptr [2 x [2 x i8]], [2 x [2 x i8]]* %alloca, i32 0, i32 0, i32 %index + %gep2 = getelementptr inbounds [2 x [2 x i8]], [2 x [2 x i8]]* %alloca, i32 0, i32 0, i32 %index %load = load i8, i8* %gep2 %sext = sext i8 %load to i32 store i32 %sext, i32 addrspace(1)* %out @@ -210,11 +210,11 @@ define void @i32_array_array(i32 addrspace(1)* %out, i32 %index) { entry: %alloca = alloca [2 x [2 x i32]] - %gep0 = getelementptr [2 x [2 x i32]], [2 x [2 x i32]]* %alloca, i32 0, i32 0, i32 0 - %gep1 = getelementptr [2 x [2 x i32]], [2 x [2 x i32]]* %alloca, i32 0, i32 0, i32 1 + %gep0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %alloca, i32 0, i32 0, i32 0 + %gep1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %alloca, i32 0, i32 0, i32 1 store i32 0, i32* %gep0 store i32 1, i32* %gep1 - %gep2 = getelementptr [2 x [2 x i32]], [2 x [2 x i32]]* %alloca, i32 0, i32 0, i32 %index + %gep2 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %alloca, i32 0, i32 0, i32 %index %load = load i32, i32* %gep2 store i32 %load, i32 addrspace(1)* %out ret void @@ -223,11 +223,11 @@ define void @i64_array_array(i64 addrspace(1)* %out, i32 %index) { entry: %alloca = alloca [2 x [2 x i64]] - %gep0 = getelementptr [2 x [2 x i64]], [2 x [2 x i64]]* %alloca, i32 0, i32 0, i32 0 - %gep1 = getelementptr [2 x [2 x i64]], [2 x [2 x i64]]* %alloca, i32 0, i32 0, i32 1 + %gep0 = getelementptr inbounds [2 x [2 x i64]], [2 x [2 x i64]]* %alloca, i32 0, i32 0, i32 0 + %gep1 = getelementptr inbounds [2 x [2 x i64]], [2 x [2 x i64]]* %alloca, i32 0, i32 0, i32 1 store i64 0, i64* %gep0 store i64 1, i64* %gep1 - %gep2 = getelementptr [2 x [2 x i64]], [2 x [2 x i64]]* %alloca, i32 0, i32 0, i32 %index + %gep2 = getelementptr inbounds [2 x [2 x i64]], [2 x [2 x i64]]* %alloca, i32 0, i32 0, i32 %index %load = load i64, i64* %gep2 store i64 %load, i64 addrspace(1)* %out ret void @@ -238,11 +238,11 @@ define void @struct_array_array(i32 addrspace(1)* %out, i32 %index) { entry: %alloca = alloca [2 x [2 x %struct.pair32]] - %gep0 = getelementptr [2 x [2 x %struct.pair32]], [2 x [2 x %struct.pair32]]* %alloca, i32 0, i32 0, i32 0, i32 1 - %gep1 = getelementptr [2 x [2 x %struct.pair32]], [2 x [2 x %struct.pair32]]* %alloca, i32 0, i32 0, i32 1, i32 1 + %gep0 = getelementptr inbounds [2 x [2 x %struct.pair32]], [2 x [2 x %struct.pair32]]* %alloca, i32 0, i32 0, i32 0, i32 1 + %gep1 = getelementptr inbounds [2 x [2 x %struct.pair32]], [2 x [2 x %struct.pair32]]* %alloca, i32 0, i32 0, i32 1, i32 1 store i32 0, i32* %gep0 store i32 1, i32* %gep1 - %gep2 = getelementptr [2 x [2 x %struct.pair32]], [2 x [2 x %struct.pair32]]* %alloca, i32 0, i32 0, i32 %index, i32 0 + %gep2 = getelementptr inbounds [2 x [2 x %struct.pair32]], [2 x [2 x %struct.pair32]]* %alloca, i32 0, i32 0, i32 %index, i32 0 %load = load i32, i32* %gep2 store i32 %load, i32 addrspace(1)* %out ret void @@ -251,11 +251,11 @@ define void @struct_pair32_array(i32 addrspace(1)* %out, i32 %index) { entry: %alloca = alloca [2 x %struct.pair32] - %gep0 = getelementptr [2 x %struct.pair32], [2 x %struct.pair32]* %alloca, i32 0, i32 0, i32 1 - %gep1 = getelementptr [2 x %struct.pair32], [2 x %struct.pair32]* %alloca, i32 0, i32 1, i32 0 + %gep0 = getelementptr inbounds [2 x %struct.pair32], [2 x %struct.pair32]* %alloca, i32 0, i32 0, i32 1 + %gep1 = getelementptr inbounds [2 x %struct.pair32], [2 x %struct.pair32]* %alloca, i32 0, i32 1, i32 0 store i32 0, i32* %gep0 store i32 1, i32* %gep1 - %gep2 = getelementptr [2 x %struct.pair32], [2 x %struct.pair32]* %alloca, i32 0, i32 %index, i32 0 + %gep2 = getelementptr inbounds [2 x %struct.pair32], [2 x %struct.pair32]* %alloca, i32 0, i32 %index, i32 0 %load = load i32, i32* %gep2 store i32 %load, i32 addrspace(1)* %out ret void @@ -264,8 +264,8 @@ define void @select_private(i32 addrspace(1)* %out, i32 %in) nounwind { entry: %tmp = alloca [2 x i32] - %tmp1 = getelementptr [2 x i32], [2 x i32]* %tmp, i32 0, i32 0 - %tmp2 = getelementptr [2 x i32], [2 x i32]* %tmp, i32 0, i32 1 + %tmp1 = getelementptr inbounds [2 x i32], [2 x i32]* %tmp, i32 0, i32 0 + %tmp2 = getelementptr inbounds [2 x i32], [2 x i32]* %tmp, i32 0, i32 1 store i32 0, i32* %tmp1 store i32 1, i32* %tmp2 %cmp = icmp eq i32 %in, 0 @@ -284,12 +284,12 @@ ; SI: buffer_load_dword v{{[0-9]+}}, v{{[0-9]+}}, s[{{[0-9]+:[0-9]+}}], s{{[0-9]+}} offen ; define void @ptrtoint(i32 addrspace(1)* %out, i32 %a, i32 %b) { %alloca = alloca [16 x i32] - %tmp0 = getelementptr [16 x i32], [16 x i32]* %alloca, i32 0, i32 %a + %tmp0 = getelementptr inbounds [16 x i32], [16 x i32]* %alloca, i32 0, i32 %a store i32 5, i32* %tmp0 %tmp1 = ptrtoint [16 x i32]* %alloca to i32 %tmp2 = add i32 %tmp1, 5 %tmp3 = inttoptr i32 %tmp2 to i32* - %tmp4 = getelementptr i32, i32* %tmp3, i32 %b + %tmp4 = getelementptr inbounds i32, i32* %tmp3, i32 %b %tmp5 = load i32, i32* %tmp4 store i32 %tmp5, i32 addrspace(1)* %out ret void Index: test/CodeGen/AMDGPU/private-memory.ll =================================================================== --- test/CodeGen/AMDGPU/private-memory.ll +++ test/CodeGen/AMDGPU/private-memory.ll @@ -5,12 +5,13 @@ ; RUN: llc -show-mc-encoding -mattr=+promote-alloca -verify-machineinstrs -march=amdgcn -mcpu=tonga < %s | FileCheck %s -check-prefix=SI-PROMOTE -check-prefix=SI -check-prefix=FUNC ; RUN: llc -show-mc-encoding -mattr=-promote-alloca -verify-machineinstrs -march=amdgcn -mcpu=tonga < %s | FileCheck %s -check-prefix=SI-ALLOCA -check-prefix=SI -check-prefix=FUNC -; RUN: opt -S -mtriple=amdgcn-unknown-amdhsa -mcpu=kaveri -amdgpu-promote-alloca < %s | FileCheck -check-prefix=HSAOPT %s -; RUN: opt -S -mtriple=amdgcn-unknown-unknown -mcpu=kaveri -amdgpu-promote-alloca < %s | FileCheck -check-prefix=NOHSAOPT %s +; RUN: opt -S -mtriple=amdgcn-unknown-amdhsa -mcpu=kaveri -amdgpu-promote-alloca < %s | FileCheck -check-prefix=HSAOPT -check-prefix=OPT %s +; RUN: opt -S -mtriple=amdgcn-unknown-unknown -mcpu=kaveri -amdgpu-promote-alloca < %s | FileCheck -check-prefix=NOHSAOPT -check-prefix=OPT %s declare i32 @llvm.amdgcn.workitem.id.x() nounwind readnone ; FUNC-LABEL: {{^}}mova_same_clause: +; OPT-LABEL: @mova_same_clause( ; R600: LDS_WRITE ; R600: LDS_WRITE @@ -90,6 +91,31 @@ ret void } +; FUNC-LABEL: {{^}}no_replace_inbounds_gep: +; OPT-LABEL: @no_replace_inbounds_gep( +; OPT: alloca [5 x i32] + +; SI-NOT: ds_write +define void @no_replace_inbounds_gep(i32 addrspace(1)* nocapture %out, i32 addrspace(1)* nocapture %in) { +entry: + %stack = alloca [5 x i32], align 4 + %0 = load i32, i32 addrspace(1)* %in, align 4 + %arrayidx1 = getelementptr [5 x i32], [5 x i32]* %stack, i32 0, i32 %0 + store i32 4, i32* %arrayidx1, align 4 + %arrayidx2 = getelementptr inbounds i32, i32 addrspace(1)* %in, i32 1 + %1 = load i32, i32 addrspace(1)* %arrayidx2, align 4 + %arrayidx3 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 %1 + store i32 5, i32* %arrayidx3, align 4 + %arrayidx10 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 0 + %2 = load i32, i32* %arrayidx10, align 4 + store i32 %2, i32 addrspace(1)* %out, align 4 + %arrayidx12 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 1 + %3 = load i32, i32* %arrayidx12 + %arrayidx13 = getelementptr inbounds i32, i32 addrspace(1)* %out, i32 1 + store i32 %3, i32 addrspace(1)* %arrayidx13 + ret void +} + ; This test checks that the stack offset is calculated correctly for structs. ; All register loads/stores should be optimized away, so there shouldn't be ; any MOVA instructions. @@ -98,6 +124,8 @@ ; this. ; FUNC-LABEL: {{^}}multiple_structs: +; OPT-LABEL: @multiple_structs( + ; R600-NOT: MOVA_INT ; SI-NOT: v_movrel ; SI-NOT: v_movrel @@ -137,19 +165,19 @@ %prv_array_const = alloca [2 x i32] %prv_array = alloca [2 x i32] %a = load i32, i32 addrspace(1)* %in - %b_src_ptr = getelementptr i32, i32 addrspace(1)* %in, i32 1 + %b_src_ptr = getelementptr inbounds i32, i32 addrspace(1)* %in, i32 1 %b = load i32, i32 addrspace(1)* %b_src_ptr - %a_dst_ptr = getelementptr [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 0 + %a_dst_ptr = getelementptr inbounds [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 0 store i32 %a, i32* %a_dst_ptr - %b_dst_ptr = getelementptr [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 1 + %b_dst_ptr = getelementptr inbounds [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 1 store i32 %b, i32* %b_dst_ptr br label %for.body for.body: %inc = phi i32 [0, %entry], [%count, %for.body] - %x_ptr = getelementptr [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 0 + %x_ptr = getelementptr inbounds [2 x i32], [2 x i32]* %prv_array_const, i32 0, i32 0 %x = load i32, i32* %x_ptr - %y_ptr = getelementptr [2 x i32], [2 x i32]* %prv_array, i32 0, i32 0 + %y_ptr = getelementptr inbounds [2 x i32], [2 x i32]* %prv_array, i32 0, i32 0 %y = load i32, i32* %y_ptr %xy = add i32 %x, %y store i32 %xy, i32* %y_ptr @@ -158,7 +186,7 @@ br i1 %done, label %for.end, label %for.body for.end: - %value_ptr = getelementptr [2 x i32], [2 x i32]* %prv_array, i32 0, i32 0 + %value_ptr = getelementptr inbounds [2 x i32], [2 x i32]* %prv_array, i32 0, i32 0 %value = load i32, i32* %value_ptr store i32 %value, i32 addrspace(1)* %out ret void @@ -174,11 +202,11 @@ define void @short_array(i32 addrspace(1)* %out, i32 %index) { entry: %0 = alloca [2 x i16] - %1 = getelementptr [2 x i16], [2 x i16]* %0, i32 0, i32 0 - %2 = getelementptr [2 x i16], [2 x i16]* %0, i32 0, i32 1 + %1 = getelementptr inbounds [2 x i16], [2 x i16]* %0, i32 0, i32 0 + %2 = getelementptr inbounds [2 x i16], [2 x i16]* %0, i32 0, i32 1 store i16 0, i16* %1 store i16 1, i16* %2 - %3 = getelementptr [2 x i16], [2 x i16]* %0, i32 0, i32 %index + %3 = getelementptr inbounds [2 x i16], [2 x i16]* %0, i32 0, i32 %index %4 = load i16, i16* %3 %5 = sext i16 %4 to i32 store i32 %5, i32 addrspace(1)* %out @@ -194,11 +222,11 @@ define void @char_array(i32 addrspace(1)* %out, i32 %index) { entry: %0 = alloca [2 x i8] - %1 = getelementptr [2 x i8], [2 x i8]* %0, i32 0, i32 0 - %2 = getelementptr [2 x i8], [2 x i8]* %0, i32 0, i32 1 + %1 = getelementptr inbounds [2 x i8], [2 x i8]* %0, i32 0, i32 0 + %2 = getelementptr inbounds [2 x i8], [2 x i8]* %0, i32 0, i32 1 store i8 0, i8* %1 store i8 1, i8* %2 - %3 = getelementptr [2 x i8], [2 x i8]* %0, i32 0, i32 %index + %3 = getelementptr inbounds [2 x i8], [2 x i8]* %0, i32 0, i32 %index %4 = load i8, i8* %3 %5 = sext i8 %4 to i32 store i32 %5, i32 addrspace(1)* %out