1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
4 %struct.Counters = type { i64, i64, i64, [8 x i8] }
6 @m = global i64 3, align 8
7 @counters = global %struct.Counters zeroinitializer, align 16
9 define i32 @align_both_equal() local_unnamed_addr {
10 ; CHECK-LABEL: @align_both_equal(
12 ; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr getelementptr inbounds ([[STRUCT_COUNTERS:%.*]], ptr @counters, i64 0, i32 1), align 8
13 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 1, i64 1>
14 ; CHECK-NEXT: store <2 x i64> [[TMP1]], ptr getelementptr inbounds ([[STRUCT_COUNTERS]], ptr @counters, i64 0, i32 1), align 8
15 ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr @m, align 8
16 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1
17 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
18 ; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2>
19 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
20 ; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2
21 ; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0
22 ; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1>
23 ; CHECK-NEXT: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]]
24 ; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true
25 ; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true
26 ; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
27 ; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]]
29 ; CHECK-NEXT: store <2 x i64> [[SIMPLIFYCFG_MERGE]], ptr getelementptr inbounds ([[STRUCT_COUNTERS]], ptr @counters, i64 0, i32 1), align 8
30 ; CHECK-NEXT: br label [[TMP10]]
32 ; CHECK-NEXT: ret i32 0
35 %0 = load <2 x i64>, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
36 %1 = add nsw <2 x i64> %0, <i64 1, i64 1>
37 store <2 x i64> %1, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
38 %2 = load i64, ptr @m, align 8
40 %tobool = icmp eq i64 %and, 0
41 br i1 %tobool, label %if.end, label %if.then
43 if.then: ; preds = %entry
44 %3 = add nsw <2 x i64> %0, <i64 2, i64 2>
45 store <2 x i64> %3, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
48 if.end: ; preds = %entry, %if.then
49 %4 = phi <2 x i64> [ %1, %entry ], [ %3, %if.then ]
51 %tobool5 = icmp eq i64 %and4, 0
52 br i1 %tobool5, label %if.end9, label %if.then6
54 if.then6: ; preds = %if.end
55 %5 = add nsw <2 x i64> %4, <i64 1, i64 1>
56 store <2 x i64> %5, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
59 if.end9: ; preds = %if.end, %if.then6
63 define i32 @align_not_equal() local_unnamed_addr {
64 ; CHECK-LABEL: @align_not_equal(
66 ; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr getelementptr inbounds ([[STRUCT_COUNTERS:%.*]], ptr @counters, i64 0, i32 1), align 8
67 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 1, i64 1>
68 ; CHECK-NEXT: store <2 x i64> [[TMP1]], ptr getelementptr inbounds ([[STRUCT_COUNTERS]], ptr @counters, i64 0, i32 1), align 8
69 ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr @m, align 8
70 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1
71 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
72 ; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2>
73 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
74 ; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2
75 ; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0
76 ; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1>
77 ; CHECK-NEXT: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]]
78 ; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true
79 ; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true
80 ; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
81 ; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]]
83 ; CHECK-NEXT: store <2 x i64> [[SIMPLIFYCFG_MERGE]], ptr getelementptr inbounds ([[STRUCT_COUNTERS]], ptr @counters, i64 0, i32 1), align 8
84 ; CHECK-NEXT: br label [[TMP10]]
86 ; CHECK-NEXT: ret i32 0
89 %0 = load <2 x i64>, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
90 %1 = add nsw <2 x i64> %0, <i64 1, i64 1>
91 store <2 x i64> %1, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
92 %2 = load i64, ptr @m, align 8
94 %tobool = icmp eq i64 %and, 0
95 br i1 %tobool, label %if.end, label %if.then
97 if.then: ; preds = %entry
98 %3 = add nsw <2 x i64> %0, <i64 2, i64 2>
99 store <2 x i64> %3, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 16
102 if.end: ; preds = %entry, %if.then
103 %4 = phi <2 x i64> [ %1, %entry ], [ %3, %if.then ]
104 %and4 = and i64 %2, 2
105 %tobool5 = icmp eq i64 %and4, 0
106 br i1 %tobool5, label %if.end9, label %if.then6
108 if.then6: ; preds = %if.end
109 %5 = add nsw <2 x i64> %4, <i64 1, i64 1>
110 store <2 x i64> %5, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
113 if.end9: ; preds = %if.end, %if.then6
117 define i32 @align_single_zero() local_unnamed_addr {
118 ; CHECK-LABEL: @align_single_zero(
120 ; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr getelementptr inbounds ([[STRUCT_COUNTERS:%.*]], ptr @counters, i64 0, i32 1), align 8
121 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 1, i64 1>
122 ; CHECK-NEXT: store <2 x i64> [[TMP1]], ptr getelementptr inbounds ([[STRUCT_COUNTERS]], ptr @counters, i64 0, i32 1), align 8
123 ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr @m, align 8
124 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1
125 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
126 ; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2>
127 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
128 ; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2
129 ; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0
130 ; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1>
131 ; CHECK-NEXT: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]]
132 ; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true
133 ; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true
134 ; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
135 ; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]]
137 ; CHECK-NEXT: store <2 x i64> [[SIMPLIFYCFG_MERGE]], ptr getelementptr inbounds ([[STRUCT_COUNTERS]], ptr @counters, i64 0, i32 1), align 8
138 ; CHECK-NEXT: br label [[TMP10]]
140 ; CHECK-NEXT: ret i32 0
143 %0 = load <2 x i64>, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
144 %1 = add nsw <2 x i64> %0, <i64 1, i64 1>
145 store <2 x i64> %1, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
146 %2 = load i64, ptr @m, align 8
148 %tobool = icmp eq i64 %and, 0
149 br i1 %tobool, label %if.end, label %if.then
151 if.then: ; preds = %entry
152 %3 = add nsw <2 x i64> %0, <i64 2, i64 2>
153 store <2 x i64> %3, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1)
156 if.end: ; preds = %entry, %if.then
157 %4 = phi <2 x i64> [ %1, %entry ], [ %3, %if.then ]
158 %and4 = and i64 %2, 2
159 %tobool5 = icmp eq i64 %and4, 0
160 br i1 %tobool5, label %if.end9, label %if.then6
162 if.then6: ; preds = %if.end
163 %5 = add nsw <2 x i64> %4, <i64 1, i64 1>
164 store <2 x i64> %5, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
167 if.end9: ; preds = %if.end, %if.then6
171 define i32 @align_single_zero_second_greater_default() local_unnamed_addr {
172 ; CHECK-LABEL: @align_single_zero_second_greater_default(
174 ; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr getelementptr inbounds ([[STRUCT_COUNTERS:%.*]], ptr @counters, i64 0, i32 1), align 8
175 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 1, i64 1>
176 ; CHECK-NEXT: store <2 x i64> [[TMP1]], ptr getelementptr inbounds ([[STRUCT_COUNTERS]], ptr @counters, i64 0, i32 1), align 8
177 ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr @m, align 8
178 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1
179 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
180 ; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2>
181 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
182 ; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2
183 ; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0
184 ; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1>
185 ; CHECK-NEXT: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]]
186 ; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true
187 ; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true
188 ; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
189 ; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]]
191 ; CHECK-NEXT: store <2 x i64> [[SIMPLIFYCFG_MERGE]], ptr getelementptr inbounds ([[STRUCT_COUNTERS]], ptr @counters, i64 0, i32 1), align 16
192 ; CHECK-NEXT: br label [[TMP10]]
194 ; CHECK-NEXT: ret i32 0
197 %0 = load <2 x i64>, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
198 %1 = add nsw <2 x i64> %0, <i64 1, i64 1>
199 store <2 x i64> %1, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
200 %2 = load i64, ptr @m, align 8
202 %tobool = icmp eq i64 %and, 0
203 br i1 %tobool, label %if.end, label %if.then
205 if.then: ; preds = %entry
206 %3 = add nsw <2 x i64> %0, <i64 2, i64 2>
207 store <2 x i64> %3, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 32
210 if.end: ; preds = %entry, %if.then
211 %4 = phi <2 x i64> [ %1, %entry ], [ %3, %if.then ]
212 %and4 = and i64 %2, 2
213 %tobool5 = icmp eq i64 %and4, 0
214 br i1 %tobool5, label %if.end9, label %if.then6
216 if.then6: ; preds = %if.end
217 %5 = add nsw <2 x i64> %4, <i64 1, i64 1>
218 store <2 x i64> %5, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1)
221 if.end9: ; preds = %if.end, %if.then6
225 define i32 @align_both_zero() local_unnamed_addr {
226 ; CHECK-LABEL: @align_both_zero(
228 ; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr getelementptr inbounds ([[STRUCT_COUNTERS:%.*]], ptr @counters, i64 0, i32 1), align 8
229 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 1, i64 1>
230 ; CHECK-NEXT: store <2 x i64> [[TMP1]], ptr getelementptr inbounds ([[STRUCT_COUNTERS]], ptr @counters, i64 0, i32 1), align 8
231 ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr @m, align 8
232 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1
233 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
234 ; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2>
235 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
236 ; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2
237 ; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0
238 ; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1>
239 ; CHECK-NEXT: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]]
240 ; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true
241 ; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true
242 ; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
243 ; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]]
245 ; CHECK-NEXT: store <2 x i64> [[SIMPLIFYCFG_MERGE]], ptr getelementptr inbounds ([[STRUCT_COUNTERS]], ptr @counters, i64 0, i32 1), align 16
246 ; CHECK-NEXT: br label [[TMP10]]
248 ; CHECK-NEXT: ret i32 0
251 %0 = load <2 x i64>, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
252 %1 = add nsw <2 x i64> %0, <i64 1, i64 1>
253 store <2 x i64> %1, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1), align 8
254 %2 = load i64, ptr @m, align 8
256 %tobool = icmp eq i64 %and, 0
257 br i1 %tobool, label %if.end, label %if.then
259 if.then: ; preds = %entry
260 %3 = add nsw <2 x i64> %0, <i64 2, i64 2>
261 store <2 x i64> %3, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1)
264 if.end: ; preds = %entry, %if.then
265 %4 = phi <2 x i64> [ %1, %entry ], [ %3, %if.then ]
266 %and4 = and i64 %2, 2
267 %tobool5 = icmp eq i64 %and4, 0
268 br i1 %tobool5, label %if.end9, label %if.then6
270 if.then6: ; preds = %if.end
271 %5 = add nsw <2 x i64> %4, <i64 1, i64 1>
272 store <2 x i64> %5, ptr getelementptr inbounds (%struct.Counters, ptr @counters, i64 0, i32 1)
275 if.end9: ; preds = %if.end, %if.then6