summaryrefslogtreecommitdiffstats
path: root/test/CodeGen/Mips/lazy-binding.ll
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@mips.com>2013-09-28 00:12:32 +0000
committerAkira Hatanaka <ahatanaka@mips.com>2013-09-28 00:12:32 +0000
commit6ff59a16a05d43fdda587ce600b5b42a63cf3d33 (patch)
tree4a9693eab502c4dbff8219cf9e17ea009803e7e6 /test/CodeGen/Mips/lazy-binding.ll
parente5f32cf3207da58359a6e3aeeb5b01205645f710 (diff)
downloadexternal_llvm-6ff59a16a05d43fdda587ce600b5b42a63cf3d33.zip
external_llvm-6ff59a16a05d43fdda587ce600b5b42a63cf3d33.tar.gz
external_llvm-6ff59a16a05d43fdda587ce600b5b42a63cf3d33.tar.bz2
[mips] Make sure loads from lazy-binding entries do not get CSE'd or hoisted out
of loops. Previously, two consecutive calls to function "func" would result in the following sequence of instructions: 1. load $16, %got(func)($gp) // load address of lazy-binding stub. 2. move $25, $16 3. jalr $25 // jump to lazy-binding stub. 4. nop 5. move $25, $16 6. jalr $25 // jump to lazy-binding stub again. With this patch, the second call directly jumps to func's address, bypassing the lazy-binding resolution routine: 1. load $25, %got(func)($gp) // load address of lazy-binding stub. 2. jalr $25 // jump to lazy-binding stub. 3. nop 4. load $25, %got(func)($gp) // load resolved address of func. 5. jalr $25 // directly jump to func. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191591 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/Mips/lazy-binding.ll')
-rw-r--r--test/CodeGen/Mips/lazy-binding.ll41
1 files changed, 41 insertions, 0 deletions
diff --git a/test/CodeGen/Mips/lazy-binding.ll b/test/CodeGen/Mips/lazy-binding.ll
new file mode 100644
index 0000000..839155a
--- /dev/null
+++ b/test/CodeGen/Mips/lazy-binding.ll
@@ -0,0 +1,41 @@
+; RUN: llc -march=mipsel < %s | FileCheck %s
+
+; CHECK-LABEL: foo6:
+; CHECK: %while.body
+; CHECK: lw $25, %call16(foo2)(${{[0-9]+}})
+; CHECK: jalr $25
+; CHECK: %while.end
+
+define void @foo6(i32 %n) {
+entry:
+ %tobool1 = icmp eq i32 %n, 0
+ br i1 %tobool1, label %while.end, label %while.body
+
+while.body: ; preds = %entry, %while.body
+ %n.addr.02 = phi i32 [ %dec, %while.body ], [ %n, %entry ]
+ %dec = add nsw i32 %n.addr.02, -1
+ tail call void @foo2()
+ %tobool = icmp eq i32 %dec, 0
+ br i1 %tobool, label %while.end, label %while.body
+
+while.end: ; preds = %while.body, %entry
+ ret void
+}
+
+declare void @foo2()
+
+; CHECK-LABEL: foo1:
+; CHECK: lw $25, %call16(foo2)(${{[0-9]+}})
+; CHECK: jalr $25
+; CHECK: lw $25, %call16(foo2)(${{[0-9]+}})
+; CHECK: jalr $25
+; CHECK: lw $25, %call16(foo2)(${{[0-9]+}})
+; CHECK: jalr $25
+
+define void @foo1() {
+entry:
+ tail call void @foo2()
+ tail call void @foo2()
+ tail call void @foo2()
+ ret void
+}