xref: /llvm-project/llvm/test/Transforms/MergeICmps/X86/pr59740.ll (revision df3a8f376084cf5e319bccd843105979d0f3b6f1)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=mergeicmps -verify-dom-info -S -mtriple=x86_64-unknown-unknown | FileCheck %s
3
4%struct.S = type { i8, i8, i8, i8 }
5%struct1.S = type { i32, i32, i32, i8 }
6%"struct.media::WebrtcVideoStatsDB::VideoDescKey" = type { i8, i32, i8, i32 }
7%"c" = type { i32, i32, i32, float}
8
9define noundef i1 @full_sequent_ne(ptr nocapture readonly align 1 dereferenceable(4) %s0, ptr nocapture readonly align 1 dereferenceable(4) %s1) {
10; CHECK-LABEL: @full_sequent_ne(
11; CHECK-NEXT:  bb0:
12; CHECK-NEXT:    [[V0:%.*]] = load i8, ptr [[S0:%.*]], align 1
13; CHECK-NEXT:    [[V1:%.*]] = load i8, ptr [[S1:%.*]], align 1
14; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i8 [[V0]], [[V1]]
15; CHECK-NEXT:    br i1 [[CMP0]], label [[BB1:%.*]], label [[BB4:%.*]]
16; CHECK:       bb1:
17; CHECK-NEXT:    [[S2:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[S0]], i64 0, i32 1
18; CHECK-NEXT:    [[V2:%.*]] = load i8, ptr [[S2]], align 1
19; CHECK-NEXT:    [[S3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S1]], i64 0, i32 1
20; CHECK-NEXT:    [[V3:%.*]] = load i8, ptr [[S3]], align 1
21; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[V2]], [[V3]]
22; CHECK-NEXT:    br i1 [[CMP1]], label [[BB2:%.*]], label [[BB4]]
23; CHECK:       bb2:
24; CHECK-NEXT:    [[S4:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S0]], i64 0, i32 2
25; CHECK-NEXT:    [[V4:%.*]] = load i8, ptr [[S4]], align 1
26; CHECK-NEXT:    [[S5:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S1]], i64 0, i32 2
27; CHECK-NEXT:    [[V5:%.*]] = load i8, ptr [[S5]], align 1
28; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[V4]], [[V5]]
29; CHECK-NEXT:    br i1 [[CMP2]], label [[BB3:%.*]], label [[BB4]]
30; CHECK:       bb3:
31; CHECK-NEXT:    [[S6:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S0]], i64 0, i32 3
32; CHECK-NEXT:    [[V6:%.*]] = load i8, ptr [[S6]], align 1
33; CHECK-NEXT:    [[S7:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S1]], i64 0, i32 3
34; CHECK-NEXT:    [[V7:%.*]] = load i8, ptr [[S7]], align 1
35; CHECK-NEXT:    [[CMP3:%.*]] = icmp ne i8 [[V6]], [[V7]]
36; CHECK-NEXT:    br label [[BB4]]
37; CHECK:       bb4:
38; CHECK-NEXT:    [[CMP:%.*]] = phi i1 [ true, [[BB0:%.*]] ], [ true, [[BB1]] ], [ true, [[BB2]] ], [ [[CMP3]], [[BB3]] ]
39; CHECK-NEXT:    ret i1 [[CMP]]
40;
41bb0:
42  %v0 = load i8, ptr %s0, align 1
43  %v1 = load i8, ptr %s1, align 1
44  %cmp0 = icmp eq i8 %v0, %v1
45  br i1 %cmp0, label %bb1, label %bb4
46
47bb1:                                              ; preds = %bb0
48  %s2 = getelementptr inbounds %struct.S, ptr %s0, i64 0, i32 1
49  %v2 = load i8, ptr %s2, align 1
50  %s3 = getelementptr inbounds %struct.S, ptr %s1, i64 0, i32 1
51  %v3 = load i8, ptr %s3, align 1
52  %cmp1 = icmp eq i8 %v2, %v3
53  br i1 %cmp1, label %bb2, label %bb4
54
55bb2:                                             ; preds = %bb1
56  %s4 = getelementptr inbounds %struct.S, ptr %s0, i64 0, i32 2
57  %v4 = load i8, ptr %s4, align 1
58  %s5 = getelementptr inbounds %struct.S, ptr %s1, i64 0, i32 2
59  %v5 = load i8, ptr %s5, align 1
60  %cmp2 = icmp eq i8 %v4, %v5
61  br i1 %cmp2, label %bb3, label %bb4
62
63bb3:                                               ; preds = %bb2
64  %s6 = getelementptr inbounds %struct.S, ptr %s0, i64 0, i32 3
65  %v6 = load i8, ptr %s6, align 1
66  %s7 = getelementptr inbounds %struct.S, ptr %s1, i64 0, i32 3
67  %v7 = load i8, ptr %s7, align 1
68  %cmp3 = icmp ne i8 %v6, %v7
69  br label %bb4
70
71bb4:                                               ; preds = %bb0, %bb1, %bb2, %bb3
72  %cmp = phi i1 [ true, %bb0 ], [ true, %bb1 ], [ true, %bb2 ], [ %cmp3, %bb3 ]
73  ret i1 %cmp
74}
75
76; Negative test: Incorrect const value in PHI node
77define noundef i1 @cmp_ne_incorrect_const(ptr nocapture readonly align 1 dereferenceable(4) %s0, ptr nocapture readonly align 1 dereferenceable(4) %s1) {
78; CHECK-LABEL: @cmp_ne_incorrect_const(
79; CHECK-NEXT:  bb0:
80; CHECK-NEXT:    [[V0:%.*]] = load i8, ptr [[S0:%.*]], align 1
81; CHECK-NEXT:    [[V1:%.*]] = load i8, ptr [[S1:%.*]], align 1
82; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i8 [[V0]], [[V1]]
83; CHECK-NEXT:    br i1 [[CMP0]], label [[BB1:%.*]], label [[BB2:%.*]]
84; CHECK:       bb1:
85; CHECK-NEXT:    [[S6:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[S0]], i64 0, i32 1
86; CHECK-NEXT:    [[V6:%.*]] = load i8, ptr [[S6]], align 1
87; CHECK-NEXT:    [[S7:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S1]], i64 0, i32 1
88; CHECK-NEXT:    [[V7:%.*]] = load i8, ptr [[S7]], align 1
89; CHECK-NEXT:    [[CMP3:%.*]] = icmp ne i8 [[V6]], [[V7]]
90; CHECK-NEXT:    br label [[BB2]]
91; CHECK:       bb2:
92; CHECK-NEXT:    [[CMP:%.*]] = phi i1 [ false, [[BB0:%.*]] ], [ [[CMP3]], [[BB1]] ]
93; CHECK-NEXT:    ret i1 [[CMP]]
94;
95bb0:
96  %v0 = load i8, ptr %s0, align 1
97  %v1 = load i8, ptr %s1, align 1
98  %cmp0 = icmp eq i8 %v0, %v1
99  br i1 %cmp0, label %bb1, label %bb2
100
101bb1:                                               ; preds = %bb0
102  %s6 = getelementptr inbounds %struct.S, ptr %s0, i64 0, i32 1
103  %v6 = load i8, ptr %s6, align 1
104  %s7 = getelementptr inbounds %struct.S, ptr %s1, i64 0, i32 1
105  %v7 = load i8, ptr %s7, align 1
106  %cmp3 = icmp ne i8 %v6, %v7
107  br label %bb2
108
109bb2:                                               ; preds = %bb0, %bb1
110  %cmp = phi i1 [ false, %bb0 ], [ %cmp3, %bb1 ]
111  ret i1 %cmp
112}
113
114; https://alive2.llvm.org/ce/z/Zi2Z3Y
115define noundef i1 @partial_sequent_eq(ptr nocapture readonly dereferenceable(16) %s0, ptr nocapture readonly dereferenceable(16) %s1) {
116; CHECK-LABEL: @partial_sequent_eq(
117; CHECK-NEXT:  bb01:
118; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[S0:%.*]], align 8
119; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[S1:%.*]], align 8
120; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
121; CHECK-NEXT:    br i1 [[TMP2]], label %"bb1+bb2", label [[BB3:%.*]]
122; CHECK:       "bb1+bb2":
123; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds [[STRUCT1_S:%.*]], ptr [[S0]], i64 0, i32 2
124; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds [[STRUCT1_S]], ptr [[S1]], i64 0, i32 2
125; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr [[TMP3]], ptr [[TMP4]], i64 5)
126; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[MEMCMP]], 0
127; CHECK-NEXT:    br label [[BB3]]
128; CHECK:       bb3:
129; CHECK-NEXT:    [[CMP:%.*]] = phi i1 [ [[TMP5]], %"bb1+bb2" ], [ false, [[BB01:%.*]] ]
130; CHECK-NEXT:    ret i1 [[CMP]]
131;
132bb0:
133  %v0 = load i32, ptr %s0, align 8
134  %v1 = load i32, ptr %s1, align 8
135  %cmp0 = icmp eq i32 %v0, %v1
136  br i1 %cmp0, label %bb1, label %bb3
137
138bb1:                                              ; preds = %bb0
139  %s2 = getelementptr inbounds %struct1.S, ptr %s0, i64 0, i32 2
140  %v2 = load i32, ptr %s2, align 8
141  %s3 = getelementptr inbounds %struct1.S, ptr %s1, i64 0, i32 2
142  %v3 = load i32, ptr %s3, align 8
143  %cmp1 = icmp eq i32 %v2, %v3
144  br i1 %cmp1, label %bb2, label %bb3
145
146bb2:                                               ; preds = %bb2
147  %s6 = getelementptr inbounds %struct1.S, ptr %s0, i64 0, i32 3
148  %v6 = load i8, ptr %s6, align 1
149  %s7 = getelementptr inbounds %struct1.S, ptr %s1, i64 0, i32 3
150  %v7 = load i8, ptr %s7, align 1
151  %cmp3 = icmp eq i8 %v6, %v7
152  br label %bb3
153
154bb3:                                               ; preds = %bb0, %bb1, %bb2
155  %cmp = phi i1 [ false, %bb0 ], [ false, %bb1 ], [ %cmp3, %bb2 ]
156  ret i1 %cmp
157}
158
159; https://alive2.llvm.org/ce/z/sL5Uz6
160define noundef i1 @partial_sequent_ne(ptr nocapture readonly dereferenceable(16) %s0, ptr nocapture readonly dereferenceable(16) %s1) {
161; CHECK-LABEL: @partial_sequent_ne(
162; CHECK-NEXT:  bb0:
163; CHECK-NEXT:    [[V0:%.*]] = load i32, ptr [[S0:%.*]], align 8
164; CHECK-NEXT:    [[V1:%.*]] = load i32, ptr [[S1:%.*]], align 8
165; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i32 [[V0]], [[V1]]
166; CHECK-NEXT:    br i1 [[CMP0]], label [[BB1:%.*]], label [[BB3:%.*]]
167; CHECK:       bb1:
168; CHECK-NEXT:    [[S2:%.*]] = getelementptr inbounds [[STRUCT1_S:%.*]], ptr [[S0]], i64 0, i32 2
169; CHECK-NEXT:    [[V2:%.*]] = load i32, ptr [[S2]], align 8
170; CHECK-NEXT:    [[S3:%.*]] = getelementptr inbounds [[STRUCT1_S]], ptr [[S1]], i64 0, i32 2
171; CHECK-NEXT:    [[V3:%.*]] = load i32, ptr [[S3]], align 8
172; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[V2]], [[V3]]
173; CHECK-NEXT:    br i1 [[CMP1]], label [[BB2:%.*]], label [[BB3]]
174; CHECK:       bb2:
175; CHECK-NEXT:    [[S6:%.*]] = getelementptr inbounds [[STRUCT1_S]], ptr [[S0]], i64 0, i32 3
176; CHECK-NEXT:    [[V6:%.*]] = load i8, ptr [[S6]], align 1
177; CHECK-NEXT:    [[S7:%.*]] = getelementptr inbounds [[STRUCT1_S]], ptr [[S1]], i64 0, i32 3
178; CHECK-NEXT:    [[V7:%.*]] = load i8, ptr [[S7]], align 1
179; CHECK-NEXT:    [[CMP3:%.*]] = icmp ne i8 [[V6]], [[V7]]
180; CHECK-NEXT:    br label [[BB3]]
181; CHECK:       bb3:
182; CHECK-NEXT:    [[CMP:%.*]] = phi i1 [ true, [[BB0:%.*]] ], [ true, [[BB1]] ], [ [[CMP3]], [[BB2]] ]
183; CHECK-NEXT:    ret i1 [[CMP]]
184;
185bb0:
186  %v0 = load i32, ptr %s0, align 8
187  %v1 = load i32, ptr %s1, align 8
188  %cmp0 = icmp eq i32 %v0, %v1
189  br i1 %cmp0, label %bb1, label %bb3
190
191bb1:                                              ; preds = %bb0
192  %s2 = getelementptr inbounds %struct1.S, ptr %s0, i64 0, i32 2
193  %v2 = load i32, ptr %s2, align 8
194  %s3 = getelementptr inbounds %struct1.S, ptr %s1, i64 0, i32 2
195  %v3 = load i32, ptr %s3, align 8
196  %cmp1 = icmp eq i32 %v2, %v3
197  br i1 %cmp1, label %bb2, label %bb3
198
199bb2:                                               ; preds = %bb2
200  %s6 = getelementptr inbounds %struct1.S, ptr %s0, i64 0, i32 3
201  %v6 = load i8, ptr %s6, align 1
202  %s7 = getelementptr inbounds %struct1.S, ptr %s1, i64 0, i32 3
203  %v7 = load i8, ptr %s7, align 1
204  %cmp3 = icmp ne i8 %v6, %v7
205  br label %bb3
206
207bb3:                                               ; preds = %bb0, %bb1, %bb2
208  %cmp = phi i1 [ true, %bb0 ], [ true, %bb1 ], [ %cmp3, %bb2 ]
209  ret i1 %cmp
210}
211
212; https://alive2.llvm.org/ce/z/EQtb_S
213define i1 @WebrtcVideoStats(ptr nocapture noundef dereferenceable(16) %S0, ptr nocapture noundef dereferenceable(16) %S1) {
214; CHECK-LABEL: @WebrtcVideoStats(
215; CHECK-NEXT:  bb0:
216; CHECK-NEXT:    [[V0:%.*]] = load i8, ptr [[S0:%.*]], align 4
217; CHECK-NEXT:    [[V1:%.*]] = load i8, ptr [[S1:%.*]], align 4
218; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i8 [[V0]], [[V1]]
219; CHECK-NEXT:    br i1 [[CMP0]], label [[BB1:%.*]], label [[BB4:%.*]]
220; CHECK:       bb1:
221; CHECK-NEXT:    [[BASE2:%.*]] = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr [[S0]], i64 0, i32 1
222; CHECK-NEXT:    [[V2:%.*]] = load i32, ptr [[BASE2]], align 4
223; CHECK-NEXT:    [[BASE3:%.*]] = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr [[S1]], i64 0, i32 1
224; CHECK-NEXT:    [[V3:%.*]] = load i32, ptr [[BASE3]], align 4
225; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[V2]], [[V3]]
226; CHECK-NEXT:    br i1 [[CMP1]], label [[BB2:%.*]], label [[BB4]]
227; CHECK:       bb2:
228; CHECK-NEXT:    [[BASE4:%.*]] = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr [[S0]], i64 0, i32 2
229; CHECK-NEXT:    [[V4:%.*]] = load i8, ptr [[BASE4]], align 4
230; CHECK-NEXT:    [[BASE5:%.*]] = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr [[S1]], i64 0, i32 2
231; CHECK-NEXT:    [[V5:%.*]] = load i8, ptr [[BASE5]], align 4
232; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[V4]], [[V5]]
233; CHECK-NEXT:    br i1 [[CMP2]], label [[BB3:%.*]], label [[BB4]]
234; CHECK:       bb3:
235; CHECK-NEXT:    [[BASE6:%.*]] = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr [[S0]], i64 0, i32 3
236; CHECK-NEXT:    [[V6:%.*]] = load i32, ptr [[BASE6]], align 4
237; CHECK-NEXT:    [[BASE7:%.*]] = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr [[S1]], i64 0, i32 3
238; CHECK-NEXT:    [[V7:%.*]] = load i32, ptr [[BASE7]], align 4
239; CHECK-NEXT:    [[CMP3:%.*]] = icmp ne i32 [[V6]], [[V7]]
240; CHECK-NEXT:    br label [[BB4]]
241; CHECK:       bb4:
242; CHECK-NEXT:    [[RESULT:%.*]] = phi i1 [ [[CMP3]], [[BB3]] ], [ true, [[BB2]] ], [ true, [[BB1]] ], [ true, [[BB0:%.*]] ]
243; CHECK-NEXT:    ret i1 [[RESULT]]
244;
245bb0:
246  %V0 = load i8, ptr %S0, align 4
247  %V1 = load i8, ptr %S1, align 4
248  %Cmp0 = icmp eq i8 %V0, %V1
249  br i1 %Cmp0, label %bb1, label %bb4
250
251bb1:                                                ; preds = %bb0
252  %Base2 = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr %S0, i64 0, i32 1
253  %V2 = load i32, ptr %Base2, align 4
254  %Base3 = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr %S1, i64 0, i32 1
255  %V3 = load i32, ptr %Base3, align 4
256  %Cmp1 = icmp eq i32 %V2, %V3
257  br i1 %Cmp1, label %bb2, label %bb4
258
259bb2:                                               ; preds = %bb1
260  %Base4 = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr %S0, i64 0, i32 2
261  %V4 = load i8, ptr %Base4, align 4
262  %Base5 = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr %S1, i64 0, i32 2
263  %V5 = load i8, ptr %Base5, align 4
264  %Cmp2 = icmp eq i8 %V4, %V5
265  br i1 %Cmp2, label %bb3, label %bb4
266
267bb3:                                               ; preds = %bb2
268  %Base6 = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr %S0, i64 0, i32 3
269  %V6 = load i32, ptr %Base6, align 4
270  %Base7 = getelementptr inbounds %"struct.media::WebrtcVideoStatsDB::VideoDescKey", ptr %S1, i64 0, i32 3
271  %V7 = load i32, ptr %Base7, align 4
272  %Cmp3 = icmp ne i32 %V6, %V7
273  br label %bb4
274
275bb4:                                               ; preds = %bb3, %bb2, %bb1, %bb0
276  %result = phi i1 [ %Cmp3, %bb3 ], [ true, %bb2 ], [ true, %bb1 ], [ true, %bb0 ]
277  ret i1 %result
278}
279
280; the comparison link sequence will be reordered according the memory offset,
281; and the unconditionla comparison will not at the end of the chain.
282define i1 @full_revert_order_ne(ptr nocapture noundef nonnull readonly dereferenceable(24) %0, ptr nocapture noundef nonnull readonly dereferenceable(24) %1) {
283; CHECK-LABEL: @full_revert_order_ne(
284; CHECK-NEXT:  bb0:
285; CHECK-NEXT:    [[S0:%.*]] = getelementptr inbounds [[C:%.*]], ptr [[TMP0:%.*]], i64 0, i32 2
286; CHECK-NEXT:    [[V0:%.*]] = load i32, ptr [[S0]], align 4
287; CHECK-NEXT:    [[S1:%.*]] = getelementptr inbounds [[C]], ptr [[TMP1:%.*]], i64 0, i32 2
288; CHECK-NEXT:    [[V1:%.*]] = load i32, ptr [[S1]], align 4
289; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i32 [[V0]], [[V1]]
290; CHECK-NEXT:    br i1 [[CMP0]], label [[BB1:%.*]], label [[BB3:%.*]]
291; CHECK:       bb1:
292; CHECK-NEXT:    [[S2:%.*]] = getelementptr inbounds [[C]], ptr [[TMP0]], i64 0, i32 1
293; CHECK-NEXT:    [[V2:%.*]] = load i32, ptr [[S2]], align 4
294; CHECK-NEXT:    [[S3:%.*]] = getelementptr inbounds [[C]], ptr [[TMP1]], i64 0, i32 1
295; CHECK-NEXT:    [[V3:%.*]] = load i32, ptr [[S3]], align 4
296; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[V2]], [[V3]]
297; CHECK-NEXT:    br i1 [[CMP1]], label [[BB2:%.*]], label [[BB3]]
298; CHECK:       bb2:
299; CHECK-NEXT:    [[S4:%.*]] = getelementptr inbounds [[C]], ptr [[TMP0]], i64 0, i32 0
300; CHECK-NEXT:    [[V4:%.*]] = load i32, ptr [[S4]], align 4
301; CHECK-NEXT:    [[S5:%.*]] = getelementptr inbounds [[C]], ptr [[TMP1]], i64 0, i32 0
302; CHECK-NEXT:    [[V5:%.*]] = load i32, ptr [[S5]], align 4
303; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[V4]], [[V5]]
304; CHECK-NEXT:    br label [[BB3]]
305; CHECK:       bb3:
306; CHECK-NEXT:    [[CMP3:%.*]] = phi i1 [ true, [[BB1]] ], [ true, [[BB0:%.*]] ], [ [[CMP2]], [[BB2]] ]
307; CHECK-NEXT:    ret i1 [[CMP3]]
308;
309bb0:
310  %s0 = getelementptr inbounds %"c", ptr %0, i64 0, i32 2
311  %v0 = load i32, ptr %s0, align 4
312  %s1 = getelementptr inbounds %"c", ptr %1, i64 0, i32 2
313  %v1 = load i32, ptr %s1, align 4
314  %cmp0 = icmp eq i32 %v0, %v1
315  br i1 %cmp0, label %bb1, label %bb3
316
317bb1:                                                ; preds = %bb0
318  %s2 = getelementptr inbounds %"c", ptr %0, i64 0, i32 1
319  %v2 = load i32, ptr %s2, align 4
320  %s3 = getelementptr inbounds %"c", ptr %1, i64 0, i32 1
321  %v3 = load i32, ptr %s3, align 4
322  %cmp1 = icmp eq i32 %v2, %v3
323  br i1 %cmp1, label %bb2, label %bb3
324
325bb2:                                               ; preds = %bb1
326  %s4 = getelementptr inbounds %"c", ptr %0, i64 0, i32 0
327  %v4 = load i32, ptr %s4, align 4
328  %s5 = getelementptr inbounds %"c", ptr %1, i64 0, i32 0
329  %v5 = load i32, ptr %s5, align 4
330  %cmp2 = icmp ne i32 %v4, %v5
331  br label %bb3
332
333bb3:                                               ; preds = %bb2, %bb1, %bb0
334  %cmp3 = phi i1 [ true, %bb1 ], [ true, %bb0 ], [ %cmp2, %bb2 ]
335  ret i1 %cmp3
336}
337