1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
2 ; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
4 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
5 ; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
7 ; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-linux-gnu \
8 ; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
9 ; RUN: FileCheck %s --check-prefix=CHECK32
11 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
12 ; RUN: -mcpu=pwr11 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
14 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
15 ; RUN: -mcpu=pwr11 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
17 ; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-linux-gnu \
18 ; RUN: -mcpu=pwr11 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
19 ; RUN: FileCheck %s --check-prefix=CHECK32
21 ; These test cases aim to test constant materialization using the pli instruction on Power10 and Power11.
23 define signext i32 @t_16BitsMinRequiring34Bits() {
24 ; CHECK-LABEL: t_16BitsMinRequiring34Bits:
25 ; CHECK: pli r3, 32768
27 ; CHECK32-LABEL: t_16BitsMinRequiring34Bits:
28 ; CHECK32: pli r3, 32768
35 define signext i32 @t_16Bits() {
36 ; CHECK-LABEL: t_16Bits:
37 ; CHECK: pli r3, 62004
39 ; CHECK32-LABEL: t_16Bits:
40 ; CHECK32: pli r3, 62004
47 define signext i32 @t_lt32gt16BitsNonShiftable() {
48 ; CHECK-LABEL: t_lt32gt16BitsNonShiftable:
49 ; CHECK: pli r3, 1193046
51 ; CHECK32-LABEL: t_lt32gt16BitsNonShiftable:
52 ; CHECK32: pli r3, 1193046
59 define signext i32 @t_32Bits() {
60 ; CHECK-LABEL: t_32Bits:
61 ; CHECK: pli r3, -231451016
63 ; CHECK32-LABEL: t_32Bits:
64 ; CHECK32: pli r3, -231451016
71 define i64 @t_34BitsLargestPositive() {
72 ; CHECK-LABEL: t_34BitsLargestPositive:
73 ; CHECK: pli r3, 8589934591
75 ; CHECK32-LABEL: t_34BitsLargestPositive:
77 ; CHECK32-NEXT: li r4, -1
84 define i64 @t_neg34Bits() {
85 ; CHECK-LABEL: t_neg34Bits:
86 ; CHECK: pli r3, -8284514696
88 ; CHECK32-LABEL: t_neg34Bits:
90 ; CHECK32-NEXT: pli r4, 305419896
97 define signext i32 @t_16BitsMinRequiring34BitsMinusOne() {
98 ; CHECK-LABEL: t_16BitsMinRequiring34BitsMinusOne:
101 ; CHECK32-LABEL: t_16BitsMinRequiring34BitsMinusOne:
102 ; CHECK32: li r3, 32767
109 define signext i32 @t_lt16Bits() {
110 ; CHECK-LABEL: t_lt16Bits:
113 ; CHECK32-LABEL: t_lt16Bits:
114 ; CHECK32: li r3, 291
121 define signext i32 @t_neglt16Bits() {
122 ; CHECK-LABEL: t_neglt16Bits:
123 ; CHECK: li r3, -3805
125 ; CHECK32-LABEL: t_neglt16Bits:
126 ; CHECK32: li r3, -3805
133 define signext i32 @t_neg16Bits() {
134 ; CHECK-LABEL: t_neg16Bits:
135 ; CHECK: li r3, -32204
137 ; CHECK32-LABEL: t_neg16Bits:
138 ; CHECK32: li r3, -32204
145 define signext i32 @t_lt32gt16BitsShiftable() {
146 ; CHECK-LABEL: t_lt32gt16BitsShiftable:
149 ; CHECK32-LABEL: t_lt32gt16BitsShiftable:
150 ; CHECK32: lis r3, 18
157 define signext i32 @t_32gt16BitsShiftable() {
158 ; CHECK-LABEL: t_32gt16BitsShiftable:
159 ; CHECK: lis r3, -3532
161 ; CHECK32-LABEL: t_32gt16BitsShiftable:
162 ; CHECK32: lis r3, -3532
169 define signext i32 @t_32BitsZero() {
170 ; CHECK-LABEL: t_32BitsZero:
173 ; CHECK32-LABEL: t_32BitsZero:
181 define signext i32 @t_32BitsAllOnes() {
182 ; CHECK-LABEL: t_32BitsAllOnes:
185 ; CHECK32-LABEL: t_32BitsAllOnes:
193 define i64 @t_34BitsLargestPositivePlus() {
194 ; CHECK-LABEL: t_34BitsLargestPositivePlus:
196 ; CHECK-NEXT: rldic r3, r3, 33, 30
198 ; CHECK32-LABEL: t_34BitsLargestPositivePlus:
200 ; CHECK32-NEXT: li r4, 0
207 define i64 @t_34Bits() {
208 ; CHECK-LABEL: t_34Bits:
209 ; CHECK: pli r3, 1648790223
210 ; CHECK-NEXT: rldic r3, r3, 3, 30
212 ; CHECK32-LABEL: t_34Bits:
214 ; CHECK32-NEXT: pli r4, 305419896
221 define i64 @t_35Bits() {
222 ; CHECK-LABEL: t_35Bits:
223 ; CHECK: pli r3, 4266035919
224 ; CHECK-NEXT: rldic r3, r3, 3, 29
226 ; CHECK32-LABEL: t_35Bits:
228 ; CHECK32-NEXT: pli r4, -231451016
235 ; (Value >> Shift) can be expressed in 34 bits
236 define i64 @t_Shift() {
237 ; CHECK-LABEL: t_Shift:
238 ; CHECK: pli r3, 8522759166
239 ; CHECK-NEXT: rotldi r3, r3, 48
244 ret i64 18157950747604548606
247 ; Leading Zeros + Following Ones + Trailing Zeros > 30
248 define i64 @t_LZFOTZ() {
249 ; CHECK-LABEL: t_LZFOTZ:
250 ; CHECK: pli r3, -349233
251 ; CHECK-NEXT: rldic r3, r3, 4, 12
256 ret i64 4503599621782768
259 ; Leading Zeros + Trailing Ones > 30
260 define i64 @t_LZTO() {
261 ; CHECK-LABEL: t_LZTO:
262 ; CHECK: pli r3, -2684406441
263 ; CHECK-NEXT: rldicl r3, r3, 11, 19
267 ret i64 29686707699711
270 ; Leading Zeros + Trailing Ones + Following Zeros > 30
271 define i64 @t_LZTOFO() {
272 ; CHECK-LABEL: t_LZTOFO:
273 ; CHECK: pli r3, -5720033968
274 ; CHECK-NEXT: rldicl r3, r3, 11, 12
278 ret i64 4491884997806079
281 ; Requires full expansion
282 define i64 @t_Full64Bits1() {
283 ; CHECK-LABEL: t_Full64Bits1:
284 ; CHECK: pli r4, 2146500607
285 ; CHECK-NEXT: pli r3, 4043305214
286 ; CHECK-NEXT: rldimi r3, r4, 32, 0
290 ret i64 9219149911952453886
293 ; Requires full expansion
294 define i64 @t_Ful64Bits2() {
295 ; CHECK-LABEL: t_Ful64Bits2:
296 ; CHECK: pli r4, 4042326015
297 ; CHECK-NEXT: pli r3, 4043305214
298 ; CHECK-NEXT: rldimi r3, r4, 32, 0
302 ret i64 17361658038238310654
305 ; A splat of 32 bits: 32 Bits Low == 32 Bits High
306 define i64 @t_Splat32Bits() {
307 ; CHECK-LABEL: t_Splat32Bits:
308 ; CHECK: pli r3, 262916796
309 ; CHECK-NEXT: rldimi r3, r3, 32, 0
313 ret i64 1129219040652020412
316 ; Producing `pli` when the constant fits within 34-bits and the constant
317 ; is being produced in other transformations (such as complex bit permutations).
318 define i64 @t_34Bits_Complex(i64 %a, i64 %b) {
319 ; CHECK-LABEL: t_34Bits_Complex:
320 ; CHECK: # %bb.0: # %entry
321 ; CHECK-NEXT: rotldi r4, r4, 30
322 ; CHECK-NEXT: rldimi r3, r4, 34, 31
323 ; CHECK-NEXT: pli r4, -268435457
324 ; CHECK-NEXT: and r3, r3, r4
327 ; CHECK32-LABEL: t_34Bits_Complex:
328 ; CHECK32: # %bb.0: # %entry
329 ; CHECK32-NEXT: rlwinm r4, r6, 0, 4, 2
330 ; CHECK32-NEXT: rlwimi r3, r5, 0, 31, 29
333 %and = and i64 %a, 8589934592
334 %and1 = and i64 %b, -8858370049
335 %or = or i64 %and1, %and
339 ; The load immediates resulting from phi-nodes are needed to test whether
340 ; li/lis is preferred to pli by the instruction selector.
341 define dso_local void @t_phiNode() {
342 ; CHECK-LABEL: t_phiNode:
344 ; CHECK-NEXT: li r5, 291
345 ; CHECK-NEXT: li r4, 0
346 ; CHECK-NEXT: cmpwi r3, 1
347 ; CHECK-NEXT: li r3, -1
348 ; CHECK: pli r6, 2147483647
349 ; CHECK-NEXT: pli r5, 1193046
350 ; CHECK-NEXT: pli r4, 32768
351 ; CHECK-NEXT: pli r3, -231451016
352 ; CHECK32-LABEL: t_phiNode:
353 ; CHECK32: lis r6, 18
354 ; CHECK32-NEXT: li r5, 291
355 ; CHECK32-NEXT: li r4, 0
356 ; CHECK32-NEXT: cmpwi r3, 1
357 ; CHECK32-NEXT: li r3, -1
358 ; CHECK32: pli r6, 2147483647
359 ; CHECK32-NEXT: pli r5, 1193046
360 ; CHECK32-NEXT: pli r4, 32768
361 ; CHECK32-NEXT: pli r3, -231451016
366 while.body: ; preds = %if.else.i, %entry
367 br label %while.body.i
369 while.body.i: ; preds = %sw.epilog.i, %while.body
370 %a.1.i = phi i32 [ %a.2.i, %sw.epilog.i ], [ -1, %while.body ]
371 %b.1.i = phi i32 [ %b.2.i, %sw.epilog.i ], [ 0, %while.body ]
372 %c.1.i = phi i32 [ %c.2.i, %sw.epilog.i ], [ 291, %while.body ]
373 %d.1.i = phi i32 [ %d.2.i, %sw.epilog.i ], [ 1179648, %while.body ]
374 %0 = load i8, ptr null, align 1
375 %cmp1.i = icmp eq i8 %0, 1
376 br i1 %cmp1.i, label %if.then.i, label %if.else.i
378 if.then.i: ; preds = %while.body.i
379 switch i8 undef, label %sw.default.i [
380 i8 3, label %sw.epilog.i
381 i8 2, label %sw.bb1.i
384 sw.bb1.i: ; preds = %if.then.i
385 br label %sw.epilog.i
387 sw.default.i: ; preds = %if.then.i
390 sw.epilog.i: ; preds = %sw.bb2.i, %sw.bb1.i, %if.then.i
391 %a.2.i = phi i32 [ -231451016, %sw.bb1.i ], [ %a.1.i, %if.then.i ]
392 %b.2.i = phi i32 [ 32768, %sw.bb1.i ], [ %b.1.i, %if.then.i ]
393 %c.2.i = phi i32 [ 1193046, %sw.bb1.i ], [ %c.1.i, %if.then.i ]
394 %d.2.i = phi i32 [ 2147483647, %sw.bb1.i ], [ %d.1.i, %if.then.i ]
395 br label %while.body.i
397 if.else.i: ; preds = %while.body.i
398 call void @func2(i32 signext %a.1.i, i32 signext %b.1.i, i32 signext %c.1.i, i32 signext %d.1.i)
402 declare void @func2(i32, i32, i32, i32)