1target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
2target triple = "powerpc64-unknown-linux-gnu"
3; RUN: llc -verify-machineinstrs -O2 -ppc-asm-full-reg-names -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck %s --implicit-check-not isel
4; Function Attrs: norecurse nounwind readnone
5define signext i32 @testExpandISELToIfElse(i32 signext %i, i32 signext %j) {
6entry:
7  %cmp = icmp sgt i32 %i, 0
8  %add = add nsw i32 %i, 1
9  %cond = select i1 %cmp, i32 %add, i32 %j
10  ret i32 %cond
11
12; CHECK-LABEL: @testExpandISELToIfElse
13; CHECK: addi r5, r3, 1
14; CHECK-NEXT: cmpwi cr0, r3, 0
15; CHECK-NEXT: bc 12, 1, [[TRUE:.LBB[0-9]+]]
16; CHECK: ori r3, r4, 0
17; CHECK-NEXT: b [[SUCCESSOR:.LBB[0-9]+]]
18; CHECK-NEXT:  [[TRUE]]
19; CHECK-NEXT: addi r3, r5, 0
20; CHECK-NEXT: [[SUCCESSOR]]
21; CHECK-NEXT: extsw r3, r3
22; CHECK-NEXT: blr
23}
24
25
26; Function Attrs: norecurse nounwind readnone
27define signext i32 @testExpandISELToIf(i32 signext %i, i32 signext %j) {
28entry:
29  %cmp = icmp sgt i32 %i, 0
30  %cond = select i1 %cmp, i32 %j, i32 %i
31  ret i32 %cond
32
33; CHECK-LABEL: @testExpandISELToIf
34; CHECK: cmpwi	 r3, 0
35; CHECK-NEXT: bc 12, 1, [[TRUE:.LBB[0-9]+]]
36; CHECK-NEXT: blr
37; CHECK-NEXT:  [[TRUE]]
38; CHECK-NEXT: addi r3, r4, 0
39; CHECK-NEXT: blr
40}
41
42; Function Attrs: norecurse nounwind readnone
43define signext i32 @testExpandISELToElse(i32 signext %i, i32 signext %j) {
44entry:
45  %cmp = icmp sgt i32 %i, 0
46  %cond = select i1 %cmp, i32 %i, i32 %j
47  ret i32 %cond
48
49; CHECK-LABEL: @testExpandISELToElse
50; CHECK: cmpwi	 r3, 0
51; CHECK-NEXT: bclr 12, 1, 0
52; CHECK: ori r3, r4, 0
53; CHECK-NEXT: blr
54}
55
56; Function Attrs: norecurse nounwind readnone
57define signext i32 @testReplaceISELWithCopy(i32 signext %i, i32 signext %j) {
58entry:
59  %cmp = icmp sgt i32 %i, 0
60  %cond = select i1 %cmp, i32 %j, i32 %j
61  ret i32 %cond
62
63; CHECK-LABEL: @testReplaceISELWithCopy
64
65; Fix me should really check: addi r3, r4, 0
66; but for some reason it's optimized to mr r3, r4
67; CHECK: mr r3, r4
68; CHECK-NEXT: blr
69}
70
71; Function Attrs: norecurse nounwind readnone
72define signext i32 @testExpandISELToNull(i32 signext %i, i32 signext %j) {
73entry:
74  %cmp = icmp sgt i32 %i, 0
75  %cond = select i1 %cmp, i32 %i, i32 %i
76  ret i32 %cond
77
78; CHECK-LABEL: @testExpandISELToNull
79; CHECK-NOT: b {{.LBB[0-9]+}}
80; CHECK-NOT: bc
81; CHECK: blr
82}
83
84; Function Attrs: norecurse nounwind readnone
85define signext i32 @testExpandISELsTo2ORIs2ADDIs
86  (i32 signext %a, i32 signext %b, i32 signext %d,
87   i32 signext %f, i32 signext %g) {
88entry:
89
90  %cmp = icmp sgt i32 %g, 0
91  %a.b = select i1 %cmp, i32 %g, i32 %b
92  %d.f = select i1 %cmp, i32 %d, i32 %f
93  %add = add nsw i32 %a.b, %d.f
94  ret i32 %add
95
96; CHECK-LABEL: @testExpandISELsTo2ORIs2ADDIs
97; CHECK: cmpwi r7, 0
98; CHECK-NEXT: bc 12, 1, [[TRUE:.LBB[0-9]+]]
99; CHECK: ori r3, r4, 0
100; CHECK-NEXT: ori r12, r6, 0
101; CHECK-NEXT: b [[SUCCESSOR:.LBB[0-9]+]]
102; CHECK-NEXT:  [[TRUE]]
103; CHECK-NEXT: addi r3, r7, 0
104; CHECK-NEXT: addi r12, r5, 0
105; CHECK-NEXT: [[SUCCESSOR]]
106; CHECK-NEXT: add r3, r3, r12
107; CHECK-NEXT: extsw r3, r3
108; CHECK-NEXT: blr
109}
110
111; Function Attrs: norecurse nounwind readnone
112define signext i32 @testExpandISELsTo2ORIs1ADDI
113  (i32 signext %a, i32 signext %b, i32 signext %d,
114   i32 signext %f, i32 signext %g) {
115entry:
116  %cmp = icmp sgt i32 %g, 0
117  %a.b = select i1 %cmp, i32 %a, i32 %b
118  %d.f = select i1 %cmp, i32 %d, i32 %f
119  %add = add nsw i32 %a.b, %d.f
120  ret i32 %add
121
122; CHECK-LABEL: @testExpandISELsTo2ORIs1ADDI
123; CHECK: cmpwi cr0, r7, 0
124; CHECK-NEXT: bc 12, 1, [[TRUE:.LBB[0-9]+]]
125; CHECK: ori r3, r4, 0
126; CHECK-NEXT: ori r12, r6, 0
127; CHECK-NEXT: b [[SUCCESSOR:.LBB[0-9]+]]
128; CHECK-NEXT: [[TRUE]]
129; CHECK-NEXT: addi r12, r5, 0
130; CHECK-NEXT:  [[SUCCESSOR]]
131; CHECK-NEXT: add r3, r3, r12
132; CHECK-NEXT: extsw r3, r3
133; CHECK-NEXT: blr
134}
135
136; Function Attrs: norecurse nounwind readnone
137define signext i32 @testExpandISELsTo1ORI1ADDI
138  (i32 signext %a, i32 signext %b, i32 signext %d,
139   i32 signext %f, i32 signext %g) {
140entry:
141
142  %cmp = icmp sgt i32 %g, 0
143  %a.b = select i1 %cmp, i32 %a, i32 %b
144  %d.f = select i1 %cmp, i32 %d, i32 %f
145  %add1 = add nsw i32 %a.b, %d.f
146  %add2 = add nsw i32 %a, %add1
147  ret i32 %add2
148
149; CHECK-LABEL: @testExpandISELsTo1ORI1ADDI
150; CHECK: cmpwi cr0, r7, 0
151; CHECK-NEXT: bc 12, 1, [[TRUE:.LBB[0-9]+]]
152; CHECK: ori r5, r6, 0
153; CHECK-NEXT: b [[SUCCESSOR:.LBB[0-9]+]]
154; CHECK-NEXT: [[TRUE]]
155; CHECK-NEXT: addi r4, r3, 0
156; CHECK-NEXT:  [[SUCCESSOR]]
157; CHECK-NEXT: add r4, r4, r5
158; CHECK-NEXT: add r3, r3, r4
159; CHECK-NEXT: extsw r3, r3
160; CHECK-NEXT: blr
161}
162
163; Function Attrs: norecurse nounwind readnone
164define signext i32 @testExpandISELsTo0ORI2ADDIs
165  (i32 signext %a, i32 signext %b, i32 signext %d,
166   i32 signext %f, i32 signext %g) {
167entry:
168
169  %cmp = icmp sgt i32 %g, 0
170  %a.b = select i1 %cmp, i32 %a, i32 %b
171  %d.f = select i1 %cmp, i32 %d, i32 %f
172  %add1 = add nsw i32 %a.b, %d.f
173  %add2 = add nsw i32 %a, %add1
174  %sub1 = sub nsw i32 %add2, %d
175  ret i32 %sub1
176
177; CHECK-LABEL: @testExpandISELsTo0ORI2ADDIs
178; CHECK: cmpwi cr0, r7, 0
179; CHECK-NEXT: bc 12, 1, [[TRUE:.LBB[0-9]+]]
180; CHECK-NEXT: b [[SUCCESSOR:.LBB[0-9]+]]
181; CHECK-NEXT:  [[TRUE]]
182; CHECK-NEXT: addi r4, r3, 0
183; CHECK-NEXT: addi r6, r5, 0
184; CHECK-NEXT:  [[SUCCESSOR]]
185; CHECK-NEXT: add r4, r4, r6
186; CHECK-NEXT: add r3, r3, r4
187; CHECK-NEXT: subf r3, r5, r3
188; CHECK-NEXT: extsw r3, r3
189; CHECK-NEXT: blr
190}
191
192
193@b = common local_unnamed_addr global i32 0, align 4
194@a = common local_unnamed_addr global i32 0, align 4
195; Function Attrs: norecurse nounwind readonly
196define signext i32 @testComplexISEL() #0 {
197entry:
198  %0 = load i32, i32* @b, align 4, !tbaa !1
199  %tobool = icmp eq i32 %0, 0
200  br i1 %tobool, label %if.end, label %cleanup
201
202if.end:
203  %1 = load i32, i32* @a, align 4, !tbaa !1
204  %conv = sext i32 %1 to i64
205  %2 = inttoptr i64 %conv to i32 (...)*
206  %cmp = icmp eq i32 (...)* %2, bitcast (i32 ()* @testComplexISEL to i32 (...)*)
207  %conv3 = zext i1 %cmp to i32
208  br label %cleanup
209
210cleanup:
211  %retval.0 = phi i32 [ %conv3, %if.end ], [ 1, %entry ]
212  ret i32 %retval.0
213
214; CHECK-LABEL: @testComplexISEL
215; CHECK-DAG: [[LI:r[0-9]+]], 1
216; CHECK-DAG: cmplwi [[LD:r[0-9]+]], 0
217; CHECK: beq cr0, [[EQ:.LBB[0-9_]+]]
218; CHECK: blr
219; CHECK: [[EQ]]
220; CHECK: xor [[XOR:r[0-9]+]]
221; CHECK: cntlzd [[CZ:r[0-9]+]], [[XOR]]
222; CHECK: rldicl [[SH:r[0-9]+]], [[CZ]], 58, 63
223}
224
225!1 = !{!2, !2, i64 0}
226!2 = !{!"int", !3, i64 0}
227!3 = !{!"omnipotent char", !4, i64 0}
228!4 = !{!"Simple C/C++ TBAA"}
229