Stackmap shadows should consider call returns a branch target.
[oota-llvm.git] / test / CodeGen / Mips / fpxx.ll
1 ; RUN: llc -march=mipsel -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-NOFPXX
2 ; RUN: llc -march=mipsel -mcpu=mips32 -mattr=fpxx < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-FPXX
3
4 ; RUN: llc -march=mipsel -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32R2-NOFPXX
5 ; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=fpxx < %s | FileCheck %s -check-prefix=ALL -check-prefix=32R2-FPXX
6
7 ; RUN: llc -march=mips64 -mcpu=mips4 < %s | FileCheck %s -check-prefix=ALL -check-prefix=4-NOFPXX
8 ; RUN: not llc -march=mips64 -mcpu=mips4 -mattr=fpxx < %s 2>&1 | FileCheck %s -check-prefix=4-FPXX
9
10 ; RUN: llc -march=mips64 -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-NOFPXX
11 ; RUN: not llc -march=mips64 -mcpu=mips64 -mattr=fpxx < %s 2>&1 | FileCheck %s -check-prefix=64-FPXX
12
13 ; RUN-TODO: llc -march=mips64 -mcpu=mips4 -mattr=-n64,+o32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=4-O32-NOFPXX
14 ; RUN-TODO: llc -march=mips64 -mcpu=mips4 -mattr=-n64,+o32 -mattr=fpxx < %s | FileCheck %s -check-prefix=ALL -check-prefix=4-O32-FPXX
15
16 ; RUN-TODO: llc -march=mips64 -mcpu=mips64 -mattr=-n64,+o32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-O32-NOFPXX
17 ; RUN-TODO: llc -march=mips64 -mcpu=mips64 -mattr=-n64,+o32 -mattr=fpxx < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-O32-FPXX
18
19 declare double @dbl();
20
21 ; 4-FPXX:  LLVM ERROR: FPXX is not permitted for the N32/N64 ABI's.
22 ; 64-FPXX: LLVM ERROR: FPXX is not permitted for the N32/N64 ABI's.
23
24 define double @test1(double %d, ...) {
25   ret double %d
26
27 ; ALL-LABEL: test1:
28
29 ; 32-NOFPXX:     mtc1    $4, $f0
30 ; 32-NOFPXX:     mtc1    $5, $f1
31
32 ; 32-FPXX:       addiu   $sp, $sp, -8
33 ; 32-FPXX:       sw      $4, 0($sp)
34 ; 32-FPXX:       sw      $5, 4($sp)
35 ; 32-FPXX:       ldc1    $f0, 0($sp)
36
37 ; 32R2-NOFPXX:   mtc1    $4, $f0
38 ; 32R2-NOFPXX:   mthc1   $5, $f0
39
40 ; 32R2-FPXX:     mtc1    $4, $f0
41 ; 32R2-FPXX:     mthc1   $5, $f0
42
43 ; floats/doubles are not passed in integer registers for n64, so dmtc1 is not used.
44 ; 4-NOFPXX:      mov.d   $f0, $f12
45
46 ; 64-NOFPXX:     mov.d   $f0, $f12
47 }
48
49 define double @test2(i32 %i, double %d) {
50   ret double %d
51
52 ; ALL-LABEL: test2:
53
54 ; 32-NOFPXX:     mtc1    $6, $f0
55 ; 32-NOFPXX:     mtc1    $7, $f1
56
57 ; 32-FPXX:       addiu   $sp, $sp, -8
58 ; 32-FPXX:       sw      $6, 0($sp)
59 ; 32-FPXX:       sw      $7, 4($sp)
60 ; 32-FPXX:       ldc1    $f0, 0($sp)
61
62 ; 32R2-NOFPXX:   mtc1    $6, $f0
63 ; 32R2-NOFPXX:   mthc1   $7, $f0
64
65 ; 32R2-FPXX:     mtc1    $6, $f0
66 ; 32R2-FPXX:     mthc1   $7, $f0
67
68 ; 4-NOFPXX:      mov.d   $f0, $f13
69
70 ; 64-NOFPXX:     mov.d   $f0, $f13
71 }
72
73 define double @test3(float %f1, float %f2, double %d) {
74   ret double %d
75
76 ; ALL-LABEL: test3:
77
78 ; 32-NOFPXX:     mtc1    $6, $f0
79 ; 32-NOFPXX:     mtc1    $7, $f1
80
81 ; 32-FPXX:       addiu   $sp, $sp, -8
82 ; 32-FPXX:       sw      $6, 0($sp)
83 ; 32-FPXX:       sw      $7, 4($sp)
84 ; 32-FPXX:       ldc1    $f0, 0($sp)
85
86 ; 32R2-NOFPXX:   mtc1    $6, $f0
87 ; 32R2-NOFPXX:   mthc1   $7, $f0
88
89 ; 32R2-FPXX:     mtc1    $6, $f0
90 ; 32R2-FPXX:     mthc1   $7, $f0
91
92 ; 4-NOFPXX:      mov.d   $f0, $f14
93
94 ; 64-NOFPXX:     mov.d   $f0, $f14
95 }
96
97 define double @test4(float %f, double %d, ...) {
98   ret double %d
99
100 ; ALL-LABEL: test4:
101
102 ; 32-NOFPXX:     mtc1    $6, $f0
103 ; 32-NOFPXX:     mtc1    $7, $f1
104
105 ; 32-FPXX:       addiu   $sp, $sp, -8
106 ; 32-FPXX:       sw      $6, 0($sp)
107 ; 32-FPXX:       sw      $7, 4($sp)
108 ; 32-FPXX:       ldc1    $f0, 0($sp)
109
110 ; 32R2-NOFPXX:   mtc1    $6, $f0
111 ; 32R2-NOFPXX:   mthc1   $7, $f0
112
113 ; 32R2-FPXX:     mtc1    $6, $f0
114 ; 32R2-FPXX:     mthc1   $7, $f0
115
116 ; 4-NOFPXX:      mov.d   $f0, $f13
117
118 ; 64-NOFPXX:     mov.d   $f0, $f13
119 }
120
121 define double @test5() {
122   ret double 0.000000e+00
123
124 ; ALL-LABEL: test5:
125
126 ; 32-NOFPXX:     mtc1    $zero, $f0
127 ; 32-NOFPXX:     mtc1    $zero, $f1
128
129 ; 32-FPXX:       addiu   $sp, $sp, -8
130 ; 32-FPXX:       sw      $zero, 0($sp)
131 ; 32-FPXX:       sw      $zero, 4($sp)
132 ; 32-FPXX:       ldc1    $f0, 0($sp)
133
134 ; 32R2-NOFPXX:   mtc1    $zero, $f0
135 ; 32R2-NOFPXX:   mthc1   $zero, $f0
136
137 ; 32R2-FPXX:     mtc1    $zero, $f0
138 ; 32R2-FPXX:     mthc1   $zero, $f0
139
140 ; 4-NOFPXX:      dmtc1 $zero, $f0
141
142 ; 64-NOFPXX:     dmtc1 $zero, $f0
143 }
144
145 define double @test6(double %a, double %b, ...) {
146   %1 = fsub double %a, %b
147   ret double %1
148
149 ; ALL-LABEL:     test6:
150
151 ; 32-NOFPXX-DAG:     mtc1    $4, $[[T0:f[0-9]+]]
152 ; 32-NOFPXX-DAG:     mtc1    $5, ${{f[0-9]*[13579]}}
153 ; 32-NOFPXX-DAG:     mtc1    $6, $[[T1:f[0-9]+]]
154 ; 32-NOFPXX-DAG:     mtc1    $7, ${{f[0-9]*[13579]}}
155 ; 32-NOFPXX:         sub.d   $f0, $[[T0]], $[[T1]]
156
157 ; 32-FPXX:           addiu   $sp, $sp, -8
158 ; 32-FPXX:           sw      $6, 0($sp)
159 ; 32-FPXX:           sw      $7, 4($sp)
160 ; 32-FPXX:           ldc1    $[[T1:f[0-9]+]], 0($sp)
161 ; 32-FPXX:           sw      $4, 0($sp)
162 ; 32-FPXX:           sw      $5, 4($sp)
163 ; 32-FPXX:           ldc1    $[[T0:f[0-9]+]], 0($sp)
164 ; 32-FPXX:           sub.d   $f0, $[[T0]], $[[T1]]
165
166 ; 32R2-NOFPXX-DAG:   mtc1    $4, $[[T0:f[0-9]+]]
167 ; 32R2-NOFPXX-DAG:   mthc1   $5, $[[T0]]
168 ; 32R2-NOFPXX-DAG:   mtc1    $6, $[[T1:f[0-9]+]]
169 ; 32R2-NOFPXX-DAG:   mthc1   $7, $[[T1]]
170 ; 32R2-NOFPXX:       sub.d   $f0, $[[T0]], $[[T1]]
171
172 ; 32R2-FPXX-DAG:     mtc1    $4, $[[T0:f[0-9]+]]
173 ; 32R2-FPXX-DAG:     mthc1   $5, $[[T0]]
174 ; 32R2-FPXX-DAG:     mtc1    $6, $[[T1:f[0-9]+]]
175 ; 32R2-FPXX-DAG:     mthc1   $7, $[[T1]]
176 ; 32R2-FPXX:         sub.d   $f0, $[[T0]], $[[T1]]
177
178 ; floats/doubles are not passed in integer registers for n64, so dmtc1 is not used.
179 ; 4-NOFPXX:          sub.d   $f0, $f12, $f13
180
181 ; floats/doubles are not passed in integer registers for n64, so dmtc1 is not used.
182 ; 64-NOFPXX:         sub.d   $f0, $f12, $f13
183 }
184
185 define double @move_from1(double %d) {
186   %1 = call double @dbl()
187   %2 = call double @test2(i32 0, double %1)
188   ret double %2
189
190 ; ALL-LABEL:   move_from1:
191
192 ; 32-NOFPXX-DAG:   mfc1    $6, $f0
193 ; 32-NOFPXX-DAG:   mfc1    $7, $f1
194
195 ; 32-FPXX:         addiu   $sp, $sp, -32
196 ; 32-FPXX:         sdc1    $f0, 16($sp)
197 ; 32-FPXX:         lw      $6, 16($sp)
198 ; FIXME: This store is redundant
199 ; 32-FPXX:         sdc1    $f0, 16($sp)
200 ; 32-FPXX:         lw      $7, 20($sp)
201
202 ; 32R2-NOFPXX-DAG: mfc1    $6, $f0
203 ; 32R2-NOFPXX-DAG: mfhc1   $7, $f0
204
205 ; 32R2-FPXX-DAG:   mfc1    $6, $f0
206 ; 32R2-FPXX-DAG:   mfhc1   $7, $f0
207
208 ; floats/doubles are not passed in integer registers for n64, so dmfc1 is not used.
209 ; We can't use inline assembly to force a copy either because trying to force
210 ; a copy to a GPR this way fails with ; "couldn't allocate input reg for
211 ; constraint 'r'". It therefore seems impossible to test the generation of dmfc1
212 ; in a simple test.
213 ; 4-NOFPXX:        mov.d   $f13, $f0
214
215 ; floats/doubles are not passed in integer registers for n64, so dmfc1 is not used.
216 ; We can't use inline assembly to force a copy either because trying to force
217 ; a copy to a GPR this way fails with ; "couldn't allocate input reg for
218 ; constraint 'r'". It therefore seems impossible to test the generation of dmfc1
219 ; in a simple test.
220 ; 64-NOFPXX:       mov.d   $f13, $f0
221 }