1*cee313d2SEric Christopher; RUN: opt < %s -jump-threading -S | FileCheck %s
2*cee313d2SEric Christopher; Test whether two consecutive switches with identical structures assign the
3*cee313d2SEric Christopher; proper value to the proper variable.  This is really testing
4*cee313d2SEric Christopher; Instruction::isIdenticalToWhenDefined, as previously that function was
5*cee313d2SEric Christopher; returning true if the value part of the operands of two phis were identical,
6*cee313d2SEric Christopher; even if the incoming blocks were not.
7*cee313d2SEric Christopher; NB: this function should be pruned down more.
8*cee313d2SEric Christopher
9*cee313d2SEric Christopher%struct._GList = type { i8*, %struct._GList*, %struct._GList* }
10*cee313d2SEric Christopher%struct.filter_def = type { i8*, i8* }
11*cee313d2SEric Christopher
12*cee313d2SEric Christopher@capture_filters = external hidden global %struct._GList*, align 8
13*cee313d2SEric Christopher@display_filters = external hidden global %struct._GList*, align 8
14*cee313d2SEric Christopher@.str2 = external hidden unnamed_addr constant [10 x i8], align 1
15*cee313d2SEric Christopher@__PRETTY_FUNCTION__.copy_filter_list = external hidden unnamed_addr constant [62 x i8], align 1
16*cee313d2SEric Christopher@.str12 = external hidden unnamed_addr constant [22 x i8], align 1
17*cee313d2SEric Christopher@.str13 = external hidden unnamed_addr constant [31 x i8], align 1
18*cee313d2SEric Christopher@capture_edited_filters = external hidden global %struct._GList*, align 8
19*cee313d2SEric Christopher@display_edited_filters = external hidden global %struct._GList*, align 8
20*cee313d2SEric Christopher@__PRETTY_FUNCTION__.get_filter_list = external hidden unnamed_addr constant [44 x i8], align 1
21*cee313d2SEric Christopher
22*cee313d2SEric Christopherdeclare void @g_assertion_message(i8*, i8*, i32, i8*, i8*) noreturn
23*cee313d2SEric Christopher
24*cee313d2SEric Christopherdeclare void @g_free(i8*)
25*cee313d2SEric Christopher
26*cee313d2SEric Christopherdeclare %struct._GList* @g_list_first(%struct._GList*)
27*cee313d2SEric Christopher
28*cee313d2SEric Christopherdeclare noalias i8* @g_malloc(i64)
29*cee313d2SEric Christopher
30*cee313d2SEric Christopherdefine void @copy_filter_list(i32 %dest_type, i32 %src_type) nounwind uwtable ssp {
31*cee313d2SEric Christopherentry:
32*cee313d2SEric Christopher  br label %do.body
33*cee313d2SEric Christopher
34*cee313d2SEric Christopherdo.body:                                          ; preds = %entry
35*cee313d2SEric Christopher  %cmp = icmp ne i32 %dest_type, %src_type
36*cee313d2SEric Christopher  br i1 %cmp, label %if.then, label %if.else
37*cee313d2SEric Christopher
38*cee313d2SEric Christopherif.then:                                          ; preds = %do.body
39*cee313d2SEric Christopher  br label %if.end
40*cee313d2SEric Christopher
41*cee313d2SEric Christopherif.else:                                          ; preds = %do.body
42*cee313d2SEric Christopher  call void @g_assertion_message_expr(i8* null, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str2, i32 0, i32 0), i32 581, i8* getelementptr inbounds ([62 x i8], [62 x i8]* @__PRETTY_FUNCTION__.copy_filter_list, i32 0, i32 0), i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str12, i32 0, i32 0)) noreturn
43*cee313d2SEric Christopher  unreachable
44*cee313d2SEric Christopher
45*cee313d2SEric Christopherif.end:                                           ; preds = %if.then
46*cee313d2SEric Christopher  br label %do.end
47*cee313d2SEric Christopher
48*cee313d2SEric Christopherdo.end:                                           ; preds = %if.end
49*cee313d2SEric Christopher  switch i32 %dest_type, label %sw.default.i [
50*cee313d2SEric Christopher    i32 0, label %sw.bb.i
51*cee313d2SEric Christopher    i32 1, label %sw.bb1.i
52*cee313d2SEric Christopher    i32 2, label %sw.bb2.i
53*cee313d2SEric Christopher    i32 3, label %sw.bb3.i
54*cee313d2SEric Christopher  ]
55*cee313d2SEric Christopher
56*cee313d2SEric Christophersw.bb.i:                                          ; preds = %do.end
57*cee313d2SEric Christopher  br label %get_filter_list.exit
58*cee313d2SEric Christopher
59*cee313d2SEric Christophersw.bb1.i:                                         ; preds = %do.end
60*cee313d2SEric Christopher  br label %get_filter_list.exit
61*cee313d2SEric Christopher
62*cee313d2SEric Christophersw.bb2.i:                                         ; preds = %do.end
63*cee313d2SEric Christopher  br label %get_filter_list.exit
64*cee313d2SEric Christopher
65*cee313d2SEric Christophersw.bb3.i:                                         ; preds = %do.end
66*cee313d2SEric Christopher  br label %get_filter_list.exit
67*cee313d2SEric Christopher
68*cee313d2SEric Christophersw.default.i:                                     ; preds = %do.end
69*cee313d2SEric Christopher  call void @g_assertion_message(i8* null, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str2, i32 0, i32 0), i32 408, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @__PRETTY_FUNCTION__.get_filter_list, i32 0, i32 0), i8* null) noreturn nounwind
70*cee313d2SEric Christopher  unreachable
71*cee313d2SEric Christopher
72*cee313d2SEric Christopherget_filter_list.exit:                             ; preds = %sw.bb3.i, %sw.bb2.i, %sw.bb1.i, %sw.bb.i
73*cee313d2SEric Christopher  %0 = phi %struct._GList** [ @display_edited_filters, %sw.bb3.i ], [ @capture_edited_filters, %sw.bb2.i ], [ @display_filters, %sw.bb1.i ], [ @capture_filters, %sw.bb.i ]
74*cee313d2SEric Christopher  switch i32 %src_type, label %sw.default.i5 [
75*cee313d2SEric Christopher    i32 0, label %sw.bb.i1
76*cee313d2SEric Christopher    i32 1, label %sw.bb1.i2
77*cee313d2SEric Christopher    i32 2, label %sw.bb2.i3
78*cee313d2SEric Christopher    i32 3, label %sw.bb3.i4
79*cee313d2SEric Christopher  ]
80*cee313d2SEric Christopher
81*cee313d2SEric Christophersw.bb.i1:                                         ; preds = %get_filter_list.exit
82*cee313d2SEric Christopher  br label %get_filter_list.exit6
83*cee313d2SEric Christopher
84*cee313d2SEric Christophersw.bb1.i2:                                        ; preds = %get_filter_list.exit
85*cee313d2SEric Christopher  br label %get_filter_list.exit6
86*cee313d2SEric Christopher
87*cee313d2SEric Christophersw.bb2.i3:                                        ; preds = %get_filter_list.exit
88*cee313d2SEric Christopher  br label %get_filter_list.exit6
89*cee313d2SEric Christopher
90*cee313d2SEric Christophersw.bb3.i4:                                        ; preds = %get_filter_list.exit
91*cee313d2SEric Christopher  br label %get_filter_list.exit6
92*cee313d2SEric Christopher
93*cee313d2SEric Christophersw.default.i5:                                    ; preds = %get_filter_list.exit
94*cee313d2SEric Christopher  call void @g_assertion_message(i8* null, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str2, i32 0, i32 0), i32 408, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @__PRETTY_FUNCTION__.get_filter_list, i32 0, i32 0), i8* null) noreturn nounwind
95*cee313d2SEric Christopher  unreachable
96*cee313d2SEric Christopher
97*cee313d2SEric Christopher; CHECK: get_filter_list.exit
98*cee313d2SEric Christopherget_filter_list.exit6:                            ; preds = %sw.bb3.i4, %sw.bb2.i3, %sw.bb1.i2, %sw.bb.i1
99*cee313d2SEric Christopher  %1 = phi %struct._GList** [ @display_edited_filters, %sw.bb3.i4 ], [ @capture_edited_filters, %sw.bb2.i3 ], [ @display_filters, %sw.bb1.i2 ], [ @capture_filters, %sw.bb.i1 ]
100*cee313d2SEric Christopher; CHECK: %2 = load
101*cee313d2SEric Christopher  %2 = load %struct._GList*, %struct._GList** %1, align 8
102*cee313d2SEric Christopher; We should have jump-threading insert an additional load here for the value
103*cee313d2SEric Christopher; coming out of the first switch, which is picked up by a subsequent phi
104*cee313d2SEric Christopher; CHECK: %.pr = load %struct._GList*, %struct._GList** %0
105*cee313d2SEric Christopher; CHECK-NEXT:  br label %while.cond
106*cee313d2SEric Christopher  br label %while.cond
107*cee313d2SEric Christopher
108*cee313d2SEric Christopher; CHECK: while.cond
109*cee313d2SEric Christopherwhile.cond:                                       ; preds = %while.body, %get_filter_list.exit6
110*cee313d2SEric Christopher; CHECK: {{= phi .*%.pr}}
111*cee313d2SEric Christopher  %3 = load %struct._GList*, %struct._GList** %0, align 8
112*cee313d2SEric Christopher; CHECK: tobool
113*cee313d2SEric Christopher  %tobool = icmp ne %struct._GList* %3, null
114*cee313d2SEric Christopher  br i1 %tobool, label %while.body, label %while.end
115*cee313d2SEric Christopher
116*cee313d2SEric Christopherwhile.body:                                       ; preds = %while.cond
117*cee313d2SEric Christopher  %4 = load %struct._GList*, %struct._GList** %0, align 8
118*cee313d2SEric Christopher  %5 = load %struct._GList*, %struct._GList** %0, align 8
119*cee313d2SEric Christopher  %call2 = call %struct._GList* @g_list_first(%struct._GList* %5)
120*cee313d2SEric Christopher  %data.i = getelementptr inbounds %struct._GList, %struct._GList* %call2, i32 0, i32 0
121*cee313d2SEric Christopher  %6 = load i8*, i8** %data.i, align 8
122*cee313d2SEric Christopher  %7 = bitcast i8* %6 to %struct.filter_def*
123*cee313d2SEric Christopher  %name.i = getelementptr inbounds %struct.filter_def, %struct.filter_def* %7, i32 0, i32 0
124*cee313d2SEric Christopher  %8 = load i8*, i8** %name.i, align 8
125*cee313d2SEric Christopher  call void @g_free(i8* %8) nounwind
126*cee313d2SEric Christopher  %strval.i = getelementptr inbounds %struct.filter_def, %struct.filter_def* %7, i32 0, i32 1
127*cee313d2SEric Christopher  %9 = load i8*, i8** %strval.i, align 8
128*cee313d2SEric Christopher  call void @g_free(i8* %9) nounwind
129*cee313d2SEric Christopher  %10 = bitcast %struct.filter_def* %7 to i8*
130*cee313d2SEric Christopher  call void @g_free(i8* %10) nounwind
131*cee313d2SEric Christopher  %call.i = call %struct._GList* @g_list_remove_link(%struct._GList* %4, %struct._GList* %call2) nounwind
132*cee313d2SEric Christopher  store %struct._GList* %call.i, %struct._GList** %0, align 8
133*cee313d2SEric Christopher  br label %while.cond
134*cee313d2SEric Christopher
135*cee313d2SEric Christopherwhile.end:                                        ; preds = %while.cond
136*cee313d2SEric Christopher  br label %do.body4
137*cee313d2SEric Christopher
138*cee313d2SEric Christopherdo.body4:                                         ; preds = %while.end
139*cee313d2SEric Christopher  %11 = load %struct._GList*, %struct._GList** %0, align 8
140*cee313d2SEric Christopher  %call5 = call i32 @g_list_length(%struct._GList* %11)
141*cee313d2SEric Christopher  %cmp6 = icmp eq i32 %call5, 0
142*cee313d2SEric Christopher  br i1 %cmp6, label %if.then7, label %if.else8
143*cee313d2SEric Christopher
144*cee313d2SEric Christopherif.then7:                                         ; preds = %do.body4
145*cee313d2SEric Christopher  br label %if.end9
146*cee313d2SEric Christopher
147*cee313d2SEric Christopherif.else8:                                         ; preds = %do.body4
148*cee313d2SEric Christopher  call void @g_assertion_message_expr(i8* null, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str2, i32 0, i32 0), i32 600, i8* getelementptr inbounds ([62 x i8], [62 x i8]* @__PRETTY_FUNCTION__.copy_filter_list, i32 0, i32 0), i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str13, i32 0, i32 0)) noreturn
149*cee313d2SEric Christopher  unreachable
150*cee313d2SEric Christopher
151*cee313d2SEric Christopherif.end9:                                          ; preds = %if.then7
152*cee313d2SEric Christopher  br label %do.end10
153*cee313d2SEric Christopher
154*cee313d2SEric Christopherdo.end10:                                         ; preds = %if.end9
155*cee313d2SEric Christopher  br label %while.cond11
156*cee313d2SEric Christopher
157*cee313d2SEric Christopherwhile.cond11:                                     ; preds = %cond.end, %do.end10
158*cee313d2SEric Christopher  %cond10 = phi %struct._GList* [ %cond, %cond.end ], [ %2, %do.end10 ]
159*cee313d2SEric Christopher  %tobool12 = icmp ne %struct._GList* %cond10, null
160*cee313d2SEric Christopher  br i1 %tobool12, label %while.body13, label %while.end16
161*cee313d2SEric Christopher
162*cee313d2SEric Christopherwhile.body13:                                     ; preds = %while.cond11
163*cee313d2SEric Christopher  %data = getelementptr inbounds %struct._GList, %struct._GList* %cond10, i32 0, i32 0
164*cee313d2SEric Christopher  %12 = load i8*, i8** %data, align 8
165*cee313d2SEric Christopher  %13 = bitcast i8* %12 to %struct.filter_def*
166*cee313d2SEric Christopher  %14 = load %struct._GList*, %struct._GList** %0, align 8
167*cee313d2SEric Christopher  %name = getelementptr inbounds %struct.filter_def, %struct.filter_def* %13, i32 0, i32 0
168*cee313d2SEric Christopher  %15 = load i8*, i8** %name, align 8
169*cee313d2SEric Christopher  %strval = getelementptr inbounds %struct.filter_def, %struct.filter_def* %13, i32 0, i32 1
170*cee313d2SEric Christopher  %16 = load i8*, i8** %strval, align 8
171*cee313d2SEric Christopher  %call.i7 = call noalias i8* @g_malloc(i64 16) nounwind
172*cee313d2SEric Christopher  %17 = bitcast i8* %call.i7 to %struct.filter_def*
173*cee313d2SEric Christopher  %call1.i = call noalias i8* @g_strdup(i8* %15) nounwind
174*cee313d2SEric Christopher  %name.i8 = getelementptr inbounds %struct.filter_def, %struct.filter_def* %17, i32 0, i32 0
175*cee313d2SEric Christopher  store i8* %call1.i, i8** %name.i8, align 8
176*cee313d2SEric Christopher  %call2.i = call noalias i8* @g_strdup(i8* %16) nounwind
177*cee313d2SEric Christopher  %strval.i9 = getelementptr inbounds %struct.filter_def, %struct.filter_def* %17, i32 0, i32 1
178*cee313d2SEric Christopher  store i8* %call2.i, i8** %strval.i9, align 8
179*cee313d2SEric Christopher  %18 = bitcast %struct.filter_def* %17 to i8*
180*cee313d2SEric Christopher  %call3.i = call %struct._GList* @g_list_append(%struct._GList* %14, i8* %18) nounwind
181*cee313d2SEric Christopher  store %struct._GList* %call3.i, %struct._GList** %0, align 8
182*cee313d2SEric Christopher  %tobool15 = icmp ne %struct._GList* %cond10, null
183*cee313d2SEric Christopher  br i1 %tobool15, label %cond.true, label %cond.false
184*cee313d2SEric Christopher
185*cee313d2SEric Christophercond.true:                                        ; preds = %while.body13
186*cee313d2SEric Christopher  %next = getelementptr inbounds %struct._GList, %struct._GList* %cond10, i32 0, i32 1
187*cee313d2SEric Christopher  %19 = load %struct._GList*, %struct._GList** %next, align 8
188*cee313d2SEric Christopher  br label %cond.end
189*cee313d2SEric Christopher
190*cee313d2SEric Christophercond.false:                                       ; preds = %while.body13
191*cee313d2SEric Christopher  br label %cond.end
192*cee313d2SEric Christopher
193*cee313d2SEric Christophercond.end:                                         ; preds = %cond.false, %cond.true
194*cee313d2SEric Christopher  %cond = phi %struct._GList* [ %19, %cond.true ], [ null, %cond.false ]
195*cee313d2SEric Christopher  br label %while.cond11
196*cee313d2SEric Christopher
197*cee313d2SEric Christopherwhile.end16:                                      ; preds = %while.cond11
198*cee313d2SEric Christopher  ret void
199*cee313d2SEric Christopher}
200*cee313d2SEric Christopher
201*cee313d2SEric Christopherdeclare void @g_assertion_message_expr(i8*, i8*, i32, i8*, i8*) noreturn
202*cee313d2SEric Christopher
203*cee313d2SEric Christopherdeclare i32 @g_list_length(%struct._GList*)
204*cee313d2SEric Christopher
205*cee313d2SEric Christopherdeclare noalias i8* @g_strdup(i8*)
206*cee313d2SEric Christopher
207*cee313d2SEric Christopherdeclare %struct._GList* @g_list_append(%struct._GList*, i8*)
208*cee313d2SEric Christopher
209*cee313d2SEric Christopherdeclare %struct._GList* @g_list_remove_link(%struct._GList*, %struct._GList*)
210