diff options
| author | Tim Northover <tnorthover@apple.com> | 2017-08-17 23:14:01 +0000 |
|---|---|---|
| committer | Tim Northover <tnorthover@apple.com> | 2017-08-17 23:14:01 +0000 |
| commit | 48fff995d62b227e742c53f472c04e8ac11a3ede (patch) | |
| tree | c774b27eae44f2dffaa6a904c5c538e89d1d0879 /llvm/test/CodeGen | |
| parent | dea43983ae0efb1cde6ea7e76cc8730407656b74 (diff) | |
| download | bcm5719-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
Diffstat (limited to 'llvm/test/CodeGen')
| -rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll | 39 |
1 files changed, 39 insertions, 0 deletions
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 +} |

