summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen
diff options
context:
space:
mode:
authorJonathan Roelofs <jonathan@codesourcery.com>2014-12-04 19:34:50 +0000
committerJonathan Roelofs <jonathan@codesourcery.com>2014-12-04 19:34:50 +0000
commit300d8ffdf2b07c77a6ffb30fe9b347f430d09df5 (patch)
tree938348af5dd4225968273796a3f8d0097b38e7b4 /llvm/test/CodeGen
parent20675c8478378c632c7906bc74a3606f631825c8 (diff)
downloadbcm5719-llvm-300d8ffdf2b07c77a6ffb30fe9b347f430d09df5.tar.gz
bcm5719-llvm-300d8ffdf2b07c77a6ffb30fe9b347f430d09df5.zip
Fix thumbv4t indirect calls
So there are a couple of issues with indirect calls on thumbv4t. First, the most 'obvious' instruction, 'blx' isn't available until v5t. And secondly, the next-most-obvious sequence: 'mov lr, pc; bx rN' doesn't DTRT in thumb code because the saved off pc has its thumb bit cleared, so when the callee returns we end up in ARM mode.... yuck. The solution is to 'bl' to a nearby landing pad with a 'bx rN' in it. We could cut down on code size by sharing the landing pads between call sites that are close enough, but for the moment let's do correctness first and look at performance later. Patch by: Iain Sandoe http://reviews.llvm.org/D6519 llvm-svn: 223380
Diffstat (limited to 'llvm/test/CodeGen')
-rw-r--r--llvm/test/CodeGen/ARM/none-macho-v4t.ll8
-rw-r--r--llvm/test/CodeGen/ARM/thumb_indirect_calls.ll40
2 files changed, 46 insertions, 2 deletions
diff --git a/llvm/test/CodeGen/ARM/none-macho-v4t.ll b/llvm/test/CodeGen/ARM/none-macho-v4t.ll
index 4c6e68e0632..b6018de796a 100644
--- a/llvm/test/CodeGen/ARM/none-macho-v4t.ll
+++ b/llvm/test/CodeGen/ARM/none-macho-v4t.ll
@@ -11,11 +11,15 @@ define void @test_call() {
; CHECK: [[PC_LABEL:LPC[0-9]+_[0-9]+]]:
; CHECK-NEXT: add r[[CALLEE_STUB]], pc
; CHECK: ldr [[CALLEE:r[0-9]+]], [r[[CALLEE_STUB]]]
-; CHECK: mov lr, pc
-; CHECK: bx [[CALLEE]]
+; CHECK-NOT: mov lr, pc
+; CHECK: bl [[INDIRECT_PAD:Ltmp[0-9]+]]
; CHECK: [[LITPOOL]]:
; CHECK-NEXT: .long L_callee$non_lazy_ptr-([[PC_LABEL]]+4)
+
+; CHECK: [[INDIRECT_PAD]]:
+; CHECK: bx [[CALLEE]]
+
call void @callee()
ret void
}
diff --git a/llvm/test/CodeGen/ARM/thumb_indirect_calls.ll b/llvm/test/CodeGen/ARM/thumb_indirect_calls.ll
new file mode 100644
index 00000000000..16a55a882d9
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/thumb_indirect_calls.ll
@@ -0,0 +1,40 @@
+; RUN: llc -mtriple=thumbv4t-eabi %s -o - | FileCheck ---check-prefix=CHECK -check-prefix=CHECK-V4T %s
+; RUN: llc -mtriple=thumbv5t-eabi %s -o - | FileCheck ---check-prefix=CHECK -check-prefix=CHECK-V5T %s
+
+@f = common global void (i32)* null, align 4
+
+; CHECK-LABEL foo:
+define void @foo(i32 %x) {
+entry:
+ %0 = load void (i32)** @f, align 4
+ tail call void %0(i32 %x)
+ ret void
+
+; CHECK: ldr [[TMP:r[0-3]]], [[F:\.[A-Z0-9_]+]]
+; CHECK: ldr [[CALLEE:r[0-3]]], {{\[}}[[TMP]]{{\]}}
+
+; CHECK-V4T-NOT: blx
+; CHECK-V4T: bl [[INDIRECT_PAD:\.Ltmp[0-9]+]]
+; CHECK-V4T: [[F]]:
+; CHECK-V4T: [[INDIRECT_PAD]]:
+; CHECK-V4T-NEXT: bx [[CALLEE]]
+; CHECK-V5T: blx [[CALLEE]]
+}
+
+; CHECK-LABEL bar:
+define void @bar(void (i32)* nocapture %g, i32 %x, void (i32)* nocapture %h) {
+entry:
+ tail call void %g(i32 %x)
+ tail call void %h(i32 %x)
+ ret void
+
+; CHECK-V4T: bl [[INDIRECT_PAD1:\.Ltmp[0-9]+]]
+; CHECK-V4T: bl [[INDIRECT_PAD2:\.Ltmp[0-9]+]]
+; CHECK-V4T: [[INDIRECT_PAD1]]:
+; CHECK-V4T-NEXT: bx
+; CHECK-V4T: [[INDIRECT_PAD2]]:
+; CHECK-V4T-NEXT: bx
+; CHECK-V5T: blx
+; CHECK-V5T: blx
+}
+
OpenPOWER on IntegriCloud