summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorDiana Picus <diana.picus@linaro.org>2017-02-02 14:01:00 +0000
committerDiana Picus <diana.picus@linaro.org>2017-02-02 14:01:00 +0000
commit32cd9b434c74134368192bd8142e05fe2170ed91 (patch)
tree8bb0ffc65208a95c0dbb91145b4dd6cdc487a2d5 /llvm
parent0c11c7b5c74264354f94c3fd945366e8814d3186 (diff)
downloadbcm5719-llvm-32cd9b434c74134368192bd8142e05fe2170ed91.tar.gz
bcm5719-llvm-32cd9b434c74134368192bd8142e05fe2170ed91.zip
[ARM] GlobalISel: Lower pointer args and returns
It is important to change the ArgInfo's type from pointer to integer, otherwise the CC assign function won't know what to do. Instead of hacking it up, we use ComputeValueVTs and introduce some of the helpers that we will need later on for lowering more complex types. llvm-svn: 293889
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/ARM/ARMCallLowering.cpp35
-rw-r--r--llvm/lib/Target/ARM/ARMCallLowering.h6
-rw-r--r--llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll38
-rw-r--r--llvm/test/CodeGen/ARM/GlobalISel/arm-isel.ll29
4 files changed, 102 insertions, 6 deletions
diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp
index c5b49ef70fd..f37d6d7b1d0 100644
--- a/llvm/lib/Target/ARM/ARMCallLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp
@@ -19,6 +19,7 @@
#include "ARMISelLowering.h"
#include "ARMSubtarget.h"
+#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -74,6 +75,25 @@ struct FuncReturnHandler : public CallLowering::ValueHandler {
};
} // End anonymous namespace.
+void ARMCallLowering::splitToValueTypes(const ArgInfo &OrigArg,
+ SmallVectorImpl<ArgInfo> &SplitArgs,
+ const DataLayout &DL,
+ MachineRegisterInfo &MRI) const {
+ const ARMTargetLowering &TLI = *getTLI<ARMTargetLowering>();
+ LLVMContext &Ctx = OrigArg.Ty->getContext();
+
+ SmallVector<EVT, 4> SplitVTs;
+ SmallVector<uint64_t, 4> Offsets;
+ ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
+
+ assert(SplitVTs.size() == 1 && "Unsupported type");
+
+ // Even if there is no splitting to do, we still want to replace the original
+ // type (e.g. pointer type -> integer).
+ SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx),
+ OrigArg.Flags, OrigArg.IsFixed);
+}
+
/// Lower the return value for the already existing \p Ret. This assumes that
/// \p MIRBuilder's insertion point is correct.
bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
@@ -91,14 +111,16 @@ bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
if (!isSupportedType(DL, TLI, Val->getType()))
return false;
- CCAssignFn *AssignFn =
- TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
-
+ SmallVector<ArgInfo, 4> SplitVTs;
ArgInfo RetInfo(VReg, Val->getType());
setArgFlags(RetInfo, AttributeSet::ReturnIndex, DL, F);
+ splitToValueTypes(RetInfo, SplitVTs, DL, MF.getRegInfo());
+
+ CCAssignFn *AssignFn =
+ TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
FuncReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret, AssignFn);
- return handleAssignments(MIRBuilder, RetInfo, RetHandler);
+ return handleAssignments(MIRBuilder, SplitVTs, RetHandler);
}
bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
@@ -179,7 +201,8 @@ bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
if (F.isVarArg())
return false;
- auto DL = MIRBuilder.getMF().getDataLayout();
+ auto &MF = MIRBuilder.getMF();
+ auto DL = MF.getDataLayout();
auto &TLI = *getTLI<ARMTargetLowering>();
if (TLI.getSubtarget()->isThumb())
@@ -198,7 +221,7 @@ bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
for (auto &Arg : Args) {
ArgInfo AInfo(VRegs[Idx], Arg.getType());
setArgFlags(AInfo, Idx + 1, DL, F);
- ArgInfos.push_back(AInfo);
+ splitToValueTypes(AInfo, ArgInfos, DL, MF.getRegInfo());
Idx++;
}
diff --git a/llvm/lib/Target/ARM/ARMCallLowering.h b/llvm/lib/Target/ARM/ARMCallLowering.h
index 6a1b886b501..7c3b3ddec74 100644
--- a/llvm/lib/Target/ARM/ARMCallLowering.h
+++ b/llvm/lib/Target/ARM/ARMCallLowering.h
@@ -37,6 +37,12 @@ public:
private:
bool lowerReturnVal(MachineIRBuilder &MIRBuilder, const Value *Val,
unsigned VReg, MachineInstrBuilder &Ret) const;
+
+ /// Split an argument into one or more arguments that the CC lowering can cope
+ /// with (e.g. replace pointers with integers).
+ void splitToValueTypes(const ArgInfo &OrigArg,
+ SmallVectorImpl<ArgInfo> &SplitArgs,
+ const DataLayout &DL, MachineRegisterInfo &MRI) const;
};
} // End of namespace llvm
#endif
diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll b/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
index a20a108d8a9..fa17271b547 100644
--- a/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
+++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
@@ -134,3 +134,41 @@ entry:
%sum = add i8 %p2, %p4
ret i8 %sum
}
+
+define i16 @test_ptr_arg(i16* %p) {
+; CHECK-LABEL: name: test_ptr_arg
+; CHECK: liveins: %r0
+; CHECK: [[VREGP:%[0-9]+]](p0) = COPY %r0
+; CHECK: [[VREGV:%[0-9]+]](s16) = G_LOAD [[VREGP]](p0)
+entry:
+ %v = load i16, i16* %p
+ ret i16 %v
+}
+
+define i32* @test_ptr_ret(i32** %p) {
+; Test pointer returns and pointer-to-pointer arguments
+; CHECK-LABEL: name: test_ptr_ret
+; CHECK: liveins: %r0
+; CHECK: [[VREGP:%[0-9]+]](p0) = COPY %r0
+; CHECK: [[VREGV:%[0-9]+]](p0) = G_LOAD [[VREGP]](p0)
+; CHECK: %r0 = COPY [[VREGV]]
+; CHECK: BX_RET 14, _, implicit %r0
+entry:
+ %v = load i32*, i32** %p
+ ret i32* %v
+}
+
+define i32 @test_ptr_arg_on_stack(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32* %p) {
+; CHECK-LABEL: name: test_ptr_arg_on_stack
+; CHECK: fixedStack:
+; CHECK: id: [[P:[0-9]+]]{{.*}}offset: 0{{.*}}size: 4
+; CHECK: liveins: %r0, %r1, %r2, %r3
+; CHECK: [[FIP:%[0-9]+]]{{.*}} = G_FRAME_INDEX %fixed-stack.[[P]]
+; CHECK: [[VREGP:%[0-9]+]](p0) = G_LOAD [[FIP]](p0)
+; CHECK: [[VREGV:%[0-9]+]](s32) = G_LOAD [[VREGP]](p0)
+; CHECK: %r0 = COPY [[VREGV]]
+; CHECK: BX_RET 14, _, implicit %r0
+entry:
+ %v = load i32, i32* %p
+ ret i32 %v
+}
diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-isel.ll b/llvm/test/CodeGen/ARM/GlobalISel/arm-isel.ll
index f5b706e7d21..2b44cd20830 100644
--- a/llvm/test/CodeGen/ARM/GlobalISel/arm-isel.ll
+++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-isel.ll
@@ -110,3 +110,32 @@ entry:
%sum = add i8 %p2, %p4
ret i8 %sum
}
+
+define i32 @test_ptr_arg_in_reg(i32* %p) {
+; CHECK-LABEL: test_ptr_arg_in_reg:
+; CHECK: ldr r0, [r0]
+; CHECK: bx lr
+entry:
+ %v = load i32, i32* %p
+ ret i32 %v
+}
+
+define i32 @test_ptr_arg_on_stack(i32 %f0, i32 %f1, i32 %f2, i32 %f3, i32* %p) {
+; CHECK-LABEL: test_ptr_arg_on_stack:
+; CHECK: mov r0, sp
+; CHECK: ldr r0, [r0]
+; CHECK: ldr r0, [r0]
+; CHECK: bx lr
+entry:
+ %v = load i32, i32* %p
+ ret i32 %v
+}
+
+define i8* @test_ptr_ret(i8** %p) {
+; CHECK-LABEL: test_ptr_ret:
+; CHECK: ldr r0, [r0]
+; CHECK: bx lr
+entry:
+ %v = load i8*, i8** %p
+ ret i8* %v
+}
OpenPOWER on IntegriCloud