summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2017-08-17 23:14:01 +0000
committerTim Northover <tnorthover@apple.com>2017-08-17 23:14:01 +0000
commit48fff995d62b227e742c53f472c04e8ac11a3ede (patch)
treec774b27eae44f2dffaa6a904c5c538e89d1d0879
parentdea43983ae0efb1cde6ea7e76cc8730407656b74 (diff)
downloadbcm5719-llvm-48fff995d62b227e742c53f472c04e8ac11a3ede.tar.gz
bcm5719-llvm-48fff995d62b227e742c53f472c04e8ac11a3ede.zip
GlobalISel (AArch64): fix ABI at border between GPRs and SP.
If a struct would end up half in GPRs and half on SP the ABI says it should actually go entirely on the stack. We were getting this wrong in GlobalISel before, causing compatibility issues. llvm-svn: 311137
-rw-r--r--clang/lib/Driver/ToolChains/Arch/ARM.cpp2
-rw-r--r--llvm/lib/Target/AArch64/AArch64CallLowering.cpp6
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll39
3 files changed, 45 insertions, 2 deletions
diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
index 49bb23535d7..c69efd96e80 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -438,7 +438,7 @@ void arm::getARMTargetFeatures(const ToolChain &TC,
//
// The above behavior is consistent with GCC.
int VersionNum = getARMSubArchVersionNumber(Triple);
- if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
+ if (Triple.isOSBinFormatMachO() || Triple.isOSNetBSD()) {
if (VersionNum < 6 ||
Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
Features.push_back("+strict-align");
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
index fc09763ed38..a0ef3262483 100644
--- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
@@ -188,12 +188,16 @@ void AArch64CallLowering::splitToValueTypes(
}
unsigned FirstRegIdx = SplitArgs.size();
+ bool AlreadySplit = false;
for (auto SplitVT : SplitVTs) {
- // FIXME: set split flags if they're actually used (e.g. i128 on AAPCS).
Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
SplitArgs.push_back(
ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*SplitTy, DL)),
SplitTy, OrigArg.Flags, OrigArg.IsFixed});
+ if (!AlreadySplit) {
+ SplitArgs.back().Flags.setSplit();
+ AlreadySplit = true;
+ }
}
for (unsigned i = 0; i < Offsets.size(); ++i)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
index 1cc196be359..b5d85055f23 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
@@ -215,3 +215,42 @@ define void @test_call_stack() {
define void @test_mem_i1([8 x i64], i1 %in) {
ret void
}
+
+; CHECK-LABEL: name: test_split_struct
+; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD {{.*}}(p0)
+; CHECK: [[LO:%[0-9]+]](s64) = G_EXTRACT [[STRUCT]](s128), 0
+; CHECK: [[HI:%[0-9]+]](s64) = G_EXTRACT [[STRUCT]](s128), 64
+
+; CHECK: [[SP:%[0-9]+]](p0) = COPY %sp
+; CHECK: [[OFF:%[0-9]+]](s64) = G_CONSTANT i64 0
+; CHECK: [[ADDR:%[0-9]+]](p0) = G_GEP [[SP]], [[OFF]]
+; CHECK: G_STORE [[LO]](s64), [[ADDR]](p0) :: (store 8 into stack, align 0)
+
+; CHECK: [[SP:%[0-9]+]](p0) = COPY %sp
+; CHECK: [[OFF:%[0-9]+]](s64) = G_CONSTANT i64 8
+; CHECK: [[ADDR:%[0-9]+]](p0) = G_GEP [[SP]], [[OFF]]
+; CHECK: G_STORE [[HI]](s64), [[ADDR]](p0) :: (store 8 into stack + 8, align 0)
+define void @test_split_struct([2 x i64]* %ptr) {
+ %struct = load [2 x i64], [2 x i64]* %ptr
+ call void @take_split_struct([2 x i64]* null, i64 1, i64 2, i64 3,
+ i64 4, i64 5, i64 6,
+ [2 x i64] %struct)
+ ret void
+}
+
+; CHECK-LABEL: name: take_split_struct
+; CHECK: fixedStack:
+; CHECK-DAG: - { id: [[LO_FRAME:[0-9]+]], type: default, offset: 0, size: 8
+; CHECK-DAG: - { id: [[HI_FRAME:[0-9]+]], type: default, offset: 8, size: 8
+
+; CHECK: [[LOPTR:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[LO_FRAME]]
+; CHECK: [[LO:%[0-9]+]](s64) = G_LOAD [[LOPTR]](p0) :: (invariant load 8 from %fixed-stack.[[LO_FRAME]], align 0)
+
+; CHECK: [[HIPTR:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[HI_FRAME]]
+; CHECK: [[HI:%[0-9]+]](s64) = G_LOAD [[HIPTR]](p0) :: (invariant load 8 from %fixed-stack.[[HI_FRAME]], align 0)
+define void @take_split_struct([2 x i64]* %ptr, i64, i64, i64,
+ i64, i64, i64,
+ [2 x i64] %in) {
+ store [2 x i64] %in, [2 x i64]* %ptr
+ ret void
+}
OpenPOWER on IntegriCloud