[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / PowerPC / ppc64-i128-abi.ll
blob2593fa4c00039ea66ce0b4f399937c45bcb922b4
1 ; RUN: llc -relocation-model=pic -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
2 ; RUN:   -mcpu=pwr8 < %s | FileCheck %s -check-prefix=CHECK-LE \
3 ; RUN:   --implicit-check-not xxswapd
5 ; RUN: llc -relocation-model=pic -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
6 ; RUN:   -mcpu=pwr8 < %s | FileCheck %s -check-prefix=CHECK-BE
8 ; RUN: llc -relocation-model=pic -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
9 ; RUN:   -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-NOVSX
11 ; RUN: llc -relocation-model=pic -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
12 ; RUN:   -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-NOVSX \
13 ; RUN:   --implicit-check-not xxswapd
15 ; RUN: llc -relocation-model=pic -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
16 ; RUN:   -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-BE-NOVSX
18 ; RUN: llc -relocation-model=pic -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
19 ; RUN:   -mcpu=pwr8 -mattr=-vsx < %s | \
20 ; RUN:   FileCheck %s -check-prefix=CHECK-LE-NOVSX --implicit-check-not xxswapd
22 ; RUN: llc -relocation-model=pic -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
23 ; RUN:   -mcpu=pwr9 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
24 ; RUN:   FileCheck %s -check-prefix=CHECK-P9 --implicit-check-not xxswapd
26 ; RUN: llc -relocation-model=pic -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
27 ; RUN:   -mcpu=pwr9 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-NOVSX \
28 ; RUN:   --implicit-check-not xxswapd
30 ; RUN: llc -relocation-model=pic -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
31 ; RUN:   -mcpu=pwr9 -mattr=-power9-vector -mattr=-direct-move < %s | \
32 ; RUN:   FileCheck %s -check-prefix=CHECK-LE --implicit-check-not xxswapd
34 @x = common global <1 x i128> zeroinitializer, align 16
35 @y = common global <1 x i128> zeroinitializer, align 16
36 @a = common global i128 zeroinitializer, align 16
37 @b = common global i128 zeroinitializer, align 16
39 ; VSX:
40 ;   %a is passed in register 34
41 ;   The value of 1 is stored in the TOC.
42 ;   On LE, ensure the value of 1 is swapped before being used (using xxswapd).
43 ; VMX (no VSX): 
44 ;   %a is passed in register 2
45 ;   The value of 1 is stored in the TOC.
46 ;   No swaps are necessary when using P8 Vector instructions on LE
47 define <1 x i128> @v1i128_increment_by_one(<1 x i128> %a) nounwind {
48        %tmp = add <1 x i128> %a, <i128 1>
49        ret <1 x i128> %tmp  
51 ; FIXME: Seems a 128-bit literal is materialized by loading from the TOC. There
52 ;        should be a better way of doing this.
54 ; CHECK-LE-LABEL: @v1i128_increment_by_one
55 ; CHECK-LE: lxvd2x [[VAL:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
56 ; CHECK-LE: xxswapd 35, [[VAL]]
57 ; CHECK-LE: vadduqm 2, 2, 3
58 ; CHECK-LE: blr
60 ; CHECK-P9-LABEL: @v1i128_increment_by_one
61 ; The below FIXME is due to the lowering for BUILD_VECTOR that will be fixed
62 ; in a subsequent patch.
63 ; FIXME: li [[R1:r[0-9]+]], 1
64 ; FIXME: li [[R2:r[0-9]+]], 0
65 ; FIXME: mtvsrdd [[V1:v[0-9]+]], [[R2]], [[R1]]
66 ; CHECK-P9: lxvx [[V1:v[0-9]+]]
67 ; CHECK-P9: vadduqm v2, v2, [[V1]]
68 ; CHECK-P9: blr
70 ; CHECK-BE-LABEL: @v1i128_increment_by_one
71 ; CHECK-BE: lxvd2x 35, {{[0-9]+}}, {{[0-9]+}}
72 ; CHECK-BE-NOT: xxswapd 
73 ; CHECK-BE: vadduqm 2, 2, 3 
74 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
75 ; CHECK-BE: blr
77 ; CHECK-NOVSX-LABEL: @v1i128_increment_by_one
78 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
79 ; CHECK-NOVSX-NOT: stxvd2x {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
80 ; CHECK-NOVSX: lvx [[VAL:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
81 ; CHECK-NOVSX-NOT: lxvd2x {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
82 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
83 ; CHECK-NOVSX: vadduqm 2, 2, [[VAL]]
84 ; CHECK-NOVSX: blr
87 ; VSX:
88 ;   %a is passed in register 34
89 ;   %b is passed in register 35
90 ;   No swaps are necessary when using P8 Vector instructions on LE
91 ; VMX (no VSX):
92 ;   %a is passewd in register 2
93 ;   %b is passed in register 3
94 ;   On LE, do not need to swap contents of 2 and 3 because the lvx/stvx 
95 ;   instructions no not swap elements
96 define <1 x i128> @v1i128_increment_by_val(<1 x i128> %a, <1 x i128> %b) nounwind {
97        %tmp = add <1 x i128> %a, %b
98        ret <1 x i128> %tmp
100 ; CHECK-LE-LABEL: @v1i128_increment_by_val
101 ; CHECK-LE-NOT: xxswapd
102 ; CHECK-LE: adduqm 2, 2, 3
103 ; CHECK-LE: blr
105 ; CHECK-BE-LABEL: @v1i128_increment_by_val
106 ; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 34
107 ; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 35
108 ; CHECK-BE-NOT: xxswapd 34, [[RESULT]]
109 ; CHECK-BE: adduqm 2, 2, 3
110 ; CHECK-BE: blr
112 ; CHECK-NOVSX-LABEL: @v1i128_increment_by_val
113 ; CHECK-NOVSX-NOT: xxswapd 34, [[RESULT]]
114 ; CHECK-NOVSX: adduqm 2, 2, 3
115 ; CHECK-NOVSX: blr
118 ; Little Endian (VSX and VMX):
119 ;   Lower 64-bits of %a are passed in register 3
120 ;   Upper 64-bits of %a are passed in register 4
121 ;   Increment lower 64-bits using addic (immediate value of 1)
122 ;   Increment upper 64-bits using add zero extended
123 ;   Results are placed in registers 3 and 4
124 ; Big Endian (VSX and VMX)
125 ;   Lower 64-bits of %a are passed in register 4
126 ;   Upper 64-bits of %a are passed in register 3
127 ;   Increment lower 64-bits using addic (immediate value of 1)
128 ;   Increment upper 64-bits using add zero extended
129 ;   Results are placed in registers 3 and 4
130 define i128 @i128_increment_by_one(i128 %a) nounwind {
131        %tmp =  add i128 %a,  1
132        ret i128 %tmp
133 ; CHECK-LE-LABEL: @i128_increment_by_one
134 ; CHECK-LE: addic 3, 3, 1
135 ; CHECK-LE-NEXT: addze 4, 4
136 ; CHECK-LE: blr
138 ; CHECK-BE-LABEL: @i128_increment_by_one
139 ; CHECK-BE: addic 4, 4, 1
140 ; CHECK-BE-NEXT: addze 3, 3
141 ; CHECK-BE: blr
143 ; CHECK-LE-NOVSX-LABEL: @i128_increment_by_one
144 ; CHECK-LE-NOVSX: addic 3, 3, 1
145 ; CHECK-LE-NOVSX-NEXT: addze 4, 4
146 ; CHECK-LE-NOVSX: blr
148 ; CHECK-BE-NOVSX-LABEL: @i128_increment_by_one
149 ; CHECK-BE-NOVSX: addic 4, 4, 1
150 ; CHECK-BE-NOVSX-NEXT: addze 3, 3
151 ; CHECK-BE-NOVSX: blr
154 ; Little Endian (VSX and VMX):
155 ;   Lower 64-bits of %a are passed in register 3
156 ;   Upper 64-bits of %a are passed in register 4
157 ;   Lower 64-bits of %b are passed in register 5
158 ;   Upper 64-bits of %b are passed in register 6
159 ;   Add the lower 64-bits using addc on registers 3 and 5
160 ;   Add the upper 64-bits using adde on registers 4 and 6
161 ;   Registers 3 and 4 should hold the result
162 ; Big Endian (VSX and VMX):
163 ;   Upper 64-bits of %a are passed in register 3
164 ;   Lower 64-bits of %a are passed in register 4
165 ;   Upper 64-bits of %b are passed in register 5
166 ;   Lower 64-bits of %b are passed in register 6
167 ;   Add the lower 64-bits using addc on registers 4 and 6
168 ;   Add the upper 64-bits using adde on registers 3 and 5
169 ;   Registers 3 and 4 should hold the result
170 define i128 @i128_increment_by_val(i128 %a, i128 %b) nounwind {
171        %tmp =  add i128 %a, %b
172        ret i128 %tmp
173 ; CHECK-LE-LABEL: @i128_increment_by_val
174 ; CHECK-LE: addc 3, 3, 5
175 ; CHECK-LE-NEXT: adde 4, 4, 6
176 ; CHECK-LE: blr
178 ; CHECK-BE-LABEL: @i128_increment_by_val
179 ; CHECK-BE: addc 4, 4, 6
180 ; CHECK-BE-NEXT: adde 3, 3, 5
181 ; CHECK-BE: blr
183 ; CHECK-LE-NOVSX-LABEL: @i128_increment_by_val
184 ; CHECK-LE-NOVSX: addc 3, 3, 5
185 ; CHECK-LE-NOVSX-NEXT: adde 4, 4, 6
186 ; CHECK-LE-NOVSX: blr
188 ; CHECK-BE-NOVSX-LABEL: @i128_increment_by_val
189 ; CHECK-BE-NOVSX: addc 4, 4, 6
190 ; CHECK-BE-NOVSX-NEXT: adde 3, 3, 5
191 ; CHECK-BE-NOVSX: blr
195 ; Callsites for the routines defined above. 
196 ; Ensure the parameters are loaded in the same order that is expected by the 
197 ; callee. See comments for individual functions above for details on registers
198 ; used for parameters.
199 define <1 x i128> @call_v1i128_increment_by_one() nounwind {
200        %tmp = load <1 x i128>, <1 x i128>* @x, align 16
201        %ret = call <1 x i128> @v1i128_increment_by_one(<1 x i128> %tmp)
202        ret <1 x i128> %ret
204 ; CHECK-LE-LABEL: @call_v1i128_increment_by_one
205 ; CHECK-LE: lvx 2, {{[0-9]+}}, {{[0-9]+}}
206 ; CHECK-LE: bl v1i128_increment_by_one
207 ; CHECK-LE: blr
209 ; CHECK-P9-LABEL: @call_v1i128_increment_by_one
210 ; CHECK-P9: lxv
211 ; CHECK-P9: bl v1i128_increment_by_one
212 ; CHECK-P9: blr
214 ; CHECK-BE-LABEL: @call_v1i128_increment_by_one
215 ; CHECK-BE: lxvw4x 34, {{[0-9]+}}, {{[0-9]+}}
216 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
217 ; CHECK-BE: bl v1i128_increment_by_one
218 ; CHECK-BE: blr
220 ; CHECK-NOVSX-LABEL: @call_v1i128_increment_by_one
221 ; CHECK-NOVSX: lvx 2, {{[0-9]+}}, {{[0-9]+}}
222 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
223 ; CHECK-NOVSX: bl v1i128_increment_by_one
224 ; CHECK-NOVSX: blr
227 define <1 x i128> @call_v1i128_increment_by_val() nounwind {
228        %tmp = load <1 x i128>, <1 x i128>* @x, align 16
229        %tmp2 = load <1 x i128>, <1 x i128>* @y, align 16
230        %ret = call <1 x i128> @v1i128_increment_by_val(<1 x i128> %tmp, <1 x i128> %tmp2)
231        ret <1 x i128> %ret
233 ; CHECK-LE-LABEL: @call_v1i128_increment_by_val
234 ; CHECK-LE: lvx 2, {{[0-9]+}}, {{[0-9]+}}
235 ; CHECK-LE: lvx 3, {{[0-9]+}}, {{[0-9]+}}
236 ; CHECK-LE: bl v1i128_increment_by_val
237 ; CHECK-LE: blr
239 ; CHECK-P9-LABEL: @call_v1i128_increment_by_val
240 ; CHECK-P9-DAG: lxvx v2
241 ; CHECK-P9-DAG: lxvx v3
242 ; CHECK-P9: bl v1i128_increment_by_val
243 ; CHECK-P9: blr
245 ; CHECK-BE-LABEL: @call_v1i128_increment_by_val
248 ; CHECK-BE-DAG: lxvw4x 35, {{[0-9]+}}, {{[0-9]+}}
249 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
250 ; CHECK-BE-NOT: xxswapd 35, {{[0-9]+}}
251 ; CHECK-BE: bl v1i128_increment_by_val
252 ; CHECK-BE: blr
254 ; CHECK-NOVSX-LABEL: @call_v1i128_increment_by_val
255 ; CHECK-NOVSX-DAG: lvx 2, {{[0-9]+}}, {{[0-9]+}}
256 ; CHECK-NOVSX-DAG: lvx 3, {{[0-9]+}}, {{[0-9]+}}
257 ; CHECK-NOVSX-NOT: xxswapd 34, {{[0-9]+}}
258 ; CHECK-NOVSX-NOT: xxswapd 35, {{[0-9]+}}
259 ; CHECK-NOVSX: bl v1i128_increment_by_val
260 ; CHECK-NOVSX: blr
264 define i128 @call_i128_increment_by_one() nounwind {
265        %tmp = load i128, i128* @a, align 16
266        %ret = call i128 @i128_increment_by_one(i128 %tmp)
267        ret i128 %ret
268 ;       %ret4 = call i128 @i128_increment_by_val(i128 %tmp2, i128 %tmp2)
269 ; CHECK-LE-LABEL: @call_i128_increment_by_one
270 ; CHECK-LE-DAG: ld 3, 0([[BASEREG:[0-9]+]])
271 ; CHECK-LE-DAG: ld 4, 8([[BASEREG]])
272 ; CHECK-LE: bl i128_increment_by_one
273 ; CHECK-LE: blr
275 ; CHECK-BE-LABEL: @call_i128_increment_by_one
276 ; CHECK-BE-DAG: ld 3, 0([[BASEREG:[0-9]+]])
277 ; CHECK-BE-DAG: ld 4, 8([[BASEREG]])
278 ; CHECK-BE: bl i128_increment_by_one
279 ; CHECK-BE: blr
281 ; CHECK-NOVSX-LABEL: @call_i128_increment_by_one
282 ; CHECK-NOVSX-DAG: ld 3, 0([[BASEREG:[0-9]+]])
283 ; CHECK-NOVSX-DAG: ld 4, 8([[BASEREG]])
284 ; CHECK-NOVSX: bl i128_increment_by_one
285 ; CHECK-NOVSX: blr
288 define i128 @call_i128_increment_by_val() nounwind {
289        %tmp = load i128, i128* @a, align 16
290        %tmp2 = load i128, i128* @b, align 16
291        %ret = call i128 @i128_increment_by_val(i128 %tmp, i128 %tmp2)
292        ret i128 %ret
293 ; CHECK-LE-LABEL: @call_i128_increment_by_val
294 ; CHECK-LE-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
295 ; CHECK-LE-DAG: ld 4, 8([[P1BASEREG]])
296 ; CHECK-LE-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
297 ; CHECK-LE-DAG: ld 6, 8([[P2BASEREG]])
298 ; CHECK-LE: bl i128_increment_by_val
299 ; CHECK-LE: blr
301 ; CHECK-BE-LABEL: @call_i128_increment_by_val
302 ; CHECK-BE-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
303 ; CHECK-BE-DAG: ld 4, 8([[P1BASEREG]])
304 ; CHECK-BE-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
305 ; CHECK-BE-DAG: ld 6, 8([[P2BASEREG]])
306 ; CHECK-BE: bl i128_increment_by_val
307 ; CHECK-BE: blr
309 ; CHECK-NOVSX-LABEL: @call_i128_increment_by_val
310 ; CHECK-NOVSX-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
311 ; CHECK-NOVSX-DAG: ld 4, 8([[P1BASEREG]])
312 ; CHECK-NOVSX-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
313 ; CHECK-NOVSX-DAG: ld 6, 8([[P2BASEREG]])
314 ; CHECK-NOVSX: bl i128_increment_by_val
315 ; CHECK-NOVSX: blr