xref: /llvm-project/llvm/test/CodeGen/PowerPC/p10-p11-constants.ll (revision 1df4d866cca51eeab8f012a97cc50957b45971fe)
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 | \
3; RUN:   FileCheck %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 | \
6; RUN:   FileCheck %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
10
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 | \
13; RUN:   FileCheck %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 | \
16; RUN:   FileCheck %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
20
21; These test cases aim to test constant materialization using the pli instruction on Power10 and Power11.
22
23define  signext i32 @t_16BitsMinRequiring34Bits() {
24; CHECK-LABEL: t_16BitsMinRequiring34Bits:
25; CHECK:	pli r3, 32768
26; CHECK-NEXT:	blr
27; CHECK32-LABEL: t_16BitsMinRequiring34Bits:
28; CHECK32:	pli r3, 32768
29; CHECK32-NEXT:	blr
30
31entry:
32  ret i32 32768
33}
34
35define  signext i32 @t_16Bits() {
36; CHECK-LABEL: t_16Bits:
37; CHECK:	pli r3, 62004
38; CHECK-NEXT:	blr
39; CHECK32-LABEL: t_16Bits:
40; CHECK32:	pli r3, 62004
41; CHECK32-NEXT:	blr
42
43entry:
44  ret i32 62004
45}
46
47define  signext i32 @t_lt32gt16BitsNonShiftable() {
48; CHECK-LABEL: t_lt32gt16BitsNonShiftable:
49; CHECK:	pli r3, 1193046
50; CHECK-NEXT:	blr
51; CHECK32-LABEL: t_lt32gt16BitsNonShiftable:
52; CHECK32:	pli r3, 1193046
53; CHECK32-NEXT:	blr
54
55entry:
56  ret i32 1193046
57}
58
59define  signext i32 @t_32Bits() {
60; CHECK-LABEL: t_32Bits:
61; CHECK:	pli r3, -231451016
62; CHECK-NEXT:	blr
63; CHECK32-LABEL: t_32Bits:
64; CHECK32:	pli r3, -231451016
65; CHECK32-NEXT:	blr
66
67entry:
68  ret i32 -231451016
69}
70
71define  i64 @t_34BitsLargestPositive() {
72; CHECK-LABEL: t_34BitsLargestPositive:
73; CHECK:	pli r3, 8589934591
74; CHECK-NEXT:	blr
75; CHECK32-LABEL: t_34BitsLargestPositive:
76; CHECK32:	li r3, 1
77; CHECK32-NEXT: li r4, -1
78; CHECK32-NEXT:	blr
79
80entry:
81  ret i64 8589934591
82}
83
84define  i64 @t_neg34Bits() {
85; CHECK-LABEL: t_neg34Bits:
86; CHECK:	pli r3, -8284514696
87; CHECK-NEXT:	blr
88; CHECK32-LABEL: t_neg34Bits:
89; CHECK32:	li r3, -2
90; CHECK32-NEXT: pli r4, 305419896
91; CHECK32-NEXT:	blr
92
93entry:
94  ret i64 -8284514696
95}
96
97define  signext i32 @t_16BitsMinRequiring34BitsMinusOne() {
98; CHECK-LABEL: t_16BitsMinRequiring34BitsMinusOne:
99; CHECK:	li r3, 32767
100; CHECK-NEXT:	blr
101; CHECK32-LABEL: t_16BitsMinRequiring34BitsMinusOne:
102; CHECK32:	li r3, 32767
103; CHECK32-NEXT:	blr
104
105entry:
106  ret i32 32767
107}
108
109define  signext i32 @t_lt16Bits() {
110; CHECK-LABEL: t_lt16Bits:
111; CHECK:	li r3, 291
112; CHECK-NEXT:	blr
113; CHECK32-LABEL: t_lt16Bits:
114; CHECK32:	li r3, 291
115; CHECK32-NEXT:	blr
116
117entry:
118  ret i32 291
119}
120
121define  signext i32 @t_neglt16Bits() {
122; CHECK-LABEL: t_neglt16Bits:
123; CHECK:	li r3, -3805
124; CHECK-NEXT:	blr
125; CHECK32-LABEL: t_neglt16Bits:
126; CHECK32:	li r3, -3805
127; CHECK32-NEXT:	blr
128
129entry:
130  ret i32 -3805
131}
132
133define  signext i32 @t_neg16Bits() {
134; CHECK-LABEL: t_neg16Bits:
135; CHECK:	li r3, -32204
136; CHECK-NEXT:	blr
137; CHECK32-LABEL: t_neg16Bits:
138; CHECK32:	li r3, -32204
139; CHECK32-NEXT:	blr
140
141entry:
142  ret i32 -32204
143}
144
145define  signext i32 @t_lt32gt16BitsShiftable() {
146; CHECK-LABEL: t_lt32gt16BitsShiftable:
147; CHECK:	lis r3, 18
148; CHECK-NEXT:	blr
149; CHECK32-LABEL: t_lt32gt16BitsShiftable:
150; CHECK32:	lis r3, 18
151; CHECK32-NEXT:	blr
152
153entry:
154  ret i32 1179648
155}
156
157define  signext i32 @t_32gt16BitsShiftable() {
158; CHECK-LABEL: t_32gt16BitsShiftable:
159; CHECK:	lis r3, -3532
160; CHECK-NEXT:	blr
161; CHECK32-LABEL: t_32gt16BitsShiftable:
162; CHECK32:	lis r3, -3532
163; CHECK32-NEXT:	blr
164
165entry:
166  ret i32 -231473152
167}
168
169define  signext i32 @t_32BitsZero() {
170; CHECK-LABEL: t_32BitsZero:
171; CHECK:	li r3, 0
172; CHECK-NEXT:	blr
173; CHECK32-LABEL: t_32BitsZero:
174; CHECK32:	li r3, 0
175; CHECK32-NEXT:	blr
176
177entry:
178  ret i32 0
179}
180
181define  signext i32 @t_32BitsAllOnes() {
182; CHECK-LABEL: t_32BitsAllOnes:
183; CHECK:	li r3, -1
184; CHECK-NEXT:	blr
185; CHECK32-LABEL: t_32BitsAllOnes:
186; CHECK32:	li r3, -1
187; CHECK32-NEXT:	blr
188
189entry:
190  ret i32 -1
191}
192
193define  i64 @t_34BitsLargestPositivePlus() {
194; CHECK-LABEL: t_34BitsLargestPositivePlus:
195; CHECK:	li r3, 1
196; CHECK-NEXT:	rldic r3, r3, 33, 30
197; CHECK-NEXT:	blr
198; CHECK32-LABEL: t_34BitsLargestPositivePlus:
199; CHECK32:	li r3, 2
200; CHECK32-NEXT:	li r4, 0
201; CHECK32-NEXT:	blr
202
203entry:
204  ret i64 8589934592
205}
206
207define  i64 @t_34Bits() {
208; CHECK-LABEL: t_34Bits:
209; CHECK:	pli r3, 1648790223
210; CHECK-NEXT:	rldic r3, r3, 3, 30
211; CHECK-NEXT:	blr
212; CHECK32-LABEL: t_34Bits:
213; CHECK32:	li r3, 3
214; CHECK32-NEXT:	pli r4, 305419896
215; CHECK32-NEXT:	blr
216
217entry:
218  ret i64 13190321784
219}
220
221define  i64 @t_35Bits() {
222; CHECK-LABEL: t_35Bits:
223; CHECK:	pli r3, 4266035919
224; CHECK-NEXT:	rldic r3, r3, 3, 29
225; CHECK-NEXT:	blr
226; CHECK32-LABEL: t_35Bits:
227; CHECK32:	li r3, 7
228; CHECK32-NEXT:	pli r4, -231451016
229; CHECK32-NEXT:	blr
230
231entry:
232  ret i64 34128287352
233}
234
235; (Value >> Shift) can be expressed in 34 bits
236define  i64 @t_Shift() {
237; CHECK-LABEL: t_Shift:
238; CHECK:         pli r3, 8522759166
239; CHECK-NEXT:    rotldi r3, r3, 48
240; CHECK-NEXT:    blr
241
242entry:
243  ; 0xFBFE00000001FBFE
244  ret i64 18157950747604548606
245}
246
247; Leading Zeros + Following Ones + Trailing Zeros > 30
248define  i64 @t_LZFOTZ() {
249; CHECK-LABEL: t_LZFOTZ:
250; CHECK:         pli r3, -349233
251; CHECK-NEXT:    rldic r3, r3, 4, 12
252; CHECK-NEXT:    blr
253
254entry:
255  ; 0x000FFFFFFFAABCF0
256  ret i64 4503599621782768
257}
258
259; Leading Zeros + Trailing Ones > 30
260define  i64 @t_LZTO() {
261; CHECK-LABEL: t_LZTO:
262; CHECK:         pli r3, -2684406441
263; CHECK-NEXT:    rldicl r3, r3, 11, 19
264; CHECK-NEXT:    blr
265entry:
266  ; 0x00001AFFF9AABFFF
267  ret i64 29686707699711
268}
269
270; Leading Zeros + Trailing Ones + Following Zeros > 30
271define  i64 @t_LZTOFO() {
272; CHECK-LABEL: t_LZTOFO:
273; CHECK:         pli r3, -5720033968
274; CHECK-NEXT:    rldicl r3, r3, 11, 12
275; CHECK-NEXT:    blr
276entry:
277  ; 0x000FF55879AA87FF
278  ret i64 4491884997806079
279}
280
281; Requires full expansion
282define  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
287; CHECK-NEXT:    blr
288entry:
289  ; 0x7FF0FFFFF0FFF0FE
290  ret i64 9219149911952453886
291}
292
293; Requires full expansion
294define  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
299; CHECK-NEXT:    blr
300entry:
301  ; 0xF0F0FFFFF0FFF0FE
302  ret i64 17361658038238310654
303}
304
305; A splat of 32 bits: 32 Bits Low == 32 Bits High
306define  i64 @t_Splat32Bits() {
307; CHECK-LABEL: t_Splat32Bits:
308; CHECK:         pli r3, 262916796
309; CHECK-NEXT:    rldimi r3, r3, 32, 0
310; CHECK-NEXT:    blr
311entry:
312  ; 0x0FABCABC0FABCABC
313  ret i64 1129219040652020412
314}
315
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).
318define 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
325; CHECK-NEXT:    blr
326;
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
331; CHECK32-NEXT:    blr
332entry:
333  %and = and i64 %a, 8589934592
334  %and1 = and i64 %b, -8858370049
335  %or = or i64 %and1, %and
336  ret i64 %or
337}
338
339; The load immediates resulting from phi-nodes are needed to test whether
340; li/lis is preferred to pli by the instruction selector.
341define dso_local void @t_phiNode() {
342; CHECK-LABEL: t_phiNode:
343; CHECK:	lis r6, 18
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
362
363entry:
364  br label %while.body
365
366while.body:                                       ; preds = %if.else.i, %entry
367  br label %while.body.i
368
369while.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
377
378if.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
382  ]
383
384sw.bb1.i:                                        ; preds = %if.then.i
385  br label %sw.epilog.i
386
387sw.default.i:                                     ; preds = %if.then.i
388  unreachable
389
390sw.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
396
397if.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)
399  br label %while.body
400}
401
402declare void @func2(i32, i32, i32, i32)
403