1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -sccp -S < %s | FileCheck %s
3
4
5; PR6940
6define double @test1() {
7; CHECK-LABEL: @test1(
8; CHECK-NEXT:    [[T:%.*]] = sitofp i32 undef to double
9; CHECK-NEXT:    ret double [[T]]
10;
11  %t = sitofp i32 undef to double
12  ret double %t
13}
14
15
16; rdar://7832370
17; Check that lots of stuff doesn't get turned into undef.
18define i32 @test2() nounwind readnone ssp {
19; CHECK-LABEL: @test2(
20; CHECK-NEXT:  init:
21; CHECK-NEXT:    br label [[CONTROL_OUTER_OUTER:%.*]]
22; CHECK:       control.outer.loopexit.us-lcssa:
23; CHECK-NEXT:    br label [[CONTROL_OUTER_LOOPEXIT:%.*]]
24; CHECK:       control.outer.loopexit:
25; CHECK-NEXT:    br label [[CONTROL_OUTER_OUTER_BACKEDGE:%.*]]
26; CHECK:       control.outer.outer:
27; CHECK-NEXT:    [[SWITCHCOND_0_PH_PH:%.*]] = phi i32 [ 2, [[INIT:%.*]] ], [ 3, [[CONTROL_OUTER_OUTER_BACKEDGE]] ]
28; CHECK-NEXT:    [[I_0_PH_PH:%.*]] = phi i32 [ undef, [[INIT]] ], [ [[I_0_PH_PH_BE:%.*]], [[CONTROL_OUTER_OUTER_BACKEDGE]] ]
29; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[I_0_PH_PH]], 0
30; CHECK-NEXT:    br i1 [[TMP4]], label [[CONTROL_OUTER_OUTER_SPLIT_US:%.*]], label [[CONTROL_OUTER_OUTER_CONTROL_OUTER_OUTER_SPLIT_CRIT_EDGE:%.*]]
31; CHECK:       control.outer.outer.control.outer.outer.split_crit_edge:
32; CHECK-NEXT:    br label [[CONTROL_OUTER:%.*]]
33; CHECK:       control.outer.outer.split.us:
34; CHECK-NEXT:    br label [[CONTROL_OUTER_US:%.*]]
35; CHECK:       control.outer.us:
36; CHECK-NEXT:    [[A_0_PH_US:%.*]] = phi i32 [ [[SWITCHCOND_0_US:%.*]], [[BB3_US:%.*]] ], [ 4, [[CONTROL_OUTER_OUTER_SPLIT_US]] ]
37; CHECK-NEXT:    [[SWITCHCOND_0_PH_US:%.*]] = phi i32 [ [[A_0_PH_US]], [[BB3_US]] ], [ [[SWITCHCOND_0_PH_PH]], [[CONTROL_OUTER_OUTER_SPLIT_US]] ]
38; CHECK-NEXT:    br label [[CONTROL_US:%.*]]
39; CHECK:       bb3.us:
40; CHECK-NEXT:    br label [[CONTROL_OUTER_US]]
41; CHECK:       bb0.us:
42; CHECK-NEXT:    br label [[CONTROL_US]]
43; CHECK:       control.us:
44; CHECK-NEXT:    [[SWITCHCOND_0_US]] = phi i32 [ [[A_0_PH_US]], [[BB0_US:%.*]] ], [ [[SWITCHCOND_0_PH_US]], [[CONTROL_OUTER_US]] ]
45; CHECK-NEXT:    switch i32 [[SWITCHCOND_0_US]], label [[CONTROL_OUTER_LOOPEXIT_US_LCSSA_US:%.*]] [
46; CHECK-NEXT:    i32 0, label [[BB0_US]]
47; CHECK-NEXT:    i32 1, label [[BB1_US_LCSSA_US:%.*]]
48; CHECK-NEXT:    i32 3, label [[BB3_US]]
49; CHECK-NEXT:    i32 4, label [[BB4_US_LCSSA_US:%.*]]
50; CHECK-NEXT:    ]
51; CHECK:       control.outer.loopexit.us-lcssa.us:
52; CHECK-NEXT:    br label [[CONTROL_OUTER_LOOPEXIT]]
53; CHECK:       bb1.us-lcssa.us:
54; CHECK-NEXT:    br label [[BB1:%.*]]
55; CHECK:       bb4.us-lcssa.us:
56; CHECK-NEXT:    br label [[BB4:%.*]]
57; CHECK:       control.outer:
58; CHECK-NEXT:    [[A_0_PH:%.*]] = phi i32 [ [[NEXTID17:%.*]], [[BB3:%.*]] ], [ 4, [[CONTROL_OUTER_OUTER_CONTROL_OUTER_OUTER_SPLIT_CRIT_EDGE]] ]
59; CHECK-NEXT:    [[SWITCHCOND_0_PH:%.*]] = phi i32 [ 0, [[BB3]] ], [ [[SWITCHCOND_0_PH_PH]], [[CONTROL_OUTER_OUTER_CONTROL_OUTER_OUTER_SPLIT_CRIT_EDGE]] ]
60; CHECK-NEXT:    br label [[CONTROL:%.*]]
61; CHECK:       control:
62; CHECK-NEXT:    [[SWITCHCOND_0:%.*]] = phi i32 [ [[A_0_PH]], [[BB0:%.*]] ], [ [[SWITCHCOND_0_PH]], [[CONTROL_OUTER]] ]
63; CHECK-NEXT:    switch i32 [[SWITCHCOND_0]], label [[CONTROL_OUTER_LOOPEXIT_US_LCSSA:%.*]] [
64; CHECK-NEXT:    i32 0, label [[BB0]]
65; CHECK-NEXT:    i32 1, label [[BB1_US_LCSSA:%.*]]
66; CHECK-NEXT:    i32 3, label [[BB3]]
67; CHECK-NEXT:    i32 4, label [[BB4_US_LCSSA:%.*]]
68; CHECK-NEXT:    ]
69; CHECK:       bb4.us-lcssa:
70; CHECK-NEXT:    br label [[BB4]]
71; CHECK:       bb4:
72; CHECK-NEXT:    br label [[CONTROL_OUTER_OUTER_BACKEDGE]]
73; CHECK:       control.outer.outer.backedge:
74; CHECK-NEXT:    [[I_0_PH_PH_BE]] = phi i32 [ 1, [[BB4]] ], [ 0, [[CONTROL_OUTER_LOOPEXIT]] ]
75; CHECK-NEXT:    br label [[CONTROL_OUTER_OUTER]]
76; CHECK:       bb3:
77; CHECK-NEXT:    [[NEXTID17]] = add i32 [[SWITCHCOND_0]], -2
78; CHECK-NEXT:    br label [[CONTROL_OUTER]]
79; CHECK:       bb0:
80; CHECK-NEXT:    br label [[CONTROL]]
81; CHECK:       bb1.us-lcssa:
82; CHECK-NEXT:    br label [[BB1]]
83; CHECK:       bb1:
84; CHECK-NEXT:    ret i32 0
85;
86init:
87  br label %control.outer.outer
88
89control.outer.loopexit.us-lcssa:                  ; preds = %control
90  br label %control.outer.loopexit
91
92control.outer.loopexit:                           ; preds = %control.outer.loopexit.us-lcssa.us, %control.outer.loopexit.us-lcssa
93  br label %control.outer.outer.backedge
94
95control.outer.outer:                              ; preds = %control.outer.outer.backedge, %init
96  %switchCond.0.ph.ph = phi i32 [ 2, %init ], [ 3, %control.outer.outer.backedge ] ; <i32> [#uses=2]
97  %i.0.ph.ph = phi i32 [ undef, %init ], [ %i.0.ph.ph.be, %control.outer.outer.backedge ] ; <i32> [#uses=1]
98  %tmp4 = icmp eq i32 %i.0.ph.ph, 0               ; <i1> [#uses=1]
99  br i1 %tmp4, label %control.outer.outer.split.us, label %control.outer.outer.control.outer.outer.split_crit_edge
100
101control.outer.outer.control.outer.outer.split_crit_edge: ; preds = %control.outer.outer
102  br label %control.outer
103
104control.outer.outer.split.us:                     ; preds = %control.outer.outer
105  br label %control.outer.us
106
107control.outer.us:                                 ; preds = %bb3.us, %control.outer.outer.split.us
108  %A.0.ph.us = phi i32 [ %switchCond.0.us, %bb3.us ], [ 4, %control.outer.outer.split.us ] ; <i32> [#uses=2]
109  %switchCond.0.ph.us = phi i32 [ %A.0.ph.us, %bb3.us ], [ %switchCond.0.ph.ph, %control.outer.outer.split.us ] ; <i32> [#uses=1]
110  br label %control.us
111
112bb3.us:                                           ; preds = %control.us
113  br label %control.outer.us
114
115bb0.us:                                           ; preds = %control.us
116  br label %control.us
117
118control.us:                                       ; preds = %bb0.us, %control.outer.us
119  %switchCond.0.us = phi i32 [ %A.0.ph.us, %bb0.us ], [ %switchCond.0.ph.us, %control.outer.us ] ; <i32> [#uses=2]
120  switch i32 %switchCond.0.us, label %control.outer.loopexit.us-lcssa.us [
121  i32 0, label %bb0.us
122  i32 1, label %bb1.us-lcssa.us
123  i32 3, label %bb3.us
124  i32 4, label %bb4.us-lcssa.us
125  ]
126
127control.outer.loopexit.us-lcssa.us:               ; preds = %control.us
128  br label %control.outer.loopexit
129
130bb1.us-lcssa.us:                                  ; preds = %control.us
131  br label %bb1
132
133bb4.us-lcssa.us:                                  ; preds = %control.us
134  br label %bb4
135
136control.outer:                                    ; preds = %bb3, %control.outer.outer.control.outer.outer.split_crit_edge
137  %A.0.ph = phi i32 [ %nextId17, %bb3 ], [ 4, %control.outer.outer.control.outer.outer.split_crit_edge ] ; <i32> [#uses=1]
138  %switchCond.0.ph = phi i32 [ 0, %bb3 ], [ %switchCond.0.ph.ph, %control.outer.outer.control.outer.outer.split_crit_edge ] ; <i32> [#uses=1]
139  br label %control
140
141control:                                          ; preds = %bb0, %control.outer
142  %switchCond.0 = phi i32 [ %A.0.ph, %bb0 ], [ %switchCond.0.ph, %control.outer ] ; <i32> [#uses=2]
143  switch i32 %switchCond.0, label %control.outer.loopexit.us-lcssa [
144  i32 0, label %bb0
145  i32 1, label %bb1.us-lcssa
146  i32 3, label %bb3
147  i32 4, label %bb4.us-lcssa
148  ]
149
150bb4.us-lcssa:                                     ; preds = %control
151  br label %bb4
152
153bb4:                                              ; preds = %bb4.us-lcssa, %bb4.us-lcssa.us
154  br label %control.outer.outer.backedge
155
156control.outer.outer.backedge:                     ; preds = %bb4, %control.outer.loopexit
157  %i.0.ph.ph.be = phi i32 [ 1, %bb4 ], [ 0, %control.outer.loopexit ] ; <i32> [#uses=1]
158  br label %control.outer.outer
159
160bb3:                                              ; preds = %control
161  %nextId17 = add i32 %switchCond.0, -2           ; <i32> [#uses=1]
162  br label %control.outer
163
164bb0:                                              ; preds = %control
165  br label %control
166
167bb1.us-lcssa:                                     ; preds = %control
168  br label %bb1
169
170bb1:                                              ; preds = %bb1.us-lcssa, %bb1.us-lcssa.us
171  ret i32 0
172}
173
174; Make sure SCCP honors the xor "idiom"
175; rdar://9956541
176define i32 @test3() {
177; CHECK-LABEL: @test3(
178; CHECK-NEXT:    [[T:%.*]] = xor i32 undef, undef
179; CHECK-NEXT:    ret i32 [[T]]
180;
181  %t = xor i32 undef, undef
182  ret i32 %t
183}
184
185; Be conservative with FP ops
186define double @test4(double %x) {
187; CHECK-LABEL: @test4(
188; CHECK-NEXT:    [[T:%.*]] = fadd double [[X:%.*]], undef
189; CHECK-NEXT:    ret double [[T]]
190;
191  %t = fadd double %x, undef
192  ret double %t
193}
194
195; Make sure casts produce a possible value
196define i32 @test5() {
197; CHECK-LABEL: @test5(
198; CHECK-NEXT:    [[T:%.*]] = sext i8 undef to i32
199; CHECK-NEXT:    ret i32 [[T]]
200;
201  %t = sext i8 undef to i32
202  ret i32 %t
203}
204
205; Make sure ashr produces a possible value
206define i32 @test6() {
207; CHECK-LABEL: @test6(
208; CHECK-NEXT:    [[T:%.*]] = ashr i32 undef, 31
209; CHECK-NEXT:    ret i32 [[T]]
210;
211  %t = ashr i32 undef, 31
212  ret i32 %t
213}
214
215; Make sure lshr produces a possible value
216define i32 @test7() {
217; CHECK-LABEL: @test7(
218; CHECK-NEXT:    [[T:%.*]] = lshr i32 undef, 31
219; CHECK-NEXT:    ret i32 [[T]]
220;
221  %t = lshr i32 undef, 31
222  ret i32 %t
223}
224
225; icmp eq with undef simplifies to undef
226define i1 @test8() {
227; CHECK-LABEL: @test8(
228; CHECK-NEXT:    [[T:%.*]] = icmp eq i32 undef, -1
229; CHECK-NEXT:    ret i1 [[T]]
230;
231  %t = icmp eq i32 undef, -1
232  ret i1 %t
233}
234
235; Make sure we don't conclude that relational comparisons simplify to undef
236define i1 @test9() {
237; CHECK-LABEL: @test9(
238; CHECK-NEXT:    [[T:%.*]] = icmp ugt i32 undef, -1
239; CHECK-NEXT:    ret i1 [[T]]
240;
241  %t = icmp ugt i32 undef, -1
242  ret i1 %t
243}
244
245; Make sure we handle extractvalue
246define i64 @test10() {
247; CHECK-LABEL: @test10(
248; CHECK-NEXT:  entry:
249; CHECK-NEXT:    [[E:%.*]] = extractvalue { i64, i64 } undef, 1
250; CHECK-NEXT:    ret i64 [[E]]
251;
252entry:
253  %e = extractvalue { i64, i64 } undef, 1
254  ret i64 %e
255}
256
257@GV = common global i32 0, align 4
258
259define i32 @test11(i1 %tobool) {
260; CHECK-LABEL: @test11(
261; CHECK-NEXT:  entry:
262; CHECK-NEXT:    [[SHR4:%.*]] = ashr i32 undef, zext (i1 icmp eq (i32* bitcast (i32 (i1)* @test11 to i32*), i32* @GV) to i32)
263; CHECK-NEXT:    ret i32 [[SHR4]]
264;
265entry:
266  %shr4 = ashr i32 undef, zext (i1 icmp eq (i32* bitcast (i32 (i1)* @test11 to i32*), i32* @GV) to i32)
267  ret i32 %shr4
268}
269
270; Test unary ops
271define double @test12(double %x) {
272; CHECK-LABEL: @test12(
273; CHECK-NEXT:    [[T:%.*]] = fneg double undef
274; CHECK-NEXT:    ret double [[T]]
275;
276  %t = fneg double undef
277  ret double %t
278}
279