1 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s -check-prefix=CHECK-LE
2 ; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s -check-prefix=CHECK-BE
3 ; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-NOVSX
4 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-NOVSX
5 ; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-BE-NOVSX
6 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s -check-prefix=CHECK-LE-NOVSX
8 @x = common global <1 x i128> zeroinitializer, align 16
9 @y = common global <1 x i128> zeroinitializer, align 16
10 @a = common global i128 zeroinitializer, align 16
11 @b = common global i128 zeroinitializer, align 16
14 ; %a is passed in register 34
15 ; On LE, ensure %a is swapped before being used (using xxswapd)
16 ; Similarly, on LE ensure the results are swapped before being returned in
19 ; %a is passed in register 2
20 ; No swaps are necessary on LE
21 define <1 x i128> @v1i128_increment_by_one(<1 x i128> %a) nounwind {
22 %tmp = add <1 x i128> %a, <i128 1>
25 ; CHECK-LE-LABEL: @v1i128_increment_by_one
26 ; CHECK-LE: xxswapd [[PARAM1:[0-9]+]], 34
27 ; CHECK-LE: stxvd2x [[PARAM1]], {{[0-9]+}}, {{[0-9]+}}
28 ; CHECK-LE: lxvd2x [[RESULT:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
29 ; CHECK-LE: xxswapd 34, [[RESULT]]
32 ; CHECK-BE-LABEL: @v1i128_increment_by_one
33 ; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 34
34 ; CHECK-BE: stxvd2x 34, {{[0-9]+}}, {{[0-9]+}}
35 ; CHECK-BE: lxvd2x 34, {{[0-9]+}}, {{[0-9]+}}
36 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
39 ; CHECK-NOVSX-LABEL: @v1i128_increment_by_one
40 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
41 ; CHECK-NOVSX-NOT: stxvd2x {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
42 ; CHECK-NOVSX: stvx 2, {{[0-9]+}}, {{[0-9]+}}
43 ; CHECK-NOVSX: lvx 2, {{[0-9]+}}, {{[0-9]+}}
44 ; CHECK-NOVSX-NOT: lxvd2x {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
45 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
50 ; %a is passed in register 34
51 ; %b is passed in register 35
52 ; On LE, ensure the contents of 34 and 35 are swapped before being used
53 ; Similarly, on LE ensure the results are swapped before being returned in
56 ; %a is passewd in register 2
57 ; %b is passed in register 3
58 ; On LE, do not need to swap contents of 2 and 3 because the lvx/stvx
59 ; instructions no not swap elements
60 define <1 x i128> @v1i128_increment_by_val(<1 x i128> %a, <1 x i128> %b) nounwind {
61 %tmp = add <1 x i128> %a, %b
64 ; CHECK-LE-LABEL: @v1i128_increment_by_val
65 ; CHECK-LE-DAG: xxswapd [[PARAM1:[0-9]+]], 34
66 ; CHECK-LE-DAG: xxswapd [[PARAM2:[0-9]+]], 35
67 ; CHECK-LE-DAG: stxvd2x [[PARAM1]], {{[0-9]+}}, {{[0-9]+}}
68 ; CHECK-LE-DAG: stxvd2x [[PARAM2]], {{[0-9]+}}, {{[0-9]+}}
69 ; CHECK-LE: lxvd2x [[RESULT:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
70 ; CHECK-LE: xxswapd 34, [[RESULT]]
73 ; CHECK-BE-LABEL: @v1i128_increment_by_val
74 ; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 34
75 ; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 35
76 ; CHECK-BE-DAG: stxvd2x 34, {{[0-9]+}}, {{[0-9]+}}
77 ; CHECK-BE-DAG: stxvd2x 35, {{[0-9]+}}, {{[0-9]+}}
78 ; CHECK-BE: lxvd2x [[RESULT:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
79 ; CHECK-BE-NOT: xxswapd 34, [[RESULT]]
82 ; CHECK-NOVSX-LABEL: @v1i128_increment_by_val
83 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
84 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
85 ; CHECK-NOVSX-DAG: stvx 2, {{[0-9]+}}, {{[0-9]+}}
86 ; CHECK-NOVSX-DAG: stvx 3, {{[0-9]+}}, {{[0-9]+}}
87 ; CHECK-NOVSX: lvx [[RESULT:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
88 ; CHECK-NOVSX-NOT: xxswapd 34, [[RESULT]]
92 ; Little Endian (VSX and VMX):
93 ; Lower 64-bits of %a are passed in register 3
94 ; Upper 64-bits of %a are passed in register 4
95 ; Increment lower 64-bits using addic (immediate value of 1)
96 ; Increment upper 64-bits using add zero extended
97 ; Results are placed in registers 3 and 4
98 ; Big Endian (VSX and VMX)
99 ; Lower 64-bits of %a are passed in register 4
100 ; Upper 64-bits of %a are passed in register 3
101 ; Increment lower 64-bits using addic (immediate value of 1)
102 ; Increment upper 64-bits using add zero extended
103 ; Results are placed in registers 3 and 4
104 define i128 @i128_increment_by_one(i128 %a) nounwind {
105 %tmp = add i128 %a, 1
107 ; CHECK-LE-LABEL: @i128_increment_by_one
108 ; CHECK-LE: addic 3, 3, 1
109 ; CHECK-LE-NEXT: addze 4, 4
112 ; CHECK-BE-LABEL: @i128_increment_by_one
113 ; CHECK-BE: addic 4, 4, 1
114 ; CHECK-BE-NEXT: addze 3, 3
117 ; CHECK-LE-NOVSX-LABEL: @i128_increment_by_one
118 ; CHECK-LE-NOVSX: addic 3, 3, 1
119 ; CHECK-LE-NOVSX-NEXT: addze 4, 4
120 ; CHECK-LE-NOVSX: blr
122 ; CHECK-BE-NOVSX-LABEL: @i128_increment_by_one
123 ; CHECK-BE-NOVSX: addic 4, 4, 1
124 ; CHECK-BE-NOVSX-NEXT: addze 3, 3
125 ; CHECK-BE-NOVSX: blr
128 ; Little Endian (VSX and VMX):
129 ; Lower 64-bits of %a are passed in register 3
130 ; Upper 64-bits of %a are passed in register 4
131 ; Lower 64-bits of %b are passed in register 5
132 ; Upper 64-bits of %b are passed in register 6
133 ; Add the lower 64-bits using addc on registers 3 and 5
134 ; Add the upper 64-bits using adde on registers 4 and 6
135 ; Registers 3 and 4 should hold the result
136 ; Big Endian (VSX and VMX):
137 ; Upper 64-bits of %a are passed in register 3
138 ; Lower 64-bits of %a are passed in register 4
139 ; Upper 64-bits of %b are passed in register 5
140 ; Lower 64-bits of %b are passed in register 6
141 ; Add the lower 64-bits using addc on registers 4 and 6
142 ; Add the upper 64-bits using adde on registers 3 and 5
143 ; Registers 3 and 4 should hold the result
144 define i128 @i128_increment_by_val(i128 %a, i128 %b) nounwind {
145 %tmp = add i128 %a, %b
147 ; CHECK-LE-LABEL: @i128_increment_by_val
148 ; CHECK-LE: addc 3, 3, 5
149 ; CHECK-LE-NEXT: adde 4, 4, 6
152 ; CHECK-BE-LABEL: @i128_increment_by_val
153 ; CHECK-BE: addc 4, 4, 6
154 ; CHECK-BE-NEXT: adde 3, 3, 5
157 ; CHECK-LE-NOVSX-LABEL: @i128_increment_by_val
158 ; CHECK-LE-NOVSX: addc 3, 3, 5
159 ; CHECK-LE-NOVSX-NEXT: adde 4, 4, 6
160 ; CHECK-LE-NOVSX: blr
162 ; CHECK-BE-NOVSX-LABEL: @i128_increment_by_val
163 ; CHECK-BE-NOVSX: addc 4, 4, 6
164 ; CHECK-BE-NOVSX-NEXT: adde 3, 3, 5
165 ; CHECK-BE-NOVSX: blr
169 ; Callsites for the routines defined above.
170 ; Ensure the parameters are loaded in the same order that is expected by the
171 ; callee. See comments for individual functions above for details on registers
172 ; used for parameters.
173 define <1 x i128> @call_v1i128_increment_by_one() nounwind {
174 %tmp = load <1 x i128>, <1 x i128>* @x, align 16
175 %ret = call <1 x i128> @v1i128_increment_by_one(<1 x i128> %tmp)
178 ; CHECK-LE-LABEL: @call_v1i128_increment_by_one
179 ; CHECK-LE: lxvd2x [[PARAM:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
180 ; CHECK-LE: xxswapd 34, [[PARAM]]
181 ; CHECK-LE: bl v1i128_increment_by_one
184 ; CHECK-BE-LABEL: @call_v1i128_increment_by_one
185 ; CHECK-BE: lxvw4x 34, {{[0-9]+}}, {{[0-9]+}}
186 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
187 ; CHECK-BE: bl v1i128_increment_by_one
190 ; CHECK-NOVSX-LABEL: @call_v1i128_increment_by_one
191 ; CHECK-NOVSX: lvx 2, {{[0-9]+}}, {{[0-9]+}}
192 ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}}
193 ; CHECK-NOVSX: bl v1i128_increment_by_one
197 define <1 x i128> @call_v1i128_increment_by_val() nounwind {
198 %tmp = load <1 x i128>, <1 x i128>* @x, align 16
199 %tmp2 = load <1 x i128>, <1 x i128>* @y, align 16
200 %ret = call <1 x i128> @v1i128_increment_by_val(<1 x i128> %tmp, <1 x i128> %tmp2)
203 ; CHECK-LE-LABEL: @call_v1i128_increment_by_val
204 ; CHECK-LE: lxvd2x [[PARAM1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
205 ; CHECK-LE: lxvd2x [[PARAM2:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
206 ; CHECK-LE-DAG: xxswapd 34, [[PARAM1]]
207 ; CHECK-LE-DAG: xxswapd 35, [[PARAM2]]
208 ; CHECK-LE: bl v1i128_increment_by_val
211 ; CHECK-BE-LABEL: @call_v1i128_increment_by_val
214 ; CHECK-BE-DAG: lxvw4x 35, {{[0-9]+}}, {{[0-9]+}}
215 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}}
216 ; CHECK-BE-NOT: xxswapd 35, {{[0-9]+}}
217 ; CHECK-BE: bl v1i128_increment_by_val
220 ; CHECK-NOVSX-LABEL: @call_v1i128_increment_by_val
221 ; CHECK-NOVSX-DAG: lvx 2, {{[0-9]+}}, {{[0-9]+}}
222 ; CHECK-NOVSX-DAG: lvx 3, {{[0-9]+}}, {{[0-9]+}}
223 ; CHECK-NOVSX-NOT: xxswapd 34, {{[0-9]+}}
224 ; CHECK-NOVSX-NOT: xxswapd 35, {{[0-9]+}}
225 ; CHECK-NOVSX: bl v1i128_increment_by_val
230 define i128 @call_i128_increment_by_one() nounwind {
231 %tmp = load i128, i128* @a, align 16
232 %ret = call i128 @i128_increment_by_one(i128 %tmp)
234 ; %ret4 = call i128 @i128_increment_by_val(i128 %tmp2, i128 %tmp2)
235 ; CHECK-LE-LABEL: @call_i128_increment_by_one
236 ; CHECK-LE-DAG: ld 3, 0([[BASEREG:[0-9]+]])
237 ; CHECK-LE-DAG: ld 4, 8([[BASEREG]])
238 ; CHECK-LE: bl i128_increment_by_one
241 ; CHECK-BE-LABEL: @call_i128_increment_by_one
242 ; CHECK-BE-DAG: ld 3, 0([[BASEREG:[0-9]+]])
243 ; CHECK-BE-DAG: ld 4, 8([[BASEREG]])
244 ; CHECK-BE: bl i128_increment_by_one
247 ; CHECK-NOVSX-LABEL: @call_i128_increment_by_one
248 ; CHECK-NOVSX-DAG: ld 3, 0([[BASEREG:[0-9]+]])
249 ; CHECK-NOVSX-DAG: ld 4, 8([[BASEREG]])
250 ; CHECK-NOVSX: bl i128_increment_by_one
254 define i128 @call_i128_increment_by_val() nounwind {
255 %tmp = load i128, i128* @a, align 16
256 %tmp2 = load i128, i128* @b, align 16
257 %ret = call i128 @i128_increment_by_val(i128 %tmp, i128 %tmp2)
259 ; CHECK-LE-LABEL: @call_i128_increment_by_val
260 ; CHECK-LE-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
261 ; CHECK-LE-DAG: ld 4, 8([[P1BASEREG]])
262 ; CHECK-LE-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
263 ; CHECK-LE-DAG: ld 6, 8([[P2BASEREG]])
264 ; CHECK-LE: bl i128_increment_by_val
267 ; CHECK-BE-LABEL: @call_i128_increment_by_val
268 ; CHECK-BE-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
269 ; CHECK-BE-DAG: ld 4, 8([[P1BASEREG]])
270 ; CHECK-BE-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
271 ; CHECK-BE-DAG: ld 6, 8([[P2BASEREG]])
272 ; CHECK-BE: bl i128_increment_by_val
275 ; CHECK-NOVSX-LABEL: @call_i128_increment_by_val
276 ; CHECK-NOVSX-DAG: ld 3, 0([[P1BASEREG:[0-9]+]])
277 ; CHECK-NOVSX-DAG: ld 4, 8([[P1BASEREG]])
278 ; CHECK-NOVSX-DAG: ld 5, 0([[P2BASEREG:[0-9]+]])
279 ; CHECK-NOVSX-DAG: ld 6, 8([[P2BASEREG]])
280 ; CHECK-NOVSX: bl i128_increment_by_val