[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / IRCE / correct-loop-info.ll
blob0141b37acdd0204d6603554e06665db5ee8ab976
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -irce < %s -S | FileCheck %s
3 ; RUN: opt -passes='require<branch-prob>,loop(irce)' < %s -S | FileCheck %s
5 ; REQUIRES: asserts
7 ; IRCE creates the pre and post loop, and invokes the
8 ; canonicalizing these loops to LCSSA and loop-simplfy structure. Make sure that the update to the loopinfo does not
9 ; incorrectly change the header while canonicalizing these pre/post loops. We
10 ; were incorrectly updating LI when the split loop is a subloop as in the case below.
11 source_filename = "correct-loop-info.ll"
13 define void @baz() personality i32* ()* @ham {
14 ; CHECK-LABEL: @baz(
15 ; CHECK-NEXT:  bb:
16 ; CHECK-NEXT:    br label [[OUTERHEADER:%.*]]
17 ; CHECK:       outerheader:
18 ; CHECK-NEXT:    [[TMP:%.*]] = icmp slt i32 undef, 84
19 ; CHECK-NEXT:    br i1 [[TMP]], label [[BB2:%.*]], label [[BB16:%.*]]
20 ; CHECK:       bb2:
21 ; CHECK-NEXT:    br i1 false, label [[INNERHEADER_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
22 ; CHECK:       innerheader.preloop.preheader:
23 ; CHECK-NEXT:    br label [[INNERHEADER_PRELOOP:%.*]]
24 ; CHECK:       mainloop:
25 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[INDVAR_END:%.*]], 0
26 ; CHECK-NEXT:    br i1 [[TMP0]], label [[INNERHEADER_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
27 ; CHECK:       innerheader.preheader:
28 ; CHECK-NEXT:    br label [[INNERHEADER:%.*]]
29 ; CHECK:       innerheader:
30 ; CHECK-NEXT:    [[TMP4:%.*]] = phi i32 [ [[TMP6:%.*]], [[BB8:%.*]] ], [ [[TMP4_PRELOOP_COPY:%.*]], [[INNERHEADER_PREHEADER]] ]
31 ; CHECK-NEXT:    invoke void @pluto()
32 ; CHECK-NEXT:    to label [[BB5:%.*]] unwind label %outer_exiting.loopexit.split-lp.loopexit.split-lp
33 ; CHECK:       bb5:
34 ; CHECK-NEXT:    [[TMP6]] = add i32 [[TMP4]], 1
35 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt i32 [[TMP6]], 1
36 ; CHECK-NEXT:    br i1 true, label [[BB8]], label [[EXIT3_LOOPEXIT5:%.*]]
37 ; CHECK:       bb8:
38 ; CHECK-NEXT:    [[TMP9:%.*]] = icmp slt i32 [[TMP6]], 84
39 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[TMP6]], 0
40 ; CHECK-NEXT:    br i1 [[TMP1]], label [[INNERHEADER]], label [[MAIN_EXIT_SELECTOR:%.*]]
41 ; CHECK:       main.exit.selector:
42 ; CHECK-NEXT:    [[TMP6_LCSSA:%.*]] = phi i32 [ [[TMP6]], [[BB8]] ]
43 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP6_LCSSA]], 84
44 ; CHECK-NEXT:    br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[BB13:%.*]]
45 ; CHECK:       main.pseudo.exit:
46 ; CHECK-NEXT:    [[TMP4_COPY:%.*]] = phi i32 [ [[TMP4_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[TMP6_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
47 ; CHECK-NEXT:    [[INDVAR_END1:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[TMP6_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
48 ; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
49 ; CHECK:       outer_exiting.loopexit:
50 ; CHECK-NEXT:    [[LPAD_LOOPEXIT:%.*]] = landingpad { i8*, i32 }
51 ; CHECK-NEXT:    cleanup
52 ; CHECK-NEXT:    br label [[OUTER_EXITING:%.*]]
53 ; CHECK:       outer_exiting.loopexit.split-lp.loopexit:
54 ; CHECK-NEXT:    [[LPAD_LOOPEXIT2:%.*]] = landingpad { i8*, i32 }
55 ; CHECK-NEXT:    cleanup
56 ; CHECK-NEXT:    br label %outer_exiting.loopexit.split-lp
57 ; CHECK:       outer_exiting.loopexit.split-lp.loopexit.split-lp:
58 ; CHECK-NEXT:    %lpad.loopexit.split-lp3 = landingpad { i8*, i32 }
59 ; CHECK-NEXT:    cleanup
60 ; CHECK-NEXT:    br label %outer_exiting.loopexit.split-lp
61 ; CHECK:       outer_exiting.loopexit.split-lp:
62 ; CHECK-NEXT:    br label [[OUTER_EXITING]]
63 ; CHECK:       outer_exiting:
64 ; CHECK-NEXT:    switch i32 undef, label [[EXIT2:%.*]] [
65 ; CHECK-NEXT:    i32 142, label [[BB14:%.*]]
66 ; CHECK-NEXT:    i32 448, label [[EXIT:%.*]]
67 ; CHECK-NEXT:    ]
68 ; CHECK:       exit3.loopexit:
69 ; CHECK-NEXT:    br label [[EXIT3:%.*]]
70 ; CHECK:       exit3.loopexit4:
71 ; CHECK-NEXT:    br label [[EXIT3]]
72 ; CHECK:       exit3.loopexit5:
73 ; CHECK-NEXT:    br label [[EXIT3]]
74 ; CHECK:       exit3:
75 ; CHECK-NEXT:    ret void
76 ; CHECK:       bb13.loopexit:
77 ; CHECK-NEXT:    br label [[BB13]]
78 ; CHECK:       bb13:
79 ; CHECK-NEXT:    unreachable
80 ; CHECK:       bb14:
81 ; CHECK-NEXT:    br label [[OUTERHEADER]]
82 ; CHECK:       exit:
83 ; CHECK-NEXT:    ret void
84 ; CHECK:       bb16:
85 ; CHECK-NEXT:    ret void
86 ; CHECK:       exit2:
87 ; CHECK-NEXT:    ret void
88 ; CHECK:       innerheader.preloop:
89 ; CHECK-NEXT:    [[TMP4_PRELOOP:%.*]] = phi i32 [ [[TMP6_PRELOOP:%.*]], [[BB8_PRELOOP:%.*]] ], [ undef, [[INNERHEADER_PRELOOP_PREHEADER]] ]
90 ; CHECK-NEXT:    invoke void @pluto()
91 ; CHECK-NEXT:    to label [[BB5_PRELOOP:%.*]] unwind label [[OUTER_EXITING_LOOPEXIT:%.*]]
92 ; CHECK:       bb5.preloop:
93 ; CHECK-NEXT:    [[TMP6_PRELOOP]] = add i32 [[TMP4_PRELOOP]], 1
94 ; CHECK-NEXT:    [[TMP7_PRELOOP:%.*]] = icmp slt i32 [[TMP6_PRELOOP]], 1
95 ; CHECK-NEXT:    br i1 [[TMP7_PRELOOP]], label [[BB8_PRELOOP]], label [[EXIT3_LOOPEXIT:%.*]]
96 ; CHECK:       bb8.preloop:
97 ; CHECK-NEXT:    [[TMP9_PRELOOP:%.*]] = icmp slt i32 [[TMP6_PRELOOP]], 84
98 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP6_PRELOOP]], -1
99 ; CHECK-NEXT:    br i1 [[TMP3]], label [[INNERHEADER_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop !0, !irce.loop.clone !5
100 ; CHECK:       preloop.exit.selector:
101 ; CHECK-NEXT:    [[TMP6_PRELOOP_LCSSA:%.*]] = phi i32 [ [[TMP6_PRELOOP]], [[BB8_PRELOOP]] ]
102 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp slt i32 [[TMP6_PRELOOP_LCSSA]], 84
103 ; CHECK-NEXT:    br i1 [[TMP4]], label [[PRELOOP_PSEUDO_EXIT]], label [[BB13]]
104 ; CHECK:       preloop.pseudo.exit:
105 ; CHECK-NEXT:    [[TMP4_PRELOOP_COPY]] = phi i32 [ undef, [[BB2]] ], [ [[TMP6_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
106 ; CHECK-NEXT:    [[INDVAR_END]] = phi i32 [ undef, [[BB2]] ], [ [[TMP6_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
107 ; CHECK-NEXT:    br label [[MAINLOOP]]
108 ; CHECK:       postloop:
109 ; CHECK-NEXT:    br label [[INNERHEADER_POSTLOOP:%.*]]
110 ; CHECK:       innerheader.postloop:
111 ; CHECK-NEXT:    [[TMP4_POSTLOOP:%.*]] = phi i32 [ [[TMP6_POSTLOOP:%.*]], [[BB8_POSTLOOP:%.*]] ], [ [[TMP4_COPY]], [[POSTLOOP]] ]
112 ; CHECK-NEXT:    invoke void @pluto()
113 ; CHECK-NEXT:    to label [[BB5_POSTLOOP:%.*]] unwind label %outer_exiting.loopexit.split-lp.loopexit
114 ; CHECK:       bb5.postloop:
115 ; CHECK-NEXT:    [[TMP6_POSTLOOP]] = add i32 [[TMP4_POSTLOOP]], 1
116 ; CHECK-NEXT:    [[TMP7_POSTLOOP:%.*]] = icmp slt i32 [[TMP6_POSTLOOP]], 1
117 ; CHECK-NEXT:    br i1 [[TMP7_POSTLOOP]], label [[BB8_POSTLOOP]], label [[EXIT3_LOOPEXIT4:%.*]]
118 ; CHECK:       bb8.postloop:
119 ; CHECK-NEXT:    [[TMP9_POSTLOOP:%.*]] = icmp slt i32 [[TMP6_POSTLOOP]], 84
120 ; CHECK-NEXT:    br i1 [[TMP9_POSTLOOP]], label [[INNERHEADER_POSTLOOP]], label [[BB13_LOOPEXIT:%.*]], !llvm.loop !6, !irce.loop.clone !5
123   br label %outerheader
125 outerheader:                                              ; preds = %bb14, %bb
126   %tmp = icmp slt i32 undef, 84
127   br i1 %tmp, label %bb2, label %bb16
129 bb2:                                              ; preds = %outerheader
130   br label %innerheader
132 innerheader:                                              ; preds = %bb8, %bb2
133   %tmp4 = phi i32 [ %tmp6, %bb8 ], [ undef, %bb2 ]
134   invoke void @pluto()
135   to label %bb5 unwind label %outer_exiting
137 bb5:                                              ; preds = %innerheader
138   %tmp6 = add i32 %tmp4, 1
139   %tmp7 = icmp slt i32 %tmp6, 1
140   br i1 %tmp7, label %bb8, label %exit3
142 bb8:                                              ; preds = %bb5
143   %tmp9 = icmp slt i32 %tmp6, 84
144   br i1 %tmp9, label %innerheader, label %bb13
146 outer_exiting:                                             ; preds = %innerheader
147   %tmp11 = landingpad { i8*, i32 }
148   cleanup
149   switch i32 undef, label %exit2 [
150   i32 142, label %bb14
151   i32 448, label %exit
152   ]
154 exit3:                                             ; preds = %bb5
155   ret void
157 bb13:                                             ; preds = %bb8
158   unreachable
160 bb14:                                             ; preds = %outer_exiting
161   br label %outerheader
163 exit:                                             ; preds = %outer_exiting
164   ret void
166 bb16:                                             ; preds = %outerheader
167   ret void
169 exit2:                                             ; preds = %outer_exiting
170   ret void
173 declare i32* @ham()
175 declare void @pluto()
177 !0 = distinct !{!0, !1, !2, !3, !4}
178 !1 = !{!"llvm.loop.unroll.disable"}
179 !2 = !{!"llvm.loop.vectorize.enable", i1 false}
180 !3 = !{!"llvm.loop.licm_versioning.disable"}
181 !4 = !{!"llvm.loop.distribute.enable", i1 false}
182 !5 = !{}
183 !6 = distinct !{!6, !1, !2, !3, !4}