Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 1 | ; Test the 'call' instruction and the tailcall variant. |
| 2 | |
Simon Dardis | d2ed8ab | 2016-09-27 13:15:54 +0000 | [diff] [blame] | 3 | ; RUN: llc -march=mips -mcpu=mips32 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C |
| 4 | ; RUN: llc -march=mips -mcpu=mips32r2 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C |
| 5 | ; RUN: llc -march=mips -mcpu=mips32r3 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C |
| 6 | ; RUN: llc -march=mips -mcpu=mips32r5 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C |
| 7 | ; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,R6C |
| 8 | ; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -mattr=+fp64,+nooddspreg -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,R6C |
Simon Dardis | ca74dd7 | 2017-01-27 11:36:52 +0000 | [diff] [blame] | 9 | ; RUN: llc -march=mips64 -mcpu=mips4 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C |
| 10 | ; RUN: llc -march=mips64 -mcpu=mips64 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C |
| 11 | ; RUN: llc -march=mips64 -mcpu=mips64r2 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C |
| 12 | ; RUN: llc -march=mips64 -mcpu=mips64r3 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C |
| 13 | ; RUN: llc -march=mips64 -mcpu=mips64r5 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C |
| 14 | ; RUN: llc -march=mips64 -mcpu=mips64r6 -relocation-model=pic -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,R6C |
Simon Dardis | d2ed8ab | 2016-09-27 13:15:54 +0000 | [diff] [blame] | 15 | ; RUN: llc -march=mips -mcpu=mips32 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C |
| 16 | ; RUN: llc -march=mips -mcpu=mips32r2 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C |
| 17 | ; RUN: llc -march=mips -mcpu=mips32r3 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C |
| 18 | ; RUN: llc -march=mips -mcpu=mips32r5 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C |
| 19 | ; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=R6C |
| 20 | ; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -mattr=+fp64,+nooddspreg -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=R6C |
Simon Dardis | ca74dd7 | 2017-01-27 11:36:52 +0000 | [diff] [blame] | 21 | ; RUN: llc -march=mips64 -mcpu=mips4 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C |
| 22 | ; RUN: llc -march=mips64 -mcpu=mips64 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C |
| 23 | ; RUN: llc -march=mips64 -mcpu=mips64r2 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C |
| 24 | ; RUN: llc -march=mips64 -mcpu=mips64r3 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C |
| 25 | ; RUN: llc -march=mips64 -mcpu=mips64r5 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C |
| 26 | ; RUN: llc -march=mips64 -mcpu=mips64r6 -relocation-model=pic -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=R6C |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 27 | |
| 28 | declare void @extern_void_void() |
| 29 | declare i32 @extern_i32_void() |
| 30 | declare float @extern_float_void() |
| 31 | |
| 32 | define i32 @call_void_void() { |
| 33 | ; ALL-LABEL: call_void_void: |
| 34 | |
| 35 | ; O32: lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) |
| 36 | |
| 37 | ; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) |
| 38 | |
Simon Dardis | d9d41f5 | 2016-04-05 12:50:29 +0000 | [diff] [blame] | 39 | ; NOT-R6C: jalr $[[TGT]] |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 40 | ; R6C: jalrc $[[TGT]] |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 41 | |
| 42 | call void @extern_void_void() |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 43 | ; R6C: jrc $ra |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 44 | ret i32 0 |
| 45 | } |
| 46 | |
| 47 | define i32 @call_i32_void() { |
| 48 | ; ALL-LABEL: call_i32_void: |
| 49 | |
| 50 | ; O32: lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) |
| 51 | |
| 52 | ; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) |
| 53 | |
Simon Dardis | d9d41f5 | 2016-04-05 12:50:29 +0000 | [diff] [blame] | 54 | ; NOT-R6C: jalr $[[TGT]] |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 55 | ; R6C: jalrc $[[TGT]] |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 56 | |
| 57 | %1 = call i32 @extern_i32_void() |
| 58 | %2 = add i32 %1, 1 |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 59 | ; R6C: jrc $ra |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 60 | ret i32 %2 |
| 61 | } |
| 62 | |
| 63 | define float @call_float_void() { |
| 64 | ; ALL-LABEL: call_float_void: |
| 65 | |
| 66 | ; FIXME: Not sure why we don't use $gp directly on such a simple test. We should |
| 67 | ; look into it at some point. |
| 68 | ; O32: addu $[[GP:[0-9]+]], ${{[0-9]+}}, $25 |
| 69 | ; O32: lw $[[TGT:[0-9]+]], %call16(extern_float_void)($[[GP]]) |
| 70 | |
| 71 | ; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp) |
| 72 | |
Simon Dardis | d9d41f5 | 2016-04-05 12:50:29 +0000 | [diff] [blame] | 73 | ; NOT-R6C: jalr $[[TGT]] |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 74 | ; R6C: jalrc $[[TGT]] |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 75 | |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 76 | |
| 77 | %1 = call float @extern_float_void() |
| 78 | %2 = fadd float %1, 1.0 |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 79 | ; R6C: jrc $ra |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 80 | ret float %2 |
| 81 | } |
| 82 | |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 83 | define i32 @indirect_call_void_void(void ()* %addr) { |
| 84 | ; ALL-LABEL: indirect_call_void_void: |
| 85 | |
| 86 | ; ALL: move $25, $4 |
Simon Dardis | d9d41f5 | 2016-04-05 12:50:29 +0000 | [diff] [blame] | 87 | ; NOT-R6C: jalr $25 |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 88 | ; R6C: jalrc $25 |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 89 | |
| 90 | call void %addr() |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 91 | ; R6C: jrc $ra |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 92 | ret i32 0 |
| 93 | } |
| 94 | |
| 95 | define i32 @indirect_call_i32_void(i32 ()* %addr) { |
| 96 | ; ALL-LABEL: indirect_call_i32_void: |
| 97 | |
| 98 | ; ALL: move $25, $4 |
Simon Dardis | d9d41f5 | 2016-04-05 12:50:29 +0000 | [diff] [blame] | 99 | ; NOT-R6C: jalr $25 |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 100 | ; R6C: jalrc $25 |
Simon Dardis | d9d41f5 | 2016-04-05 12:50:29 +0000 | [diff] [blame] | 101 | |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 102 | |
| 103 | %1 = call i32 %addr() |
| 104 | %2 = add i32 %1, 1 |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 105 | ; R6C: jrc $ra |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 106 | ret i32 %2 |
| 107 | } |
| 108 | |
| 109 | define float @indirect_call_float_void(float ()* %addr) { |
| 110 | ; ALL-LABEL: indirect_call_float_void: |
| 111 | |
| 112 | ; ALL: move $25, $4 |
Simon Dardis | d9d41f5 | 2016-04-05 12:50:29 +0000 | [diff] [blame] | 113 | ; NOT-R6C: jalr $25 |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 114 | ; R6C: jalrc $25 |
Simon Dardis | d9d41f5 | 2016-04-05 12:50:29 +0000 | [diff] [blame] | 115 | |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 116 | |
| 117 | %1 = call float %addr() |
| 118 | %2 = fadd float %1, 1.0 |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 119 | ; R6C: jrc $ra |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 120 | ret float %2 |
| 121 | } |
| 122 | |
| 123 | ; We can't use 'musttail' here because the verifier is too conservative and |
| 124 | ; prohibits any prototype difference. |
| 125 | define void @tail_indirect_call_void_void(void ()* %addr) { |
| 126 | ; ALL-LABEL: tail_indirect_call_void_void: |
| 127 | |
| 128 | ; ALL: move $25, $4 |
Simon Dardis | 57f4ae4 | 2016-08-04 09:17:07 +0000 | [diff] [blame] | 129 | ; NOT-R6C: jr $[[TGT]] |
| 130 | ; R6C: jrc $[[TGT]] |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 131 | |
| 132 | tail call void %addr() |
| 133 | ret void |
| 134 | } |
| 135 | |
| 136 | define i32 @tail_indirect_call_i32_void(i32 ()* %addr) { |
| 137 | ; ALL-LABEL: tail_indirect_call_i32_void: |
| 138 | |
| 139 | ; ALL: move $25, $4 |
Simon Dardis | 57f4ae4 | 2016-08-04 09:17:07 +0000 | [diff] [blame] | 140 | ; NOT-R6C: jr $[[TGT]] |
| 141 | ; R6C: jrc $[[TGT]] |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 142 | |
| 143 | %1 = tail call i32 %addr() |
| 144 | ret i32 %1 |
| 145 | } |
| 146 | |
| 147 | define float @tail_indirect_call_float_void(float ()* %addr) { |
| 148 | ; ALL-LABEL: tail_indirect_call_float_void: |
| 149 | |
| 150 | ; ALL: move $25, $4 |
Simon Dardis | 57f4ae4 | 2016-08-04 09:17:07 +0000 | [diff] [blame] | 151 | ; NOT-R6C: jr $[[TGT]] |
| 152 | ; R6C: jrc $[[TGT]] |
Daniel Sanders | 20c82ee4 | 2014-07-04 15:16:14 +0000 | [diff] [blame] | 153 | |
| 154 | %1 = tail call float %addr() |
| 155 | ret float %1 |
| 156 | } |
Daniel Sanders | 2fb8564 | 2015-10-12 13:55:44 +0000 | [diff] [blame] | 157 | |
| 158 | ; Check that passing undef as a double value doesn't cause machine code errors |
| 159 | ; for FP64. |
| 160 | declare hidden void @undef_double(i32 %this, double %volume) unnamed_addr align 2 |
| 161 | |
| 162 | define hidden void @thunk_undef_double(i32 %this, double %volume) unnamed_addr align 2 { |
| 163 | ; ALL-LABEL: thunk_undef_double: |
Puyan Lotfi | 43e94b1 | 2018-01-31 22:04:26 +0000 | [diff] [blame] | 164 | ; O32: # implicit-def: $a2 |
| 165 | ; O32: # implicit-def: $a3 |
Simon Dardis | 57f4ae4 | 2016-08-04 09:17:07 +0000 | [diff] [blame] | 166 | ; NOT-R6C: jr $[[TGT]] |
| 167 | ; R6C: jrc $[[TGT]] |
Simon Dardis | d9d41f5 | 2016-04-05 12:50:29 +0000 | [diff] [blame] | 168 | |
Daniel Sanders | 2fb8564 | 2015-10-12 13:55:44 +0000 | [diff] [blame] | 169 | tail call void @undef_double(i32 undef, double undef) #8 |
| 170 | ret void |
| 171 | } |
Daniel Sanders | 4d32300 | 2016-01-11 15:57:46 +0000 | [diff] [blame] | 172 | |
| 173 | ; Check that immediate addresses do not use jal. |
| 174 | define i32 @jal_only_allows_symbols() { |
| 175 | ; ALL-LABEL: jal_only_allows_symbols: |
| 176 | |
| 177 | ; ALL-NOT: {{jal }} |
| 178 | ; ALL: addiu $[[TGT:[0-9]+]], $zero, 1234 |
| 179 | ; ALL-NOT: {{jal }} |
Simon Dardis | d9d41f5 | 2016-04-05 12:50:29 +0000 | [diff] [blame] | 180 | ; NOT-R6C: jalr $[[TGT]] |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 181 | ; R6C: jalrc $[[TGT]] |
Daniel Sanders | 4d32300 | 2016-01-11 15:57:46 +0000 | [diff] [blame] | 182 | ; ALL-NOT: {{jal }} |
| 183 | |
| 184 | call void () inttoptr (i32 1234 to void ()*)() |
Simon Dardis | 53a3492 | 2016-04-14 13:43:17 +0000 | [diff] [blame] | 185 | ; R6C: jrc $ra |
Daniel Sanders | 4d32300 | 2016-01-11 15:57:46 +0000 | [diff] [blame] | 186 | ret i32 0 |
| 187 | } |
| 188 | |