mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-15 07:59:57 +00:00
R600: Fix calculation of stack offset in AMDGPUFrameLowering
We weren't computing structure size correctly and we were relying on the original alloca instruction to compute the offset, which isn't always reliable. Reviewed-by: Vincent Lejeune <vljn@ovi.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183568 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fc61b6f111
commit
df74b86e1e
@ -78,27 +78,8 @@ int AMDGPUFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
|
||||
int UpperBound = FI == -1 ? MFI->getNumObjects() : FI;
|
||||
|
||||
for (int i = MFI->getObjectIndexBegin(); i < UpperBound; ++i) {
|
||||
const AllocaInst *Alloca = MFI->getObjectAllocation(i);
|
||||
unsigned ArrayElements;
|
||||
const Type *AllocaType = Alloca->getAllocatedType();
|
||||
const Type *ElementType;
|
||||
|
||||
if (AllocaType->isArrayTy()) {
|
||||
ArrayElements = AllocaType->getArrayNumElements();
|
||||
ElementType = AllocaType->getArrayElementType();
|
||||
} else {
|
||||
ArrayElements = 1;
|
||||
ElementType = AllocaType;
|
||||
}
|
||||
|
||||
unsigned VectorElements;
|
||||
if (ElementType->isVectorTy()) {
|
||||
VectorElements = ElementType->getVectorNumElements();
|
||||
} else {
|
||||
VectorElements = 1;
|
||||
}
|
||||
|
||||
Offset += (VectorElements / getStackWidth(MF)) * ArrayElements;
|
||||
unsigned Size = MFI->getObjectSize(i);
|
||||
Offset += (Size / (getStackWidth(MF) * 4));
|
||||
}
|
||||
return Offset;
|
||||
}
|
||||
|
@ -30,3 +30,36 @@ entry:
|
||||
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.
|
||||
;
|
||||
; XXX: This generated code has unnecessary MOVs, we should be able to optimize
|
||||
; this.
|
||||
|
||||
; CHECK: @multiple_structs
|
||||
; CHECK-NOT: MOVA_INT
|
||||
|
||||
%struct.point = type { i32, i32 }
|
||||
|
||||
define void @multiple_structs(i32 addrspace(1)* %out) {
|
||||
entry:
|
||||
%a = alloca %struct.point
|
||||
%b = alloca %struct.point
|
||||
%a.x.ptr = getelementptr %struct.point* %a, i32 0, i32 0
|
||||
%a.y.ptr = getelementptr %struct.point* %a, i32 0, i32 1
|
||||
%b.x.ptr = getelementptr %struct.point* %b, i32 0, i32 0
|
||||
%b.y.ptr = getelementptr %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* %a, i32 0, i32 0
|
||||
%b.indirect.ptr = getelementptr %struct.point* %b, i32 0, i32 0
|
||||
%a.indirect = load i32* %a.indirect.ptr
|
||||
%b.indirect = load i32* %b.indirect.ptr
|
||||
%0 = add i32 %a.indirect, %b.indirect
|
||||
store i32 %0, i32 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user