Arsenault, Matthew via llvm-dev
2021-Mar-06 01:57 UTC
[llvm-dev] Are calls with byval broken for AArch64 GlobalISel?
[AMD Public Use] I noticed the byval handling is largely missing from the GlobalISel call lowering implementation, and noticed AArch64 is producing different code vs. SelectionDAG. Specifically, it is not copying byval argument contents and is just directly passing the pointer. If the callee were to modify the memory, it would incorrectly overwrite the caller's value. Consider this minimal example: define i32 @call_byval(i32 %arg0) { %alloca = alloca i32 %ret = call i32 @callee(i32* byval %alloca) ret i32 %ret } For SelectionDAG, this inserts a copy: sub sp, sp, #32 str x30, [sp, #16] .cfi_def_cfa_offset 32 .cfi_offset w30, -16 ldr w8, [sp, #28] // Read value str w8, [sp] // Copy to outgoing slot bl callee For GlobalISel, this copy is missing: sub sp, sp, #32 str x30, [sp, #16] .cfi_def_cfa_offset 32 .cfi_offset w30, -16 bl callee -Matt -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210306/90a87dfe/attachment-0001.html>
Arsenault, Matthew via llvm-dev
2021-Mar-06 14:12 UTC
[llvm-dev] Are calls with byval broken for AArch64 GlobalISel?
[AMD Public Use] The incoming direction also looks totally broken: define void @test_byval(i8* byval(i8) %ptr) { %load = load volatile i8, i8* %ptr ret void } // SDAG: .cfi_startproc ldrb w8, [sp] ret // GISel: .cfi_startproc ; %bb.0: ldr x8, [sp] ldrb wzr, [x8] ret I have a patch which fixes this second half, but wanted to confirm this is fixing the AArch64 ABI and not breaking it -Matt ________________________________ From: llvm-dev <llvm-dev-bounces at lists.llvm.org> on behalf of Arsenault, Matthew via llvm-dev <llvm-dev at lists.llvm.org> Sent: Friday, March 5, 2021 8:57 PM To: llvm-dev <llvm-dev at lists.llvm.org> Subject: [llvm-dev] Are calls with byval broken for AArch64 GlobalISel? [AMD Public Use] [CAUTION: External Email] [AMD Public Use] I noticed the byval handling is largely missing from the GlobalISel call lowering implementation, and noticed AArch64 is producing different code vs. SelectionDAG. Specifically, it is not copying byval argument contents and is just directly passing the pointer. If the callee were to modify the memory, it would incorrectly overwrite the caller's value. Consider this minimal example: define i32 @call_byval(i32 %arg0) { %alloca = alloca i32 %ret = call i32 @callee(i32* byval %alloca) ret i32 %ret } For SelectionDAG, this inserts a copy: sub sp, sp, #32 str x30, [sp, #16] .cfi_def_cfa_offset 32 .cfi_offset w30, -16 ldr w8, [sp, #28] // Read value str w8, [sp] // Copy to outgoing slot bl callee For GlobalISel, this copy is missing: sub sp, sp, #32 str x30, [sp, #16] .cfi_def_cfa_offset 32 .cfi_offset w30, -16 bl callee -Matt -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210306/8fdd7e7e/attachment.html>