xref: /llvm-project/llvm/test/Transforms/LoopIdiom/RISCV/popcnt.ll (revision 48c6b2729e2111bec08799c65b8b459e12413546)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=+zbb -S < %s | FileCheck %s --check-prefixes=CPOP
3; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=+zbb -S < %s | FileCheck %s --check-prefixes=CPOP
4; RUN: opt -passes=loop-idiom -mtriple=riscv32 -S < %s | FileCheck %s --check-prefixes=NOCPOP
5; RUN: opt -passes=loop-idiom -mtriple=riscv64 -S < %s | FileCheck %s --check-prefixes=NOCPOP
6
7; Mostly copied from AMDGPU version.
8
9;To recognize this pattern:
10;int popcount(unsigned long long a) {
11;    int c = 0;
12;    while (a) {
13;        c++;
14;        a &= a - 1;
15;    }
16;    return c;
17;}
18;
19
20define i32 @popcount_i64(i64 %a) nounwind uwtable readnone ssp {
21; CPOP-LABEL: @popcount_i64(
22; CPOP-NEXT:  entry:
23; CPOP-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
24; CPOP-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
25; CPOP-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
26; CPOP-NEXT:    br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
27; CPOP:       while.body.preheader:
28; CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
29; CPOP:       while.body:
30; CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
31; CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
32; CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
33; CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
34; CPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_04]], -1
35; CPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_04]]
36; CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
37; CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
38; CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
39; CPOP:       while.end.loopexit:
40; CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
41; CPOP-NEXT:    br label [[WHILE_END]]
42; CPOP:       while.end:
43; CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
44; CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
45;
46; NOCPOP-LABEL: @popcount_i64(
47; NOCPOP-NEXT:  entry:
48; NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i64 [[A:%.*]], 0
49; NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
50; NOCPOP:       while.body.preheader:
51; NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
52; NOCPOP:       while.body:
53; NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
54; NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
55; NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
56; NOCPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_04]], -1
57; NOCPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_04]]
58; NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
59; NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
60; NOCPOP:       while.end.loopexit:
61; NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
62; NOCPOP-NEXT:    br label [[WHILE_END]]
63; NOCPOP:       while.end:
64; NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
65; NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
66;
67entry:
68  %tobool3 = icmp eq i64 %a, 0
69  br i1 %tobool3, label %while.end, label %while.body
70
71while.body:                                       ; preds = %entry, %while.body
72  %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
73  %a.addr.04 = phi i64 [ %and, %while.body ], [ %a, %entry ]
74  %inc = add nsw i32 %c.05, 1
75  %sub = add i64 %a.addr.04, -1
76  %and = and i64 %sub, %a.addr.04
77  %tobool = icmp eq i64 %and, 0
78  br i1 %tobool, label %while.end, label %while.body
79
80while.end:                                        ; preds = %while.body, %entry
81  %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
82  ret i32 %c.0.lcssa
83}
84
85define i32 @popcount_i32(i32 %a) nounwind uwtable readnone ssp {
86; CPOP-LABEL: @popcount_i32(
87; CPOP-NEXT:  entry:
88; CPOP-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A:%.*]])
89; CPOP-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0
90; CPOP-NEXT:    br i1 [[TMP1]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
91; CPOP:       while.body.preheader:
92; CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
93; CPOP:       while.body:
94; CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
95; CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
96; CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
97; CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
98; CPOP-NEXT:    [[SUB:%.*]] = add i32 [[A_ADDR_04]], -1
99; CPOP-NEXT:    [[AND]] = and i32 [[SUB]], [[A_ADDR_04]]
100; CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
101; CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
102; CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
103; CPOP:       while.end.loopexit:
104; CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY]] ]
105; CPOP-NEXT:    br label [[WHILE_END]]
106; CPOP:       while.end:
107; CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
108; CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
109;
110; NOCPOP-LABEL: @popcount_i32(
111; NOCPOP-NEXT:  entry:
112; NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[A:%.*]], 0
113; NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
114; NOCPOP:       while.body.preheader:
115; NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
116; NOCPOP:       while.body:
117; NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
118; NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
119; NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
120; NOCPOP-NEXT:    [[SUB:%.*]] = add i32 [[A_ADDR_04]], -1
121; NOCPOP-NEXT:    [[AND]] = and i32 [[SUB]], [[A_ADDR_04]]
122; NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0
123; NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
124; NOCPOP:       while.end.loopexit:
125; NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
126; NOCPOP-NEXT:    br label [[WHILE_END]]
127; NOCPOP:       while.end:
128; NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
129; NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
130;
131entry:
132  %tobool3 = icmp eq i32 %a, 0
133  br i1 %tobool3, label %while.end, label %while.body
134
135while.body:                                       ; preds = %entry, %while.body
136  %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
137  %a.addr.04 = phi i32 [ %and, %while.body ], [ %a, %entry ]
138  %inc = add nsw i32 %c.05, 1
139  %sub = add i32 %a.addr.04, -1
140  %and = and i32 %sub, %a.addr.04
141  %tobool = icmp eq i32 %and, 0
142  br i1 %tobool, label %while.end, label %while.body
143
144while.end:                                        ; preds = %while.body, %entry
145  %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
146  ret i32 %c.0.lcssa
147}
148
149define i32 @popcount_i128(i128 %a) nounwind uwtable readnone ssp {
150; CPOP-LABEL: @popcount_i128(
151; CPOP-NEXT:  entry:
152; CPOP-NEXT:    [[TMP0:%.*]] = call i128 @llvm.ctpop.i128(i128 [[A:%.*]])
153; CPOP-NEXT:    [[TMP1:%.*]] = trunc i128 [[TMP0]] to i32
154; CPOP-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
155; CPOP-NEXT:    br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
156; CPOP:       while.body.preheader:
157; CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
158; CPOP:       while.body:
159; CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
160; CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
161; CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i128 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
162; CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
163; CPOP-NEXT:    [[SUB:%.*]] = add i128 [[A_ADDR_04]], -1
164; CPOP-NEXT:    [[AND]] = and i128 [[SUB]], [[A_ADDR_04]]
165; CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
166; CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
167; CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
168; CPOP:       while.end.loopexit:
169; CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
170; CPOP-NEXT:    br label [[WHILE_END]]
171; CPOP:       while.end:
172; CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
173; CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
174;
175; NOCPOP-LABEL: @popcount_i128(
176; NOCPOP-NEXT:  entry:
177; NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i128 [[A:%.*]], 0
178; NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
179; NOCPOP:       while.body.preheader:
180; NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
181; NOCPOP:       while.body:
182; NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
183; NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i128 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
184; NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
185; NOCPOP-NEXT:    [[SUB:%.*]] = add i128 [[A_ADDR_04]], -1
186; NOCPOP-NEXT:    [[AND]] = and i128 [[SUB]], [[A_ADDR_04]]
187; NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i128 [[AND]], 0
188; NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
189; NOCPOP:       while.end.loopexit:
190; NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
191; NOCPOP-NEXT:    br label [[WHILE_END]]
192; NOCPOP:       while.end:
193; NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
194; NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
195;
196entry:
197  %tobool3 = icmp eq i128 %a, 0
198  br i1 %tobool3, label %while.end, label %while.body
199
200while.body:                                       ; preds = %entry, %while.body
201  %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
202  %a.addr.04 = phi i128 [ %and, %while.body ], [ %a, %entry ]
203  %inc = add nsw i32 %c.05, 1
204  %sub = add i128 %a.addr.04, -1
205  %and = and i128 %sub, %a.addr.04
206  %tobool = icmp eq i128 %and, 0
207  br i1 %tobool, label %while.end, label %while.body
208
209while.end:                                        ; preds = %while.body, %entry
210  %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
211  ret i32 %c.0.lcssa
212}
213
214; To recognize this pattern:
215;int popcount(unsigned long long a, int mydata1, int mydata2) {
216;    int c = 0;
217;    while (a) {
218;        c++;
219;        a &= a - 1;
220;        mydata1 *= c;
221;        mydata2 *= (int)a;
222;    }
223;    return c + mydata1 + mydata2;
224;}
225
226define i32 @popcount2(i64 %a, i32 %mydata1, i32 %mydata2) nounwind uwtable readnone ssp {
227; CPOP-LABEL: @popcount2(
228; CPOP-NEXT:  entry:
229; CPOP-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
230; CPOP-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
231; CPOP-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
232; CPOP-NEXT:    br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
233; CPOP:       while.body.preheader:
234; CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
235; CPOP:       while.body:
236; CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
237; CPOP-NEXT:    [[C_013:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
238; CPOP-NEXT:    [[MYDATA2_ADDR_012:%.*]] = phi i32 [ [[MUL1:%.*]], [[WHILE_BODY]] ], [ [[MYDATA2:%.*]], [[WHILE_BODY_PREHEADER]] ]
239; CPOP-NEXT:    [[MYDATA1_ADDR_011:%.*]] = phi i32 [ [[MUL:%.*]], [[WHILE_BODY]] ], [ [[MYDATA1:%.*]], [[WHILE_BODY_PREHEADER]] ]
240; CPOP-NEXT:    [[A_ADDR_010:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
241; CPOP-NEXT:    [[INC]] = add nsw i32 [[C_013]], 1
242; CPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_010]], -1
243; CPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_010]]
244; CPOP-NEXT:    [[MUL]] = mul nsw i32 [[INC]], [[MYDATA1_ADDR_011]]
245; CPOP-NEXT:    [[CONV:%.*]] = trunc i64 [[AND]] to i32
246; CPOP-NEXT:    [[MUL1]] = mul nsw i32 [[CONV]], [[MYDATA2_ADDR_012]]
247; CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
248; CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
249; CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
250; CPOP:       while.end.loopexit:
251; CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
252; CPOP-NEXT:    [[MUL_LCSSA:%.*]] = phi i32 [ [[MUL]], [[WHILE_BODY]] ]
253; CPOP-NEXT:    [[MUL1_LCSSA:%.*]] = phi i32 [ [[MUL1]], [[WHILE_BODY]] ]
254; CPOP-NEXT:    br label [[WHILE_END]]
255; CPOP:       while.end:
256; CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
257; CPOP-NEXT:    [[MYDATA2_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA2]], [[ENTRY]] ], [ [[MUL1_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
258; CPOP-NEXT:    [[MYDATA1_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA1]], [[ENTRY]] ], [ [[MUL_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
259; CPOP-NEXT:    [[ADD:%.*]] = add i32 [[MYDATA2_ADDR_0_LCSSA]], [[MYDATA1_ADDR_0_LCSSA]]
260; CPOP-NEXT:    [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]]
261; CPOP-NEXT:    ret i32 [[ADD2]]
262;
263; NOCPOP-LABEL: @popcount2(
264; NOCPOP-NEXT:  entry:
265; NOCPOP-NEXT:    [[TOBOOL9:%.*]] = icmp eq i64 [[A:%.*]], 0
266; NOCPOP-NEXT:    br i1 [[TOBOOL9]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
267; NOCPOP:       while.body.preheader:
268; NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
269; NOCPOP:       while.body:
270; NOCPOP-NEXT:    [[C_013:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
271; NOCPOP-NEXT:    [[MYDATA2_ADDR_012:%.*]] = phi i32 [ [[MUL1:%.*]], [[WHILE_BODY]] ], [ [[MYDATA2:%.*]], [[WHILE_BODY_PREHEADER]] ]
272; NOCPOP-NEXT:    [[MYDATA1_ADDR_011:%.*]] = phi i32 [ [[MUL:%.*]], [[WHILE_BODY]] ], [ [[MYDATA1:%.*]], [[WHILE_BODY_PREHEADER]] ]
273; NOCPOP-NEXT:    [[A_ADDR_010:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
274; NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_013]], 1
275; NOCPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_010]], -1
276; NOCPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_010]]
277; NOCPOP-NEXT:    [[MUL]] = mul nsw i32 [[INC]], [[MYDATA1_ADDR_011]]
278; NOCPOP-NEXT:    [[CONV:%.*]] = trunc i64 [[AND]] to i32
279; NOCPOP-NEXT:    [[MUL1]] = mul nsw i32 [[CONV]], [[MYDATA2_ADDR_012]]
280; NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
281; NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
282; NOCPOP:       while.end.loopexit:
283; NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
284; NOCPOP-NEXT:    [[MUL_LCSSA:%.*]] = phi i32 [ [[MUL]], [[WHILE_BODY]] ]
285; NOCPOP-NEXT:    [[MUL1_LCSSA:%.*]] = phi i32 [ [[MUL1]], [[WHILE_BODY]] ]
286; NOCPOP-NEXT:    br label [[WHILE_END]]
287; NOCPOP:       while.end:
288; NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
289; NOCPOP-NEXT:    [[MYDATA2_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA2]], [[ENTRY]] ], [ [[MUL1_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
290; NOCPOP-NEXT:    [[MYDATA1_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA1]], [[ENTRY]] ], [ [[MUL_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
291; NOCPOP-NEXT:    [[ADD:%.*]] = add i32 [[MYDATA2_ADDR_0_LCSSA]], [[MYDATA1_ADDR_0_LCSSA]]
292; NOCPOP-NEXT:    [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]]
293; NOCPOP-NEXT:    ret i32 [[ADD2]]
294;
295entry:
296  %tobool9 = icmp eq i64 %a, 0
297  br i1 %tobool9, label %while.end, label %while.body
298
299while.body:                                       ; preds = %entry, %while.body
300  %c.013 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
301  %mydata2.addr.012 = phi i32 [ %mul1, %while.body ], [ %mydata2, %entry ]
302  %mydata1.addr.011 = phi i32 [ %mul, %while.body ], [ %mydata1, %entry ]
303  %a.addr.010 = phi i64 [ %and, %while.body ], [ %a, %entry ]
304  %inc = add nsw i32 %c.013, 1
305  %sub = add i64 %a.addr.010, -1
306  %and = and i64 %sub, %a.addr.010
307  %mul = mul nsw i32 %inc, %mydata1.addr.011
308  %conv = trunc i64 %and to i32
309  %mul1 = mul nsw i32 %conv, %mydata2.addr.012
310  %tobool = icmp eq i64 %and, 0
311  br i1 %tobool, label %while.end, label %while.body
312
313while.end:                                        ; preds = %while.body, %entry
314  %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
315  %mydata2.addr.0.lcssa = phi i32 [ %mydata2, %entry ], [ %mul1, %while.body ]
316  %mydata1.addr.0.lcssa = phi i32 [ %mydata1, %entry ], [ %mul, %while.body ]
317  %add = add i32 %mydata2.addr.0.lcssa, %mydata1.addr.0.lcssa
318  %add2 = add i32 %add, %c.0.lcssa
319  ret i32 %add2
320}
321