mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
AMDGPU: Do not promote allocas with non-inbounds GEPs
If we can't assume the pointer value isn't within the bounds of the object, it seems risky to try to replace the pointer calculations. llvm-svn: 259573
This commit is contained in:
parent
1eab1a7019
commit
b7a70ed17f
@ -447,6 +447,13 @@ static bool collectUsesWithPtrTypes(Value *Val, std::vector<Value*> &WorkList) {
|
||||
if (!User->getType()->isPointerTy())
|
||||
continue;
|
||||
|
||||
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(UseInst)) {
|
||||
// Be conservative if an address could be computed outside the bounds of
|
||||
// the alloca.
|
||||
if (!GEP->isInBounds())
|
||||
return false;
|
||||
}
|
||||
|
||||
WorkList.push_back(User);
|
||||
if (!collectUsesWithPtrTypes(User, WorkList))
|
||||
return false;
|
||||
|
@ -20,24 +20,24 @@ declare void @llvm.AMDGPU.barrier.local() nounwind convergent
|
||||
; 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
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ declare void @llvm.AMDGPU.barrier.local() convergent nounwind
|
||||
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_f64_alloca(double addrspace(1)* noalias %out, double
|
||||
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_v2f64_alloca(<2 x double> addrspace(1)* noalias %out
|
||||
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_i64_alloca(i64 addrspace(1)* noalias %out, i64 addrs
|
||||
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
|
||||
|
@ -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 @@ entry:
|
||||
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
|
||||
|
@ -51,16 +51,16 @@ define void @multiple_structs(i32 addrspace(1)* %out) {
|
||||
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 @@ entry:
|
||||
%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 @@ for.body:
|
||||
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 @@ for.end:
|
||||
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 @@ entry:
|
||||
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 @@ entry:
|
||||
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 @@ define void @no_overlap(i32 addrspace(1)* %out, i32 %in) {
|
||||
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 @@ entry:
|
||||
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 @@ entry:
|
||||
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 @@ entry:
|
||||
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 @@ entry:
|
||||
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 @@ entry:
|
||||
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 @@ entry:
|
||||
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 @@ entry:
|
||||
; 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
|
||||
|
@ -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 @@ entry:
|
||||
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 @@ entry:
|
||||
; 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 @@ entry:
|
||||
%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 @@ for.body:
|
||||
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 @@ for.end:
|
||||
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 @@ entry:
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user