[mips] Enable tail calls by default
Enable tail calls by default for (micro)MIPS(64).
microMIPS is slightly more tricky than doing it for MIPS(R6) or microMIPSR6.
microMIPS has two instruction encodings: 16bit and 32bit along with some
restrictions on the size of the instruction that can fill the delay slot.
For safe tail calls for microMIPS, the delay slot filler attempts to find
a correct size instruction for the delay slot of TAILCALL pseudos.
Reviewers: dsanders, vkalintris
Subscribers: jfb, dsanders, sdardis, llvm-commits
Differential Revision: https://reviews.llvm.org/D21138
llvm-svn: 277708
diff --git a/llvm/test/CodeGen/Mips/biggot.ll b/llvm/test/CodeGen/Mips/biggot.ll
index aafaf55..9494054 100644
--- a/llvm/test/CodeGen/Mips/biggot.ll
+++ b/llvm/test/CodeGen/Mips/biggot.ll
@@ -1,11 +1,12 @@
; RUN: llc -march=mipsel -mxgot -relocation-model=pic < %s | FileCheck %s -check-prefix=O32
-; RUN: llc -march=mips64el -mcpu=mips64r2 -mattr=+n64 -mxgot -relocation-model=pic < %s | \
+; RUN: llc -march=mips64el -mcpu=mips64r2 -mxgot -relocation-model=pic < %s | \
; RUN: FileCheck %s -check-prefix=N64
@v0 = external global i32
define void @foo1() nounwind {
entry:
+; O32-LABEL: foo1:
; O32: lui $[[R0:[0-9]+]], %got_hi(v0)
; O32: addu $[[R1:[0-9]+]], $[[R0]], ${{[a-z0-9]+}}
; O32: lw ${{[0-9]+}}, %got_lo(v0)($[[R1]])
@@ -13,11 +14,12 @@
; O32: addu $[[R3:[0-9]+]], $[[R2]], ${{[a-z0-9]+}}
; O32: lw ${{[0-9]+}}, %call_lo(foo0)($[[R3]])
+; N64-LABEL: foo1:
; N64: lui $[[R0:[0-9]+]], %got_hi(v0)
; N64: daddu $[[R1:[0-9]+]], $[[R0]], ${{[a-z0-9]+}}
-; N64: ld ${{[0-9]+}}, %got_lo(v0)($[[R1]])
; N64: lui $[[R2:[0-9]+]], %call_hi(foo0)
; N64: daddu $[[R3:[0-9]+]], $[[R2]], ${{[a-z0-9]+}}
+; N64: ld ${{[0-9]+}}, %got_lo(v0)($[[R1]])
; N64: ld ${{[0-9]+}}, %call_lo(foo0)($[[R3]])
%0 = load i32, i32* @v0, align 4
diff --git a/llvm/test/CodeGen/Mips/brdelayslot.ll b/llvm/test/CodeGen/Mips/brdelayslot.ll
index 3a5d4dc..136cc65 100644
--- a/llvm/test/CodeGen/Mips/brdelayslot.ll
+++ b/llvm/test/CodeGen/Mips/brdelayslot.ll
@@ -22,7 +22,7 @@
; None: nop
; None: .end
- tail call void @foo2(i32 3) nounwind
+ call void @foo2(i32 3) nounwind
ret void
}
@@ -37,7 +37,7 @@
; Default: cvt.d.w
%conv = sitofp i32 %a to double
- tail call void @foo4(double %conv) nounwind
+ call void @foo4(double %conv) nounwind
ret void
}
@@ -83,7 +83,7 @@
define void @foo6(float %a0, double %a1) nounwind {
entry:
- tail call void @foo7(double %a1, float %a0) nounwind
+ call void @foo7(double %a1, float %a0) nounwind
ret void
}
@@ -101,7 +101,7 @@
entry:
store i32 %a, i32* @g1, align 4
%0 = load void ()*, void ()** @foo9, align 4
- tail call void %0() nounwind
+ call void %0() nounwind
%1 = load i32, i32* @g1, align 4
%add = add nsw i32 %1, %a
ret i32 %add
diff --git a/llvm/test/CodeGen/Mips/cconv/reserved-space.ll b/llvm/test/CodeGen/Mips/cconv/reserved-space.ll
index a17377b..0a92234 100644
--- a/llvm/test/CodeGen/Mips/cconv/reserved-space.ll
+++ b/llvm/test/CodeGen/Mips/cconv/reserved-space.ll
@@ -17,7 +17,7 @@
define void @reserved_space() nounwind {
entry:
- tail call void @foo()
+ call void @foo()
ret void
}
diff --git a/llvm/test/CodeGen/Mips/fastcc.ll b/llvm/test/CodeGen/Mips/fastcc.ll
index 4b6191f..bf082f6 100644
--- a/llvm/test/CodeGen/Mips/fastcc.ll
+++ b/llvm/test/CodeGen/Mips/fastcc.ll
@@ -290,7 +290,7 @@
; NOODDSPREG-DAG: lwc1 $f18, 36($[[R0]])
; NOODDSPREG-DAG: lwc1 $[[F0:f[0-9]*[02468]]], 40($[[R0]])
-; NOODDSPREG-DAG: swc1 $[[F0]], 0($sp)
+; NOODDSPREG-DAG: swc1 $[[F0]], 8($sp)
%0 = load float, float* getelementptr ([11 x float], [11 x float]* @fa, i32 0, i32 0), align 4
%1 = load float, float* getelementptr ([11 x float], [11 x float]* @fa, i32 0, i32 1), align 4
diff --git a/llvm/test/CodeGen/Mips/gpreg-lazy-binding.ll b/llvm/test/CodeGen/Mips/gpreg-lazy-binding.ll
index 98849de..0330d7c 100644
--- a/llvm/test/CodeGen/Mips/gpreg-lazy-binding.ll
+++ b/llvm/test/CodeGen/Mips/gpreg-lazy-binding.ll
@@ -6,7 +6,7 @@
; CHECK: jalr $25
; CHECK: nop
; CHECK-NOT: move $gp
-; CHECK: jalr $25
+; CHECK: jr $25
define void @f0() nounwind {
entry:
diff --git a/llvm/test/CodeGen/Mips/i64arg.ll b/llvm/test/CodeGen/Mips/i64arg.ll
index 22a0c1f..036b88e 100644
--- a/llvm/test/CodeGen/Mips/i64arg.ll
+++ b/llvm/test/CodeGen/Mips/i64arg.ll
@@ -2,14 +2,14 @@
define void @f1(i64 %ll1, float %f, i64 %ll, i32 %i, float %f2) nounwind {
entry:
-; CHECK-DAG: lw $[[R2:[0-9]+]], 80($sp)
-; CHECK-DAG: lw $[[R3:[0-9]+]], 84($sp)
+; CHECK-DAG: lw $[[R2:[0-9]+]], 64($sp)
+; CHECK-DAG: lw $[[R3:[0-9]+]], 68($sp)
; CHECK-DAG: move $[[R1:[0-9]+]], $5
; CHECK-DAG: move $[[R0:[0-9]+]], $4
; CHECK-DAG: ori $6, ${{[0-9]+}}, 3855
; CHECK-DAG: ori $7, ${{[0-9]+}}, 22136
; CHECK-DAG: lw $25, %call16(ff1)
-; CHECK: jalr
+; CHECK: jalr $25
tail call void @ff1(i32 %i, i64 1085102592623924856) nounwind
; CHECK-DAG: lw $25, %call16(ff2)
; CHECK-DAG: move $4, $[[R2]]
@@ -18,11 +18,11 @@
tail call void @ff2(i64 %ll, double 3.000000e+00) nounwind
%sub = add nsw i32 %i, -1
; CHECK-DAG: lw $25, %call16(ff3)
-; CHECK-DAG: sw $[[R1]], 28($sp)
-; CHECK-DAG: sw $[[R0]], 24($sp)
+; CHECK-DAG: sw $[[R1]], 76($sp)
+; CHECK-DAG: sw $[[R0]], 72($sp)
; CHECK-DAG: move $6, $[[R2]]
; CHECK-DAG: move $7, $[[R3]]
-; CHECK: jalr $25
+; CHECK: jr $25
tail call void @ff3(i32 %i, i64 %ll, i32 %sub, i64 %ll1) nounwind
ret void
}
diff --git a/llvm/test/CodeGen/Mips/indirectcall.ll b/llvm/test/CodeGen/Mips/indirectcall.ll
index ac565d6..97c29d0 100644
--- a/llvm/test/CodeGen/Mips/indirectcall.ll
+++ b/llvm/test/CodeGen/Mips/indirectcall.ll
@@ -2,7 +2,7 @@
define void @foo0(void (i32)* nocapture %f1) nounwind {
entry:
-; CHECK: jalr $25
+; CHECK: jr $25
tail call void %f1(i32 13) nounwind
ret void
}
diff --git a/llvm/test/CodeGen/Mips/lazy-binding.ll b/llvm/test/CodeGen/Mips/lazy-binding.ll
index 87040cc..2e2f350 100644
--- a/llvm/test/CodeGen/Mips/lazy-binding.ll
+++ b/llvm/test/CodeGen/Mips/lazy-binding.ll
@@ -30,7 +30,7 @@
; CHECK: lw $25, %call16(foo2)(${{[0-9]+}})
; CHECK: jalr $25
; CHECK: lw $25, %call16(foo2)(${{[0-9]+}})
-; CHECK: jalr $25
+; CHECK: jr $25
define void @foo1() {
entry:
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/call.ll b/llvm/test/CodeGen/Mips/llvm-ir/call.ll
index 0d524d4..1d0c768 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/call.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/call.ll
@@ -1,18 +1,29 @@
; Test the 'call' instruction and the tailcall variant.
-; FIXME: We should remove the need for -enable-mips-tail-calls
-; RUN: llc -march=mips -mcpu=mips32 -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
-; RUN: llc -march=mips -mcpu=mips32r2 -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
-; RUN: llc -march=mips -mcpu=mips32r3 -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
-; RUN: llc -march=mips -mcpu=mips32r5 -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
-; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,R6C
-; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -mattr=+fp64,+nooddspreg -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,R6C
-; RUN: llc -march=mips64 -mcpu=mips4 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r3 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r5 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r6 -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,R6C
+; RUN: llc -march=mips -mcpu=mips32 -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
+; RUN: llc -march=mips -mcpu=mips32r2 -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
+; RUN: llc -march=mips -mcpu=mips32r3 -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
+; RUN: llc -march=mips -mcpu=mips32r5 -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
+; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,O32,R6C
+; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -mattr=+fp64,+nooddspreg -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,O32,R6C
+; RUN: llc -march=mips64 -mcpu=mips4 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r2 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r3 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r5 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r6 -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,N64,R6C
+; RUN: llc -march=mips -mcpu=mips32 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
+; RUN: llc -march=mips -mcpu=mips32r2 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
+; RUN: llc -march=mips -mcpu=mips32r3 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
+; RUN: llc -march=mips -mcpu=mips32r5 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
+; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=R6C
+; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -mattr=+fp64,+nooddspreg -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=R6C
+; RUN: llc -march=mips64 -mcpu=mips4 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r3 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r5 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r6 -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=R6C
declare void @extern_void_void()
declare i32 @extern_i32_void()
@@ -76,7 +87,8 @@
; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
-; ALL: jr $[[TGT]]
+; NOT-R6C: jr $[[TGT]]
+; R6C: jrc $[[TGT]]
musttail call void @extern_void_void()
ret void
@@ -89,7 +101,8 @@
; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
-; ALL: jr $[[TGT]]
+; NOT-R6C: jr $[[TGT]]
+; R6C: jrc $[[TGT]]
%1 = musttail call i32 @extern_i32_void()
ret i32 %1
@@ -102,7 +115,8 @@
; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
-; ALL: jr $[[TGT]]
+; NOT-R6C: jr $[[TGT]]
+; R6C: jrc $[[TGT]]
%1 = musttail call float @extern_float_void()
ret float %1
@@ -154,7 +168,8 @@
; ALL-LABEL: tail_indirect_call_void_void:
; ALL: move $25, $4
-; ALL: jr $25
+; NOT-R6C: jr $[[TGT]]
+; R6C: jrc $[[TGT]]
tail call void %addr()
ret void
@@ -164,7 +179,8 @@
; ALL-LABEL: tail_indirect_call_i32_void:
; ALL: move $25, $4
-; ALL: jr $25
+; NOT-R6C: jr $[[TGT]]
+; R6C: jrc $[[TGT]]
%1 = tail call i32 %addr()
ret i32 %1
@@ -174,7 +190,8 @@
; ALL-LABEL: tail_indirect_call_float_void:
; ALL: move $25, $4
-; ALL: jr $25
+; NOT-R6C: jr $[[TGT]]
+; R6C: jrc $[[TGT]]
%1 = tail call float %addr()
ret float %1
@@ -188,7 +205,8 @@
; ALL-LABEL: thunk_undef_double:
; O32: # implicit-def: %A2
; O32: # implicit-def: %A3
-; ALL: jr $25
+; NOT-R6C: jr $[[TGT]]
+; R6C: jrc $[[TGT]]
tail call void @undef_double(i32 undef, double undef) #8
ret void
diff --git a/llvm/test/CodeGen/Mips/nacl-branch-delay.ll b/llvm/test/CodeGen/Mips/nacl-branch-delay.ll
index 2927f39..b0d7e9c 100644
--- a/llvm/test/CodeGen/Mips/nacl-branch-delay.ll
+++ b/llvm/test/CodeGen/Mips/nacl-branch-delay.ll
@@ -44,7 +44,7 @@
define void @test2() {
store i32 1, i32* @x, align 4
- tail call void @f2()
+ call void @f2()
ret void
diff --git a/llvm/test/CodeGen/Mips/tailcall.ll b/llvm/test/CodeGen/Mips/tailcall.ll
index 61f8e50..1db780c 100644
--- a/llvm/test/CodeGen/Mips/tailcall.ll
+++ b/llvm/test/CodeGen/Mips/tailcall.ll
@@ -1,13 +1,32 @@
-; RUN: llc -march=mipsel -relocation-model=pic -enable-mips-tail-calls \
+; RUN: llc -march=mipsel -relocation-model=pic \
; RUN: -verify-machineinstrs < %s | FileCheck %s -check-prefix=PIC32
-; RUN: llc -march=mipsel -relocation-model=static -enable-mips-tail-calls \
+; RUN: llc -march=mipsel -relocation-model=static \
; RUN: -verify-machineinstrs < %s | FileCheck %s -check-prefix=STATIC32
-; RUN: llc -march=mips64el -mcpu=mips64r2 -enable-mips-tail-calls \
+; RUN: llc -march=mips64el -mcpu=mips64r2 \
; RUN: -verify-machineinstrs < %s | FileCheck %s -check-prefix=N64
; RUN: llc -march=mipsel -mattr=mips16 -relocation-model=pic \
-; RUN: -enable-mips-tail-calls -verify-machineinstrs < %s | \
+; RUN: -verify-machineinstrs < %s | \
; RUN: FileCheck %s -check-prefix=PIC16
+; RUN: llc -march=mipsel -relocation-model=pic -mattr=+micromips < %s | \
+; RUN: FileCheck %s -check-prefix=PIC32
+; RUN: llc -march=mipsel -relocation-model=static -mattr=+micromips \
+; RUN: < %s | FileCheck %s -check-prefix=STATIC32
+
+; RUN: llc -march=mipsel -relocation-model=pic -mcpu=mips32r6 < %s | \
+; RUN: FileCheck %s -check-prefix=PIC32
+; RUN: llc -march=mipsel -relocation-model=static -mcpu=mips32r6 \
+; RUN: < %s | FileCheck %s -check-prefix=STATIC32
+; RUN: llc -march=mips64el -mcpu=mips64r6 \
+; RUN: < %s | FileCheck %s -check-prefix=N64
+
+; RUN: llc -march=mipsel -relocation-model=pic -mcpu=mips32r6 -mattr=+micromips \
+; RUN: < %s | FileCheck %s -check-prefix=PIC32
+; RUN: llc -march=mipsel -relocation-model=static -mcpu=mips32r6 \
+; RUN: -mattr=+micromips < %s | FileCheck %s -check-prefix=STATIC32
+; RUN: llc -march=mips64el -mcpu=mips64r6 -mattr=+micromips < %s \
+; RUN: | FileCheck %s -check-prefix=N64
+
@g0 = common global i32 0, align 4
@g1 = common global i32 0, align 4
@g2 = common global i32 0, align 4
@@ -74,13 +93,13 @@
define i32 @caller5() nounwind readonly {
entry:
; PIC32: .ent caller5
-; PIC32-NOT: jalr
+; PIC32-NOT: jalr $25
; PIC32: .end caller5
; STATIC32: .ent caller5
; STATIC32-NOT: jal
; STATIC32: .end caller5
; N64: .ent caller5
-; N64-NOT: jalr
+; N64-NOT: jalr $25
; N64: .end caller5
; PIC16: .ent caller5
; PIC16: jalrc
@@ -118,6 +137,19 @@
define i32 @caller8_0() nounwind {
entry:
+; PIC32: .ent caller8_0
+; PIC32: jr
+; PIC32: .end caller8_0
+; STATIC32: .ent caller8_0
+; STATIC32: j
+; STATIC32: .end caller8_0
+; N64: .ent caller8_0
+; N64-NOT: jalr $25
+; N64: .end caller8_0
+; PIC16: .ent caller8_0
+; PIC16: jalrc
+; PIC16: .end caller8_0
+
%call = tail call fastcc i32 @caller8_1()
ret i32 %call
}
@@ -131,7 +163,7 @@
; STATIC32: jal
; STATIC32: .end caller8_1
; N64: .ent caller8_1
-; N64-NOT: jalr
+; N64-NOT: jalr $25
; N64: .end caller8_1
; PIC16: .ent caller8_1
; PIC16: jalrc
@@ -149,6 +181,18 @@
define i32 @caller9_0() nounwind {
entry:
+; PIC32: .ent caller9_0
+; PIC32: jr
+; PIC32: .end caller9_0
+; STATIC32: .ent caller9_0
+; STATIC32: j
+; STATIC32: .end caller9_0
+; N64: .ent caller9_0
+; N64-NOT: jalr $25
+; N64: .end caller9_0
+; PIC16: .ent caller9_0
+; PIC16: jalrc
+; PIC16: .end caller9_0
%call = tail call fastcc i32 @caller9_1()
ret i32 %call
}
@@ -177,11 +221,11 @@
define i32 @caller10(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7, i32 %a8) nounwind {
entry:
; PIC32: .ent caller10
-; PIC32-NOT: jalr
+; PIC32-NOT: jalr $25
; STATIC32: .ent caller10
; STATIC32-NOT: jal
; N64: .ent caller10
-; N64-NOT: jalr
+; N64-NOT: jalr $25
; PIC16: .ent caller10
; PIC16: jalrc
@@ -236,7 +280,7 @@
; STATIC32: .ent caller13
; STATIC32-NOT: jal
; N64: .ent caller13
-; N64-NOT: jalr
+; N64-NOT: jalr $25
; PIC16: .ent caller13
; PIC16: jalrc