xref: /llvm-project/llvm/test/Transforms/LoopUnroll/unroll-cost-symbolic-execute.ll (revision ef992b60798b6cd2c50b25351bfc392e319896b7)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=loop-unroll -S -unroll-threshold=120 -unroll-max-iteration-count-to-analyze=100 < %s | FileCheck %s
3
4; TODO: None of the if.false blocks are reachable, it would be nice if
5; the output of unrolling made this obvious and didn't rely on other
6; passes to cleanup code the cost model already knew was dead.
7
8@G = global i32 0
9
10; Symbolic simplification can prove the value of %zext on first
11; iteration, and can prove that it's loop invariant on the second
12define i32 @test_symbolic_simplify(i32 %limit) {
13; CHECK-LABEL: @test_symbolic_simplify(
14; CHECK-NEXT:  entry:
15; CHECK-NEXT:    br label [[LOOP:%.*]]
16; CHECK:       loop:
17; CHECK-NEXT:    store i32 -1, ptr @G, align 4
18; CHECK-NEXT:    [[CMP_1:%.*]] = icmp eq i32 0, [[LIMIT:%.*]]
19; CHECK-NEXT:    [[ZEXT_1:%.*]] = sext i1 [[CMP_1]] to i32
20; CHECK-NEXT:    store i32 [[ZEXT_1]], ptr @G, align 4
21; CHECK-NEXT:    [[CMP_2:%.*]] = icmp eq i32 0, [[LIMIT]]
22; CHECK-NEXT:    [[ZEXT_2:%.*]] = sext i1 [[CMP_2]] to i32
23; CHECK-NEXT:    store i32 [[ZEXT_2]], ptr @G, align 4
24; CHECK-NEXT:    [[CMP_3:%.*]] = icmp eq i32 0, [[LIMIT]]
25; CHECK-NEXT:    [[ZEXT_3:%.*]] = sext i1 [[CMP_3]] to i32
26; CHECK-NEXT:    store i32 [[ZEXT_3]], ptr @G, align 4
27; CHECK-NEXT:    [[CMP_4:%.*]] = icmp eq i32 0, [[LIMIT]]
28; CHECK-NEXT:    [[ZEXT_4:%.*]] = sext i1 [[CMP_4]] to i32
29; CHECK-NEXT:    store i32 [[ZEXT_4]], ptr @G, align 4
30; CHECK-NEXT:    [[CMP_5:%.*]] = icmp eq i32 0, [[LIMIT]]
31; CHECK-NEXT:    [[ZEXT_5:%.*]] = sext i1 [[CMP_5]] to i32
32; CHECK-NEXT:    store i32 [[ZEXT_5]], ptr @G, align 4
33; CHECK-NEXT:    [[CMP_6:%.*]] = icmp eq i32 0, [[LIMIT]]
34; CHECK-NEXT:    [[ZEXT_6:%.*]] = sext i1 [[CMP_6]] to i32
35; CHECK-NEXT:    store i32 [[ZEXT_6]], ptr @G, align 4
36; CHECK-NEXT:    [[CMP_7:%.*]] = icmp eq i32 0, [[LIMIT]]
37; CHECK-NEXT:    [[ZEXT_7:%.*]] = sext i1 [[CMP_7]] to i32
38; CHECK-NEXT:    store i32 [[ZEXT_7]], ptr @G, align 4
39; CHECK-NEXT:    [[CMP_8:%.*]] = icmp eq i32 0, [[LIMIT]]
40; CHECK-NEXT:    [[ZEXT_8:%.*]] = sext i1 [[CMP_8]] to i32
41; CHECK-NEXT:    store i32 [[ZEXT_8]], ptr @G, align 4
42; CHECK-NEXT:    [[CMP_9:%.*]] = icmp eq i32 0, [[LIMIT]]
43; CHECK-NEXT:    [[ZEXT_9:%.*]] = sext i1 [[CMP_9]] to i32
44; CHECK-NEXT:    store i32 [[ZEXT_9]], ptr @G, align 4
45; CHECK-NEXT:    [[CMP_10:%.*]] = icmp eq i32 0, [[LIMIT]]
46; CHECK-NEXT:    [[ZEXT_10:%.*]] = sext i1 [[CMP_10]] to i32
47; CHECK-NEXT:    store i32 [[ZEXT_10]], ptr @G, align 4
48; CHECK-NEXT:    [[CMP_11:%.*]] = icmp eq i32 0, [[LIMIT]]
49; CHECK-NEXT:    [[ZEXT_11:%.*]] = sext i1 [[CMP_11]] to i32
50; CHECK-NEXT:    store i32 [[ZEXT_11]], ptr @G, align 4
51; CHECK-NEXT:    [[CMP_12:%.*]] = icmp eq i32 0, [[LIMIT]]
52; CHECK-NEXT:    [[ZEXT_12:%.*]] = sext i1 [[CMP_12]] to i32
53; CHECK-NEXT:    store i32 [[ZEXT_12]], ptr @G, align 4
54; CHECK-NEXT:    [[CMP_13:%.*]] = icmp eq i32 0, [[LIMIT]]
55; CHECK-NEXT:    [[ZEXT_13:%.*]] = sext i1 [[CMP_13]] to i32
56; CHECK-NEXT:    store i32 [[ZEXT_13]], ptr @G, align 4
57; CHECK-NEXT:    [[CMP_14:%.*]] = icmp eq i32 0, [[LIMIT]]
58; CHECK-NEXT:    [[ZEXT_14:%.*]] = sext i1 [[CMP_14]] to i32
59; CHECK-NEXT:    store i32 [[ZEXT_14]], ptr @G, align 4
60; CHECK-NEXT:    [[CMP_15:%.*]] = icmp eq i32 0, [[LIMIT]]
61; CHECK-NEXT:    [[ZEXT_15:%.*]] = sext i1 [[CMP_15]] to i32
62; CHECK-NEXT:    store i32 [[ZEXT_15]], ptr @G, align 4
63; CHECK-NEXT:    [[CMP_16:%.*]] = icmp eq i32 0, [[LIMIT]]
64; CHECK-NEXT:    [[ZEXT_16:%.*]] = sext i1 [[CMP_16]] to i32
65; CHECK-NEXT:    store i32 [[ZEXT_16]], ptr @G, align 4
66; CHECK-NEXT:    [[CMP_17:%.*]] = icmp eq i32 0, [[LIMIT]]
67; CHECK-NEXT:    [[ZEXT_17:%.*]] = sext i1 [[CMP_17]] to i32
68; CHECK-NEXT:    store i32 [[ZEXT_17]], ptr @G, align 4
69; CHECK-NEXT:    [[CMP_18:%.*]] = icmp eq i32 0, [[LIMIT]]
70; CHECK-NEXT:    [[ZEXT_18:%.*]] = sext i1 [[CMP_18]] to i32
71; CHECK-NEXT:    store i32 [[ZEXT_18]], ptr @G, align 4
72; CHECK-NEXT:    [[CMP_19:%.*]] = icmp eq i32 0, [[LIMIT]]
73; CHECK-NEXT:    [[ZEXT_19:%.*]] = sext i1 [[CMP_19]] to i32
74; CHECK-NEXT:    store i32 [[ZEXT_19]], ptr @G, align 4
75; CHECK-NEXT:    [[CMP_20:%.*]] = icmp eq i32 0, [[LIMIT]]
76; CHECK-NEXT:    [[ZEXT_20:%.*]] = sext i1 [[CMP_20]] to i32
77; CHECK-NEXT:    store i32 [[ZEXT_20]], ptr @G, align 4
78; CHECK-NEXT:    [[CMP_21:%.*]] = icmp eq i32 0, [[LIMIT]]
79; CHECK-NEXT:    [[ZEXT_21:%.*]] = sext i1 [[CMP_21]] to i32
80; CHECK-NEXT:    store i32 [[ZEXT_21]], ptr @G, align 4
81; CHECK-NEXT:    [[CMP_22:%.*]] = icmp eq i32 0, [[LIMIT]]
82; CHECK-NEXT:    [[ZEXT_22:%.*]] = sext i1 [[CMP_22]] to i32
83; CHECK-NEXT:    store i32 [[ZEXT_22]], ptr @G, align 4
84; CHECK-NEXT:    [[CMP_23:%.*]] = icmp eq i32 0, [[LIMIT]]
85; CHECK-NEXT:    [[ZEXT_23:%.*]] = sext i1 [[CMP_23]] to i32
86; CHECK-NEXT:    store i32 [[ZEXT_23]], ptr @G, align 4
87; CHECK-NEXT:    [[CMP_24:%.*]] = icmp eq i32 0, [[LIMIT]]
88; CHECK-NEXT:    [[ZEXT_24:%.*]] = sext i1 [[CMP_24]] to i32
89; CHECK-NEXT:    store i32 [[ZEXT_24]], ptr @G, align 4
90; CHECK-NEXT:    [[CMP_25:%.*]] = icmp eq i32 0, [[LIMIT]]
91; CHECK-NEXT:    [[ZEXT_25:%.*]] = sext i1 [[CMP_25]] to i32
92; CHECK-NEXT:    store i32 [[ZEXT_25]], ptr @G, align 4
93; CHECK-NEXT:    [[CMP_26:%.*]] = icmp eq i32 0, [[LIMIT]]
94; CHECK-NEXT:    [[ZEXT_26:%.*]] = sext i1 [[CMP_26]] to i32
95; CHECK-NEXT:    store i32 [[ZEXT_26]], ptr @G, align 4
96; CHECK-NEXT:    [[CMP_27:%.*]] = icmp eq i32 0, [[LIMIT]]
97; CHECK-NEXT:    [[ZEXT_27:%.*]] = sext i1 [[CMP_27]] to i32
98; CHECK-NEXT:    store i32 [[ZEXT_27]], ptr @G, align 4
99; CHECK-NEXT:    [[CMP_28:%.*]] = icmp eq i32 0, [[LIMIT]]
100; CHECK-NEXT:    [[ZEXT_28:%.*]] = sext i1 [[CMP_28]] to i32
101; CHECK-NEXT:    store i32 [[ZEXT_28]], ptr @G, align 4
102; CHECK-NEXT:    [[CMP_29:%.*]] = icmp eq i32 0, [[LIMIT]]
103; CHECK-NEXT:    [[ZEXT_29:%.*]] = sext i1 [[CMP_29]] to i32
104; CHECK-NEXT:    store i32 [[ZEXT_29]], ptr @G, align 4
105; CHECK-NEXT:    [[CMP_30:%.*]] = icmp eq i32 0, [[LIMIT]]
106; CHECK-NEXT:    [[ZEXT_30:%.*]] = sext i1 [[CMP_30]] to i32
107; CHECK-NEXT:    store i32 [[ZEXT_30]], ptr @G, align 4
108; CHECK-NEXT:    [[CMP_31:%.*]] = icmp eq i32 0, [[LIMIT]]
109; CHECK-NEXT:    [[ZEXT_31:%.*]] = sext i1 [[CMP_31]] to i32
110; CHECK-NEXT:    store i32 [[ZEXT_31]], ptr @G, align 4
111; CHECK-NEXT:    [[CMP_32:%.*]] = icmp eq i32 0, [[LIMIT]]
112; CHECK-NEXT:    [[ZEXT_32:%.*]] = sext i1 [[CMP_32]] to i32
113; CHECK-NEXT:    store i32 [[ZEXT_32]], ptr @G, align 4
114; CHECK-NEXT:    [[CMP_33:%.*]] = icmp eq i32 0, [[LIMIT]]
115; CHECK-NEXT:    [[ZEXT_33:%.*]] = sext i1 [[CMP_33]] to i32
116; CHECK-NEXT:    store i32 [[ZEXT_33]], ptr @G, align 4
117; CHECK-NEXT:    [[CMP_34:%.*]] = icmp eq i32 0, [[LIMIT]]
118; CHECK-NEXT:    [[ZEXT_34:%.*]] = sext i1 [[CMP_34]] to i32
119; CHECK-NEXT:    store i32 [[ZEXT_34]], ptr @G, align 4
120; CHECK-NEXT:    [[CMP_35:%.*]] = icmp eq i32 0, [[LIMIT]]
121; CHECK-NEXT:    [[ZEXT_35:%.*]] = sext i1 [[CMP_35]] to i32
122; CHECK-NEXT:    store i32 [[ZEXT_35]], ptr @G, align 4
123; CHECK-NEXT:    [[CMP_36:%.*]] = icmp eq i32 0, [[LIMIT]]
124; CHECK-NEXT:    [[ZEXT_36:%.*]] = sext i1 [[CMP_36]] to i32
125; CHECK-NEXT:    store i32 [[ZEXT_36]], ptr @G, align 4
126; CHECK-NEXT:    [[CMP_37:%.*]] = icmp eq i32 0, [[LIMIT]]
127; CHECK-NEXT:    [[ZEXT_37:%.*]] = sext i1 [[CMP_37]] to i32
128; CHECK-NEXT:    store i32 [[ZEXT_37]], ptr @G, align 4
129; CHECK-NEXT:    [[CMP_38:%.*]] = icmp eq i32 0, [[LIMIT]]
130; CHECK-NEXT:    [[ZEXT_38:%.*]] = sext i1 [[CMP_38]] to i32
131; CHECK-NEXT:    store i32 [[ZEXT_38]], ptr @G, align 4
132; CHECK-NEXT:    [[CMP_39:%.*]] = icmp eq i32 0, [[LIMIT]]
133; CHECK-NEXT:    [[ZEXT_39:%.*]] = sext i1 [[CMP_39]] to i32
134; CHECK-NEXT:    store i32 [[ZEXT_39]], ptr @G, align 4
135; CHECK-NEXT:    [[CMP_40:%.*]] = icmp eq i32 0, [[LIMIT]]
136; CHECK-NEXT:    [[ZEXT_40:%.*]] = sext i1 [[CMP_40]] to i32
137; CHECK-NEXT:    store i32 [[ZEXT_40]], ptr @G, align 4
138; CHECK-NEXT:    [[CMP_41:%.*]] = icmp eq i32 0, [[LIMIT]]
139; CHECK-NEXT:    [[ZEXT_41:%.*]] = sext i1 [[CMP_41]] to i32
140; CHECK-NEXT:    store i32 [[ZEXT_41]], ptr @G, align 4
141; CHECK-NEXT:    [[CMP_42:%.*]] = icmp eq i32 0, [[LIMIT]]
142; CHECK-NEXT:    [[ZEXT_42:%.*]] = sext i1 [[CMP_42]] to i32
143; CHECK-NEXT:    store i32 [[ZEXT_42]], ptr @G, align 4
144; CHECK-NEXT:    [[CMP_43:%.*]] = icmp eq i32 0, [[LIMIT]]
145; CHECK-NEXT:    [[ZEXT_43:%.*]] = sext i1 [[CMP_43]] to i32
146; CHECK-NEXT:    store i32 [[ZEXT_43]], ptr @G, align 4
147; CHECK-NEXT:    [[CMP_44:%.*]] = icmp eq i32 0, [[LIMIT]]
148; CHECK-NEXT:    [[ZEXT_44:%.*]] = sext i1 [[CMP_44]] to i32
149; CHECK-NEXT:    store i32 [[ZEXT_44]], ptr @G, align 4
150; CHECK-NEXT:    [[CMP_45:%.*]] = icmp eq i32 0, [[LIMIT]]
151; CHECK-NEXT:    [[ZEXT_45:%.*]] = sext i1 [[CMP_45]] to i32
152; CHECK-NEXT:    store i32 [[ZEXT_45]], ptr @G, align 4
153; CHECK-NEXT:    [[CMP_46:%.*]] = icmp eq i32 0, [[LIMIT]]
154; CHECK-NEXT:    [[ZEXT_46:%.*]] = sext i1 [[CMP_46]] to i32
155; CHECK-NEXT:    store i32 [[ZEXT_46]], ptr @G, align 4
156; CHECK-NEXT:    [[CMP_47:%.*]] = icmp eq i32 0, [[LIMIT]]
157; CHECK-NEXT:    [[ZEXT_47:%.*]] = sext i1 [[CMP_47]] to i32
158; CHECK-NEXT:    store i32 [[ZEXT_47]], ptr @G, align 4
159; CHECK-NEXT:    [[CMP_48:%.*]] = icmp eq i32 0, [[LIMIT]]
160; CHECK-NEXT:    [[ZEXT_48:%.*]] = sext i1 [[CMP_48]] to i32
161; CHECK-NEXT:    store i32 [[ZEXT_48]], ptr @G, align 4
162; CHECK-NEXT:    [[CMP_49:%.*]] = icmp eq i32 0, [[LIMIT]]
163; CHECK-NEXT:    [[ZEXT_49:%.*]] = sext i1 [[CMP_49]] to i32
164; CHECK-NEXT:    store i32 [[ZEXT_49]], ptr @G, align 4
165; CHECK-NEXT:    [[CMP_50:%.*]] = icmp eq i32 0, [[LIMIT]]
166; CHECK-NEXT:    [[ZEXT_50:%.*]] = sext i1 [[CMP_50]] to i32
167; CHECK-NEXT:    store i32 [[ZEXT_50]], ptr @G, align 4
168; CHECK-NEXT:    [[CMP_51:%.*]] = icmp eq i32 0, [[LIMIT]]
169; CHECK-NEXT:    [[ZEXT_51:%.*]] = sext i1 [[CMP_51]] to i32
170; CHECK-NEXT:    store i32 [[ZEXT_51]], ptr @G, align 4
171; CHECK-NEXT:    [[CMP_52:%.*]] = icmp eq i32 0, [[LIMIT]]
172; CHECK-NEXT:    [[ZEXT_52:%.*]] = sext i1 [[CMP_52]] to i32
173; CHECK-NEXT:    store i32 [[ZEXT_52]], ptr @G, align 4
174; CHECK-NEXT:    [[CMP_53:%.*]] = icmp eq i32 0, [[LIMIT]]
175; CHECK-NEXT:    [[ZEXT_53:%.*]] = sext i1 [[CMP_53]] to i32
176; CHECK-NEXT:    store i32 [[ZEXT_53]], ptr @G, align 4
177; CHECK-NEXT:    [[CMP_54:%.*]] = icmp eq i32 0, [[LIMIT]]
178; CHECK-NEXT:    [[ZEXT_54:%.*]] = sext i1 [[CMP_54]] to i32
179; CHECK-NEXT:    store i32 [[ZEXT_54]], ptr @G, align 4
180; CHECK-NEXT:    [[CMP_55:%.*]] = icmp eq i32 0, [[LIMIT]]
181; CHECK-NEXT:    [[ZEXT_55:%.*]] = sext i1 [[CMP_55]] to i32
182; CHECK-NEXT:    store i32 [[ZEXT_55]], ptr @G, align 4
183; CHECK-NEXT:    [[CMP_56:%.*]] = icmp eq i32 0, [[LIMIT]]
184; CHECK-NEXT:    [[ZEXT_56:%.*]] = sext i1 [[CMP_56]] to i32
185; CHECK-NEXT:    store i32 [[ZEXT_56]], ptr @G, align 4
186; CHECK-NEXT:    [[CMP_57:%.*]] = icmp eq i32 0, [[LIMIT]]
187; CHECK-NEXT:    [[ZEXT_57:%.*]] = sext i1 [[CMP_57]] to i32
188; CHECK-NEXT:    store i32 [[ZEXT_57]], ptr @G, align 4
189; CHECK-NEXT:    [[CMP_58:%.*]] = icmp eq i32 0, [[LIMIT]]
190; CHECK-NEXT:    [[ZEXT_58:%.*]] = sext i1 [[CMP_58]] to i32
191; CHECK-NEXT:    store i32 [[ZEXT_58]], ptr @G, align 4
192; CHECK-NEXT:    [[CMP_59:%.*]] = icmp eq i32 0, [[LIMIT]]
193; CHECK-NEXT:    [[ZEXT_59:%.*]] = sext i1 [[CMP_59]] to i32
194; CHECK-NEXT:    store i32 [[ZEXT_59]], ptr @G, align 4
195; CHECK-NEXT:    [[CMP_60:%.*]] = icmp eq i32 0, [[LIMIT]]
196; CHECK-NEXT:    [[ZEXT_60:%.*]] = sext i1 [[CMP_60]] to i32
197; CHECK-NEXT:    store i32 [[ZEXT_60]], ptr @G, align 4
198; CHECK-NEXT:    [[CMP_61:%.*]] = icmp eq i32 0, [[LIMIT]]
199; CHECK-NEXT:    [[ZEXT_61:%.*]] = sext i1 [[CMP_61]] to i32
200; CHECK-NEXT:    store i32 [[ZEXT_61]], ptr @G, align 4
201; CHECK-NEXT:    [[CMP_62:%.*]] = icmp eq i32 0, [[LIMIT]]
202; CHECK-NEXT:    [[ZEXT_62:%.*]] = sext i1 [[CMP_62]] to i32
203; CHECK-NEXT:    store i32 [[ZEXT_62]], ptr @G, align 4
204; CHECK-NEXT:    [[CMP_63:%.*]] = icmp eq i32 0, [[LIMIT]]
205; CHECK-NEXT:    [[ZEXT_63:%.*]] = sext i1 [[CMP_63]] to i32
206; CHECK-NEXT:    store i32 [[ZEXT_63]], ptr @G, align 4
207; CHECK-NEXT:    [[CMP_64:%.*]] = icmp eq i32 0, [[LIMIT]]
208; CHECK-NEXT:    [[ZEXT_64:%.*]] = sext i1 [[CMP_64]] to i32
209; CHECK-NEXT:    store i32 [[ZEXT_64]], ptr @G, align 4
210; CHECK-NEXT:    [[CMP_65:%.*]] = icmp eq i32 0, [[LIMIT]]
211; CHECK-NEXT:    [[ZEXT_65:%.*]] = sext i1 [[CMP_65]] to i32
212; CHECK-NEXT:    store i32 [[ZEXT_65]], ptr @G, align 4
213; CHECK-NEXT:    [[CMP_66:%.*]] = icmp eq i32 0, [[LIMIT]]
214; CHECK-NEXT:    [[ZEXT_66:%.*]] = sext i1 [[CMP_66]] to i32
215; CHECK-NEXT:    store i32 [[ZEXT_66]], ptr @G, align 4
216; CHECK-NEXT:    [[CMP_67:%.*]] = icmp eq i32 0, [[LIMIT]]
217; CHECK-NEXT:    [[ZEXT_67:%.*]] = sext i1 [[CMP_67]] to i32
218; CHECK-NEXT:    store i32 [[ZEXT_67]], ptr @G, align 4
219; CHECK-NEXT:    [[CMP_68:%.*]] = icmp eq i32 0, [[LIMIT]]
220; CHECK-NEXT:    [[ZEXT_68:%.*]] = sext i1 [[CMP_68]] to i32
221; CHECK-NEXT:    store i32 [[ZEXT_68]], ptr @G, align 4
222; CHECK-NEXT:    [[CMP_69:%.*]] = icmp eq i32 0, [[LIMIT]]
223; CHECK-NEXT:    [[ZEXT_69:%.*]] = sext i1 [[CMP_69]] to i32
224; CHECK-NEXT:    store i32 [[ZEXT_69]], ptr @G, align 4
225; CHECK-NEXT:    [[CMP_70:%.*]] = icmp eq i32 0, [[LIMIT]]
226; CHECK-NEXT:    [[ZEXT_70:%.*]] = sext i1 [[CMP_70]] to i32
227; CHECK-NEXT:    store i32 [[ZEXT_70]], ptr @G, align 4
228; CHECK-NEXT:    [[CMP_71:%.*]] = icmp eq i32 0, [[LIMIT]]
229; CHECK-NEXT:    [[ZEXT_71:%.*]] = sext i1 [[CMP_71]] to i32
230; CHECK-NEXT:    store i32 [[ZEXT_71]], ptr @G, align 4
231; CHECK-NEXT:    [[CMP_72:%.*]] = icmp eq i32 0, [[LIMIT]]
232; CHECK-NEXT:    [[ZEXT_72:%.*]] = sext i1 [[CMP_72]] to i32
233; CHECK-NEXT:    store i32 [[ZEXT_72]], ptr @G, align 4
234; CHECK-NEXT:    [[CMP_73:%.*]] = icmp eq i32 0, [[LIMIT]]
235; CHECK-NEXT:    [[ZEXT_73:%.*]] = sext i1 [[CMP_73]] to i32
236; CHECK-NEXT:    store i32 [[ZEXT_73]], ptr @G, align 4
237; CHECK-NEXT:    [[CMP_74:%.*]] = icmp eq i32 0, [[LIMIT]]
238; CHECK-NEXT:    [[ZEXT_74:%.*]] = sext i1 [[CMP_74]] to i32
239; CHECK-NEXT:    store i32 [[ZEXT_74]], ptr @G, align 4
240; CHECK-NEXT:    [[CMP_75:%.*]] = icmp eq i32 0, [[LIMIT]]
241; CHECK-NEXT:    [[ZEXT_75:%.*]] = sext i1 [[CMP_75]] to i32
242; CHECK-NEXT:    store i32 [[ZEXT_75]], ptr @G, align 4
243; CHECK-NEXT:    [[CMP_76:%.*]] = icmp eq i32 0, [[LIMIT]]
244; CHECK-NEXT:    [[ZEXT_76:%.*]] = sext i1 [[CMP_76]] to i32
245; CHECK-NEXT:    store i32 [[ZEXT_76]], ptr @G, align 4
246; CHECK-NEXT:    [[CMP_77:%.*]] = icmp eq i32 0, [[LIMIT]]
247; CHECK-NEXT:    [[ZEXT_77:%.*]] = sext i1 [[CMP_77]] to i32
248; CHECK-NEXT:    store i32 [[ZEXT_77]], ptr @G, align 4
249; CHECK-NEXT:    [[CMP_78:%.*]] = icmp eq i32 0, [[LIMIT]]
250; CHECK-NEXT:    [[ZEXT_78:%.*]] = sext i1 [[CMP_78]] to i32
251; CHECK-NEXT:    store i32 [[ZEXT_78]], ptr @G, align 4
252; CHECK-NEXT:    [[CMP_79:%.*]] = icmp eq i32 0, [[LIMIT]]
253; CHECK-NEXT:    [[ZEXT_79:%.*]] = sext i1 [[CMP_79]] to i32
254; CHECK-NEXT:    store i32 [[ZEXT_79]], ptr @G, align 4
255; CHECK-NEXT:    [[CMP_80:%.*]] = icmp eq i32 0, [[LIMIT]]
256; CHECK-NEXT:    [[ZEXT_80:%.*]] = sext i1 [[CMP_80]] to i32
257; CHECK-NEXT:    store i32 [[ZEXT_80]], ptr @G, align 4
258; CHECK-NEXT:    ret i32 [[ZEXT_80]]
259;
260entry:
261  br label %loop
262
263loop:                                             ; preds = %backedge, %entry
264  %phi = phi i32 [ 0, %entry ], [ %limit, %loop ]
265  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
266  %sub = sub i32 %limit, %phi
267  %cmp = icmp eq i32 %sub, %limit
268  %zext = sext i1 %cmp to i32
269  store i32 %zext, ptr @G
270  %iv.next = add i32 %iv, 1
271  %loop.cond = icmp ne i32 %iv, 80
272  br i1 %loop.cond, label %loop, label %done
273
274done:                                             ; preds = %backedge
275  ret i32 %zext
276}
277
278; Use symbolic value facts to prune unreachable (expensive) paths
279; through the loop.
280define i32 @test_symbolic_path(i32 %limit) {
281; CHECK-LABEL: @test_symbolic_path(
282; CHECK-NEXT:  entry:
283; CHECK-NEXT:    br label [[LOOP:%.*]]
284; CHECK:       loop:
285; CHECK-NEXT:    br i1 true, label [[BACKEDGE:%.*]], label [[IF_FALSE:%.*]]
286; CHECK:       if.false:
287; CHECK-NEXT:    call void @foo()
288; CHECK-NEXT:    call void @foo()
289; CHECK-NEXT:    call void @foo()
290; CHECK-NEXT:    call void @foo()
291; CHECK-NEXT:    call void @foo()
292; CHECK-NEXT:    call void @foo()
293; CHECK-NEXT:    call void @foo()
294; CHECK-NEXT:    call void @foo()
295; CHECK-NEXT:    call void @foo()
296; CHECK-NEXT:    call void @foo()
297; CHECK-NEXT:    call void @foo()
298; CHECK-NEXT:    call void @foo()
299; CHECK-NEXT:    call void @foo()
300; CHECK-NEXT:    call void @foo()
301; CHECK-NEXT:    br label [[BACKEDGE]]
302; CHECK:       backedge:
303; CHECK-NEXT:    br i1 true, label [[BACKEDGE_1:%.*]], label [[IF_FALSE_1:%.*]]
304; CHECK:       if.false.1:
305; CHECK-NEXT:    call void @foo()
306; CHECK-NEXT:    call void @foo()
307; CHECK-NEXT:    call void @foo()
308; CHECK-NEXT:    call void @foo()
309; CHECK-NEXT:    call void @foo()
310; CHECK-NEXT:    call void @foo()
311; CHECK-NEXT:    call void @foo()
312; CHECK-NEXT:    call void @foo()
313; CHECK-NEXT:    call void @foo()
314; CHECK-NEXT:    call void @foo()
315; CHECK-NEXT:    call void @foo()
316; CHECK-NEXT:    call void @foo()
317; CHECK-NEXT:    call void @foo()
318; CHECK-NEXT:    call void @foo()
319; CHECK-NEXT:    br label [[BACKEDGE_1]]
320; CHECK:       backedge.1:
321; CHECK-NEXT:    br i1 true, label [[BACKEDGE_2:%.*]], label [[IF_FALSE_2:%.*]]
322; CHECK:       if.false.2:
323; CHECK-NEXT:    call void @foo()
324; CHECK-NEXT:    call void @foo()
325; CHECK-NEXT:    call void @foo()
326; CHECK-NEXT:    call void @foo()
327; CHECK-NEXT:    call void @foo()
328; CHECK-NEXT:    call void @foo()
329; CHECK-NEXT:    call void @foo()
330; CHECK-NEXT:    call void @foo()
331; CHECK-NEXT:    call void @foo()
332; CHECK-NEXT:    call void @foo()
333; CHECK-NEXT:    call void @foo()
334; CHECK-NEXT:    call void @foo()
335; CHECK-NEXT:    call void @foo()
336; CHECK-NEXT:    call void @foo()
337; CHECK-NEXT:    br label [[BACKEDGE_2]]
338; CHECK:       backedge.2:
339; CHECK-NEXT:    br i1 true, label [[BACKEDGE_3:%.*]], label [[IF_FALSE_3:%.*]]
340; CHECK:       if.false.3:
341; CHECK-NEXT:    call void @foo()
342; CHECK-NEXT:    call void @foo()
343; CHECK-NEXT:    call void @foo()
344; CHECK-NEXT:    call void @foo()
345; CHECK-NEXT:    call void @foo()
346; CHECK-NEXT:    call void @foo()
347; CHECK-NEXT:    call void @foo()
348; CHECK-NEXT:    call void @foo()
349; CHECK-NEXT:    call void @foo()
350; CHECK-NEXT:    call void @foo()
351; CHECK-NEXT:    call void @foo()
352; CHECK-NEXT:    call void @foo()
353; CHECK-NEXT:    call void @foo()
354; CHECK-NEXT:    call void @foo()
355; CHECK-NEXT:    br label [[BACKEDGE_3]]
356; CHECK:       backedge.3:
357; CHECK-NEXT:    br i1 true, label [[BACKEDGE_4:%.*]], label [[IF_FALSE_4:%.*]]
358; CHECK:       if.false.4:
359; CHECK-NEXT:    call void @foo()
360; CHECK-NEXT:    call void @foo()
361; CHECK-NEXT:    call void @foo()
362; CHECK-NEXT:    call void @foo()
363; CHECK-NEXT:    call void @foo()
364; CHECK-NEXT:    call void @foo()
365; CHECK-NEXT:    call void @foo()
366; CHECK-NEXT:    call void @foo()
367; CHECK-NEXT:    call void @foo()
368; CHECK-NEXT:    call void @foo()
369; CHECK-NEXT:    call void @foo()
370; CHECK-NEXT:    call void @foo()
371; CHECK-NEXT:    call void @foo()
372; CHECK-NEXT:    call void @foo()
373; CHECK-NEXT:    br label [[BACKEDGE_4]]
374; CHECK:       backedge.4:
375; CHECK-NEXT:    br i1 true, label [[BACKEDGE_5:%.*]], label [[IF_FALSE_5:%.*]]
376; CHECK:       if.false.5:
377; CHECK-NEXT:    call void @foo()
378; CHECK-NEXT:    call void @foo()
379; CHECK-NEXT:    call void @foo()
380; CHECK-NEXT:    call void @foo()
381; CHECK-NEXT:    call void @foo()
382; CHECK-NEXT:    call void @foo()
383; CHECK-NEXT:    call void @foo()
384; CHECK-NEXT:    call void @foo()
385; CHECK-NEXT:    call void @foo()
386; CHECK-NEXT:    call void @foo()
387; CHECK-NEXT:    call void @foo()
388; CHECK-NEXT:    call void @foo()
389; CHECK-NEXT:    call void @foo()
390; CHECK-NEXT:    call void @foo()
391; CHECK-NEXT:    br label [[BACKEDGE_5]]
392; CHECK:       backedge.5:
393; CHECK-NEXT:    br i1 true, label [[BACKEDGE_6:%.*]], label [[IF_FALSE_6:%.*]]
394; CHECK:       if.false.6:
395; CHECK-NEXT:    call void @foo()
396; CHECK-NEXT:    call void @foo()
397; CHECK-NEXT:    call void @foo()
398; CHECK-NEXT:    call void @foo()
399; CHECK-NEXT:    call void @foo()
400; CHECK-NEXT:    call void @foo()
401; CHECK-NEXT:    call void @foo()
402; CHECK-NEXT:    call void @foo()
403; CHECK-NEXT:    call void @foo()
404; CHECK-NEXT:    call void @foo()
405; CHECK-NEXT:    call void @foo()
406; CHECK-NEXT:    call void @foo()
407; CHECK-NEXT:    call void @foo()
408; CHECK-NEXT:    call void @foo()
409; CHECK-NEXT:    br label [[BACKEDGE_6]]
410; CHECK:       backedge.6:
411; CHECK-NEXT:    br i1 true, label [[BACKEDGE_7:%.*]], label [[IF_FALSE_7:%.*]]
412; CHECK:       if.false.7:
413; CHECK-NEXT:    call void @foo()
414; CHECK-NEXT:    call void @foo()
415; CHECK-NEXT:    call void @foo()
416; CHECK-NEXT:    call void @foo()
417; CHECK-NEXT:    call void @foo()
418; CHECK-NEXT:    call void @foo()
419; CHECK-NEXT:    call void @foo()
420; CHECK-NEXT:    call void @foo()
421; CHECK-NEXT:    call void @foo()
422; CHECK-NEXT:    call void @foo()
423; CHECK-NEXT:    call void @foo()
424; CHECK-NEXT:    call void @foo()
425; CHECK-NEXT:    call void @foo()
426; CHECK-NEXT:    call void @foo()
427; CHECK-NEXT:    br label [[BACKEDGE_7]]
428; CHECK:       backedge.7:
429; CHECK-NEXT:    br i1 true, label [[BACKEDGE_8:%.*]], label [[IF_FALSE_8:%.*]]
430; CHECK:       if.false.8:
431; CHECK-NEXT:    call void @foo()
432; CHECK-NEXT:    call void @foo()
433; CHECK-NEXT:    call void @foo()
434; CHECK-NEXT:    call void @foo()
435; CHECK-NEXT:    call void @foo()
436; CHECK-NEXT:    call void @foo()
437; CHECK-NEXT:    call void @foo()
438; CHECK-NEXT:    call void @foo()
439; CHECK-NEXT:    call void @foo()
440; CHECK-NEXT:    call void @foo()
441; CHECK-NEXT:    call void @foo()
442; CHECK-NEXT:    call void @foo()
443; CHECK-NEXT:    call void @foo()
444; CHECK-NEXT:    call void @foo()
445; CHECK-NEXT:    br label [[BACKEDGE_8]]
446; CHECK:       backedge.8:
447; CHECK-NEXT:    ret i32 0
448;
449entry:
450  br label %loop
451
452loop:                                             ; preds = %backedge, %entry
453  %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ]
454  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
455  %sub = sub i32 %limit, %sum
456  %is.positive = icmp eq i32 %sub, %limit
457  br i1 %is.positive, label %backedge, label %if.false
458
459if.false:                                         ; preds = %loop
460  call void @foo()
461  call void @foo()
462  call void @foo()
463  call void @foo()
464  call void @foo()
465  call void @foo()
466  call void @foo()
467  call void @foo()
468  call void @foo()
469  call void @foo()
470  call void @foo()
471  call void @foo()
472  call void @foo()
473  call void @foo()
474  br label %backedge
475
476backedge:                                         ; preds = %if.false, %loop
477  %hidden_zero = sub i32 %limit, %sub
478  %sum.next = add i32 %sum, %hidden_zero
479  %iv.next = add i32 %iv, 1
480  %loop.cond = icmp ne i32 %iv, 8
481  br i1 %loop.cond, label %loop, label %done
482
483done:                                             ; preds = %backedge
484  %sum.next.lcssa = phi i32 [ %sum.next, %backedge ]
485  ret i32 %sum.next.lcssa
486}
487
488; A test to show the ability to simplify branches (even without general
489; symbolic execution of the loop beyond constants) is still useful.
490define i32 @test_dom_condition(i32 %limit) {
491; CHECK-LABEL: @test_dom_condition(
492; CHECK-NEXT:  entry:
493; CHECK-NEXT:    [[LOOP_GUARD:%.*]] = icmp sge i32 [[LIMIT:%.*]], 0
494; CHECK-NEXT:    br i1 [[LOOP_GUARD]], label [[LOOP_PREHEADER:%.*]], label [[FAILURE:%.*]]
495; CHECK:       loop.preheader:
496; CHECK-NEXT:    br label [[LOOP:%.*]]
497; CHECK:       loop:
498; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ [[SUM_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
499; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE]] ], [ 0, [[LOOP_PREHEADER]] ]
500; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[SUM]]
501; CHECK-NEXT:    [[IS_POSITIVE:%.*]] = icmp sle i32 [[SUB]], [[LIMIT]]
502; CHECK-NEXT:    br i1 [[IS_POSITIVE]], label [[BACKEDGE]], label [[IF_FALSE:%.*]]
503; CHECK:       if.false:
504; CHECK-NEXT:    call void @foo()
505; CHECK-NEXT:    call void @foo()
506; CHECK-NEXT:    call void @foo()
507; CHECK-NEXT:    call void @foo()
508; CHECK-NEXT:    call void @foo()
509; CHECK-NEXT:    call void @foo()
510; CHECK-NEXT:    call void @foo()
511; CHECK-NEXT:    call void @foo()
512; CHECK-NEXT:    call void @foo()
513; CHECK-NEXT:    call void @foo()
514; CHECK-NEXT:    call void @foo()
515; CHECK-NEXT:    call void @foo()
516; CHECK-NEXT:    call void @foo()
517; CHECK-NEXT:    call void @foo()
518; CHECK-NEXT:    br label [[BACKEDGE]]
519; CHECK:       backedge:
520; CHECK-NEXT:    [[SUM_NEXT]] = add i32 [[SUM]], [[SUB]]
521; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
522; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 8
523; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]]
524; CHECK:       done:
525; CHECK-NEXT:    [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[BACKEDGE]] ]
526; CHECK-NEXT:    ret i32 [[SUM_NEXT_LCSSA]]
527; CHECK:       failure:
528; CHECK-NEXT:    unreachable
529;
530entry:
531  %loop_guard = icmp sge i32 %limit, 0
532  br i1 %loop_guard, label %loop, label %failure
533
534loop:                                             ; preds = %backedge, %entry
535  %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ]
536  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
537  %sub = sub i32 0, %sum
538  %is.positive = icmp sle i32 %sub, %limit
539  br i1 %is.positive, label %backedge, label %if.false
540
541if.false:                                         ; preds = %loop
542  call void @foo()
543  call void @foo()
544  call void @foo()
545  call void @foo()
546  call void @foo()
547  call void @foo()
548  call void @foo()
549  call void @foo()
550  call void @foo()
551  call void @foo()
552  call void @foo()
553  call void @foo()
554  call void @foo()
555  call void @foo()
556  br label %backedge
557
558backedge:                                         ; preds = %if.false, %loop
559  %sum.next = add i32 %sum, %sub
560  %iv.next = add i32 %iv, 1
561  %loop.cond = icmp ne i32 %iv, 8
562  br i1 %loop.cond, label %loop, label %done
563
564done:                                             ; preds = %backedge
565  %sum.next.lcssa = phi i32 [ %sum.next, %backedge ]
566  ret i32 %sum.next.lcssa
567
568failure:
569  unreachable
570}
571
572; We can symbolically evaluate %sub to %limit on first iteration, and
573; to zero on all future iterations.
574define i32 @test_both(i32 %limit) {
575; CHECK-LABEL: @test_both(
576; CHECK-NEXT:  entry:
577; CHECK-NEXT:    [[LOOP_GUARD:%.*]] = icmp sge i32 [[LIMIT:%.*]], 0
578; CHECK-NEXT:    br i1 [[LOOP_GUARD]], label [[LOOP_PREHEADER:%.*]], label [[FAILURE:%.*]]
579; CHECK:       loop.preheader:
580; CHECK-NEXT:    br label [[LOOP:%.*]]
581; CHECK:       loop:
582; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ [[SUM_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
583; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE]] ], [ 0, [[LOOP_PREHEADER]] ]
584; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[LIMIT]], [[SUM]]
585; CHECK-NEXT:    [[IS_POSITIVE:%.*]] = icmp sge i32 [[SUB]], 0
586; CHECK-NEXT:    br i1 [[IS_POSITIVE]], label [[BACKEDGE]], label [[IF_FALSE:%.*]]
587; CHECK:       if.false:
588; CHECK-NEXT:    call void @foo()
589; CHECK-NEXT:    call void @foo()
590; CHECK-NEXT:    call void @foo()
591; CHECK-NEXT:    call void @foo()
592; CHECK-NEXT:    call void @foo()
593; CHECK-NEXT:    call void @foo()
594; CHECK-NEXT:    call void @foo()
595; CHECK-NEXT:    call void @foo()
596; CHECK-NEXT:    call void @foo()
597; CHECK-NEXT:    call void @foo()
598; CHECK-NEXT:    call void @foo()
599; CHECK-NEXT:    call void @foo()
600; CHECK-NEXT:    call void @foo()
601; CHECK-NEXT:    call void @foo()
602; CHECK-NEXT:    br label [[BACKEDGE]]
603; CHECK:       backedge:
604; CHECK-NEXT:    [[SUM_NEXT]] = add i32 [[SUM]], [[SUB]]
605; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
606; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 8
607; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]]
608; CHECK:       done:
609; CHECK-NEXT:    [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[BACKEDGE]] ]
610; CHECK-NEXT:    ret i32 [[SUM_NEXT_LCSSA]]
611; CHECK:       failure:
612; CHECK-NEXT:    unreachable
613;
614entry:
615  %loop_guard = icmp sge i32 %limit, 0
616  br i1 %loop_guard, label %loop, label %failure
617
618loop:                                             ; preds = %backedge, %entry
619  %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ]
620  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
621  %sub = sub i32 %limit, %sum
622  %is.positive = icmp sge i32 %sub, 0
623  br i1 %is.positive, label %backedge, label %if.false
624
625if.false:                                         ; preds = %loop
626  call void @foo()
627  call void @foo()
628  call void @foo()
629  call void @foo()
630  call void @foo()
631  call void @foo()
632  call void @foo()
633  call void @foo()
634  call void @foo()
635  call void @foo()
636  call void @foo()
637  call void @foo()
638  call void @foo()
639  call void @foo()
640  br label %backedge
641
642backedge:                                         ; preds = %if.false, %loop
643  %sum.next = add i32 %sum, %sub
644  %iv.next = add i32 %iv, 1
645  %loop.cond = icmp ne i32 %iv, 8
646  br i1 %loop.cond, label %loop, label %done
647
648done:                                             ; preds = %backedge
649  %sum.next.lcssa = phi i32 [ %sum.next, %backedge ]
650  ret i32 %sum.next.lcssa
651
652failure:
653  unreachable
654}
655
656declare void @foo()
657