From 1437f6d710ecf2c7a6aa19858e57a93ee0685338 Mon Sep 17 00:00:00 2001 From: Diana Picus Date: Mon, 19 Dec 2016 11:55:41 +0000 Subject: [PATCH] [ARM] GlobalISel: Lower more than 4 arguments This adds support for lowering more than 4 arguments (although still i32 only). It uses the handleAssignments / ValueHandler infrastructure extracted from the AArch64 backend in r288658. Differential Revision: https://reviews.llvm.org/D27195 llvm-svn: 290098 --- llvm/lib/Target/ARM/ARMCallLowering.cpp | 32 +++++++++++++------ .../ARM/GlobalISel/arm-irtranslator.ll | 17 ++++++++++ llvm/test/CodeGen/ARM/GlobalISel/arm-isel.ll | 11 +++++++ 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp index f266e1889505..de40dd0db0e2 100644 --- a/llvm/lib/Target/ARM/ARMCallLowering.cpp +++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp @@ -19,6 +19,7 @@ #include "ARMISelLowering.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" using namespace llvm; @@ -115,7 +116,27 @@ struct FormalArgHandler : public CallLowering::ValueHandler { unsigned getStackAddress(uint64_t Size, int64_t Offset, MachinePointerInfo &MPO) override { - llvm_unreachable("Don't know how to get a stack address yet"); + assert(Size == 4 && "Unsupported size"); + + auto &MFI = MIRBuilder.getMF().getFrameInfo(); + + int FI = MFI.CreateFixedObject(Size, Offset, true); + MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); + + unsigned AddrReg = + MRI.createGenericVirtualRegister(LLT::pointer(MPO.getAddrSpace(), 32)); + MIRBuilder.buildFrameIndex(AddrReg, FI); + + return AddrReg; + } + + void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, + MachinePointerInfo &MPO, CCValAssign &VA) override { + assert(Size == 4 && "Unsupported size"); + + auto MMO = MIRBuilder.getMF().getMachineMemOperand( + MPO, MachineMemOperand::MOLoad, Size, /* Alignment */ 0); + MIRBuilder.buildLoad(ValVReg, Addr, *MMO); } void assignValueToReg(unsigned ValVReg, unsigned PhysReg, @@ -129,11 +150,6 @@ struct FormalArgHandler : public CallLowering::ValueHandler { MIRBuilder.getMBB().addLiveIn(PhysReg); MIRBuilder.buildCopy(ValVReg, PhysReg); } - - void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, - MachinePointerInfo &MPO, CCValAssign &VA) override { - llvm_unreachable("Don't know how to assign a value to an address yet"); - } }; } // End anonymous namespace @@ -144,10 +160,6 @@ bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, if (F.arg_empty()) return true; - // Stick to only 4 arguments for now - if (F.arg_size() > 4) - return false; - if (F.isVarArg()) return false; diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll b/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll index de9e082d1ba5..a9909817bafd 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll @@ -19,3 +19,20 @@ entry: %sum = add i32 %x, %y ret i32 %sum } + +define i32 @test_many_args(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) { +; CHECK-LABEL: name: test_many_args +; CHECK: fixedStack: +; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 4 +; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 4 +; CHECK: liveins: %r0, %r1, %r2, %r3 +; CHECK: [[VREGP2:%[0-9]+]]{{.*}} = COPY %r2 +; CHECK: [[FIP5:%[0-9]+]]{{.*}} = G_FRAME_INDEX %fixed-stack.[[P5]] +; CHECK: [[VREGP5:%[0-9]+]]{{.*}} = G_LOAD [[FIP5]] +; CHECK: [[SUM:%[0-9]+]]{{.*}} = G_ADD [[VREGP2]], [[VREGP5]] +; CHECK: %r0 = COPY [[SUM]] +; CHECK: BX_RET 14, _, implicit %r0 +entry: + %sum = add i32 %p2, %p5 + ret i32 %sum +} diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-isel.ll b/llvm/test/CodeGen/ARM/GlobalISel/arm-isel.ll index 0d62c6f7bfa9..59c788892ce9 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-isel.ll +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-isel.ll @@ -15,3 +15,14 @@ entry: %sum = add i32 %x, %y ret i32 %sum } + +define i32 @test_many_args(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) { +; CHECK-LABEL: test_many_args: +; CHECK: add [[P5ADDR:r[0-9]+]], sp, #4 +; CHECK: ldr [[P5:r[0-9]+]], {{.*}}[[P5ADDR]] +; CHECK: add r0, r2, [[P5]] +; CHECK: bx lr +entry: + %sum = add i32 %p2, %p5 + ret i32 %sum +}