mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-01 15:17:25 +00:00
[PowerPC] Fix "byval align" arguments
Arguments passed as "byval align" should get the specified alignment in the parameter save area. There was some code in PPCISelLowering.cpp that attempted to implement this, but this didn't work correctly: while code did update the ArgOffset value, it neglected to update the PtrOff value (which was already computed from the old ArgOffset), and it also neglected to update GPR_idx -- fields skipped due to alignment in the save area must likewise be skipped in GPRs. This patch fixes and simplifies this logic by: - handling argument offset alignment right at the beginning of argument processing, using a new helper routine CalculateStackSlotAlignment (this avoids having to update PtrOff and other derived values later on) - not tracking GPR_idx separately, but always computing the correct GPR_idx for each argument *from* its ArgOffset - removing some redundant computation in LowerFormalArguments: MinReservedArea must equal ArgOffset after argument processing, so there's no use in computing it twice. [This doesn't change the behavior of the current clang front-end, since that never creates "byval align" arguments at the moment. This will change with a follow-on patch, however.] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212476 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
56
test/CodeGen/PowerPC/ppc64-byval-align.ll
Normal file
56
test/CodeGen/PowerPC/ppc64-byval-align.ll
Normal file
@@ -0,0 +1,56 @@
|
||||
; RUN: llc -O1 < %s -march=ppc64 | FileCheck %s
|
||||
|
||||
target datalayout = "E-m:e-i64:64-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
|
||||
%struct.test = type { i64, [8 x i8] }
|
||||
%struct.pad = type { [8 x i64] }
|
||||
|
||||
@gt = common global %struct.test zeroinitializer, align 16
|
||||
@gp = common global %struct.pad zeroinitializer, align 8
|
||||
|
||||
define signext i32 @callee1(i32 signext %x, %struct.test* byval align 16 nocapture readnone %y, i32 signext %z) {
|
||||
entry:
|
||||
ret i32 %z
|
||||
}
|
||||
; CHECK-LABEL: @callee1
|
||||
; CHECK: mr 3, 7
|
||||
; CHECK: blr
|
||||
|
||||
declare signext i32 @test1(i32 signext, %struct.test* byval align 16, i32 signext)
|
||||
define void @caller1(i32 signext %z) {
|
||||
entry:
|
||||
%call = tail call signext i32 @test1(i32 signext 0, %struct.test* byval align 16 @gt, i32 signext %z)
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: @caller1
|
||||
; CHECK: mr [[REG:[0-9]+]], 3
|
||||
; CHECK: mr 7, [[REG]]
|
||||
; CHECK: bl test1
|
||||
|
||||
define i64 @callee2(%struct.pad* byval nocapture readnone %x, i32 signext %y, %struct.test* byval align 16 nocapture readonly %z) {
|
||||
entry:
|
||||
%x1 = getelementptr inbounds %struct.test* %z, i64 0, i32 0
|
||||
%0 = load i64* %x1, align 16
|
||||
ret i64 %0
|
||||
}
|
||||
; CHECK-LABEL: @callee2
|
||||
; CHECK: ld [[REG:[0-9]+]], 128(1)
|
||||
; CHECK: mr 3, [[REG]]
|
||||
; CHECK: blr
|
||||
|
||||
declare i64 @test2(%struct.pad* byval, i32 signext, %struct.test* byval align 16)
|
||||
define void @caller2(i64 %z) {
|
||||
entry:
|
||||
%tmp = alloca %struct.test, align 16
|
||||
%.compoundliteral.sroa.0.0..sroa_idx = getelementptr inbounds %struct.test* %tmp, i64 0, i32 0
|
||||
store i64 %z, i64* %.compoundliteral.sroa.0.0..sroa_idx, align 16
|
||||
%call = call i64 @test2(%struct.pad* byval @gp, i32 signext 0, %struct.test* byval align 16 %tmp)
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: @caller2
|
||||
; CHECK: std 3, [[OFF:[0-9]+]](1)
|
||||
; CHECK: ld [[REG:[0-9]+]], [[OFF]](1)
|
||||
; CHECK: std [[REG]], 128(1)
|
||||
; CHECK: bl test2
|
||||
|
||||
Reference in New Issue
Block a user