1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -select-optimize -mtriple=aarch64-linux-gnu -mcpu=generic -S < %s | FileCheck %s --check-prefix=CHECKOO
3 ; RUN: opt -select-optimize -mtriple=aarch64-linux-gnu -mcpu=cortex-a55 -S < %s | FileCheck %s --check-prefix=CHECKII
4 ; RUN: opt -select-optimize -mtriple=aarch64-linux-gnu -mcpu=cortex-a510 -S < %s | FileCheck %s --check-prefix=CHECKII
5 ; RUN: opt -select-optimize -mtriple=aarch64-linux-gnu -mcpu=cortex-a72 -S < %s | FileCheck %s --check-prefix=CHECKOO
6 ; RUN: opt -select-optimize -mtriple=aarch64-linux-gnu -mcpu=neoverse-n1 -S < %s | FileCheck %s --check-prefix=CHECKOO
7 ; RUN: opt -select-optimize -mtriple=aarch64-linux-gnu -mcpu=cortex-a710 -S < %s | FileCheck %s --check-prefix=CHECKOO
8 ; RUN: opt -select-optimize -mtriple=aarch64-linux-gnu -mcpu=neoverse-v2 -S < %s | FileCheck %s --check-prefix=CHECKOO
9 ; RUN: opt -debugify-and-strip-all-safe -select-optimize -mtriple=aarch64-linux-gnu -mcpu=generic -S < %s | FileCheck %s --check-prefix=CHECKOO
10 ; RUN: opt -passes='require<profile-summary>,function(select-optimize)' -mtriple=aarch64-linux-gnu -mcpu=generic -S < %s | FileCheck %s --check-prefix=CHECKOO
11 ; RUN: opt -passes='require<profile-summary>,function(select-optimize)' -mtriple=aarch64-linux-gnu -mcpu=cortex-a55 -S < %s | FileCheck %s --check-prefix=CHECKII
12 ; RUN: opt -passes='require<profile-summary>,function(select-optimize)' -mtriple=aarch64-linux-gnu -mcpu=cortex-a510 -S < %s | FileCheck %s --check-prefix=CHECKII
13 ; RUN: opt -passes='require<profile-summary>,function(select-optimize)' -mtriple=aarch64-linux-gnu -mcpu=cortex-a72 -S < %s | FileCheck %s --check-prefix=CHECKOO
14 ; RUN: opt -passes='require<profile-summary>,function(select-optimize)' -mtriple=aarch64-linux-gnu -mcpu=neoverse-n1 -S < %s | FileCheck %s --check-prefix=CHECKOO
15 ; RUN: opt -passes='require<profile-summary>,function(select-optimize)' -mtriple=aarch64-linux-gnu -mcpu=cortex-a710 -S < %s | FileCheck %s --check-prefix=CHECKOO
16 ; RUN: opt -passes='require<profile-summary>,function(select-optimize)' -mtriple=aarch64-linux-gnu -mcpu=neoverse-v2 -S < %s | FileCheck %s --check-prefix=CHECKOO
18 %struct.st = type { i32, i64, ptr, ptr, i16, ptr, ptr, i64, i64 }
20 ; This test has a select at the end of if.then, which is better transformed to a branch on OoO cores.
22 define void @replace(ptr nocapture noundef %newst, ptr noundef %t, ptr noundef %h, i64 noundef %c, i64 noundef %rc, i64 noundef %ma, i64 noundef %n) {
23 ; CHECKOO-LABEL: @replace(
24 ; CHECKOO-NEXT: entry:
25 ; CHECKOO-NEXT: [[T1:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], ptr [[NEWST:%.*]], i64 0, i32 2
26 ; CHECKOO-NEXT: store ptr [[T:%.*]], ptr [[T1]], align 8
27 ; CHECKOO-NEXT: [[H3:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 3
28 ; CHECKOO-NEXT: store ptr [[H:%.*]], ptr [[H3]], align 8
29 ; CHECKOO-NEXT: [[ORG_C:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 8
30 ; CHECKOO-NEXT: store i64 [[C:%.*]], ptr [[ORG_C]], align 8
31 ; CHECKOO-NEXT: [[C6:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 1
32 ; CHECKOO-NEXT: store i64 [[C]], ptr [[C6]], align 8
33 ; CHECKOO-NEXT: [[FLOW:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 7
34 ; CHECKOO-NEXT: store i64 [[RC:%.*]], ptr [[FLOW]], align 8
35 ; CHECKOO-NEXT: [[CONV:%.*]] = trunc i64 [[N:%.*]] to i32
36 ; CHECKOO-NEXT: store i32 [[CONV]], ptr [[NEWST]], align 8
37 ; CHECKOO-NEXT: [[FLOW10:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 1, i32 7
38 ; CHECKOO-NEXT: [[TMP0:%.*]] = load i64, ptr [[FLOW10]], align 8
39 ; CHECKOO-NEXT: [[FLOW12:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 2, i32 7
40 ; CHECKOO-NEXT: [[TMP1:%.*]] = load i64, ptr [[FLOW12]], align 8
41 ; CHECKOO-NEXT: [[CMP13:%.*]] = icmp sgt i64 [[TMP0]], [[TMP1]]
42 ; CHECKOO-NEXT: [[CONV15:%.*]] = select i1 [[CMP13]], i64 2, i64 3
43 ; CHECKOO-NEXT: [[CMP16_NOT149:%.*]] = icmp sgt i64 [[CONV15]], [[MA:%.*]]
44 ; CHECKOO-NEXT: br i1 [[CMP16_NOT149]], label [[WHILE_END:%.*]], label [[LAND_RHS:%.*]]
46 ; CHECKOO-NEXT: [[CMP_0151:%.*]] = phi i64 [ [[CMP_1:%.*]], [[IF_END87:%.*]] ], [ [[CONV15]], [[ENTRY:%.*]] ]
47 ; CHECKOO-NEXT: [[POS_0150:%.*]] = phi i64 [ [[CMP_0151]], [[IF_END87]] ], [ 1, [[ENTRY]] ]
48 ; CHECKOO-NEXT: [[SUB:%.*]] = add nsw i64 [[CMP_0151]], -1
49 ; CHECKOO-NEXT: [[FLOW19:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 7
50 ; CHECKOO-NEXT: [[TMP2:%.*]] = load i64, ptr [[FLOW19]], align 8
51 ; CHECKOO-NEXT: [[CMP20:%.*]] = icmp sgt i64 [[TMP2]], [[RC]]
52 ; CHECKOO-NEXT: br i1 [[CMP20]], label [[WHILE_BODY:%.*]], label [[WHILE_END]]
53 ; CHECKOO: while.body:
54 ; CHECKOO-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]]
55 ; CHECKOO-NEXT: [[T24:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 2
56 ; CHECKOO-NEXT: [[TMP3:%.*]] = load ptr, ptr [[T24]], align 8
57 ; CHECKOO-NEXT: [[SUB25:%.*]] = add nsw i64 [[POS_0150]], -1
58 ; CHECKOO-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]]
59 ; CHECKOO-NEXT: [[T27:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 2
60 ; CHECKOO-NEXT: store ptr [[TMP3]], ptr [[T27]], align 8
61 ; CHECKOO-NEXT: [[H30:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 3
62 ; CHECKOO-NEXT: [[TMP4:%.*]] = load ptr, ptr [[H30]], align 8
63 ; CHECKOO-NEXT: [[H33:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 3
64 ; CHECKOO-NEXT: store ptr [[TMP4]], ptr [[H33]], align 8
65 ; CHECKOO-NEXT: [[C36:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 1
66 ; CHECKOO-NEXT: [[TMP5:%.*]] = load i64, ptr [[C36]], align 8
67 ; CHECKOO-NEXT: [[C39:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 1
68 ; CHECKOO-NEXT: store i64 [[TMP5]], ptr [[C39]], align 8
69 ; CHECKOO-NEXT: [[TMP6:%.*]] = load i64, ptr [[C36]], align 8
70 ; CHECKOO-NEXT: [[ORG_C45:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 8
71 ; CHECKOO-NEXT: store i64 [[TMP6]], ptr [[ORG_C45]], align 8
72 ; CHECKOO-NEXT: [[FLOW51:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 7
73 ; CHECKOO-NEXT: store i64 [[TMP2]], ptr [[FLOW51]], align 8
74 ; CHECKOO-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX18]], align 8
75 ; CHECKOO-NEXT: store i32 [[TMP7]], ptr [[ARRAYIDX26]], align 8
76 ; CHECKOO-NEXT: store ptr [[T]], ptr [[T24]], align 8
77 ; CHECKOO-NEXT: store ptr [[H]], ptr [[H30]], align 8
78 ; CHECKOO-NEXT: store i64 [[C]], ptr [[C36]], align 8
79 ; CHECKOO-NEXT: [[ORG_C69:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 8
80 ; CHECKOO-NEXT: store i64 [[C]], ptr [[ORG_C69]], align 8
81 ; CHECKOO-NEXT: store i64 [[RC]], ptr [[FLOW19]], align 8
82 ; CHECKOO-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX18]], align 8
83 ; CHECKOO-NEXT: [[MUL:%.*]] = shl nsw i64 [[CMP_0151]], 1
84 ; CHECKOO-NEXT: [[ADD:%.*]] = or i64 [[MUL]], 1
85 ; CHECKOO-NEXT: [[CMP77_NOT:%.*]] = icmp sgt i64 [[ADD]], [[MA]]
86 ; CHECKOO-NEXT: br i1 [[CMP77_NOT]], label [[IF_END87]], label [[IF_THEN:%.*]]
88 ; CHECKOO-NEXT: [[SUB79:%.*]] = add nsw i64 [[MUL]], -1
89 ; CHECKOO-NEXT: [[FLOW81:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB79]], i32 7
90 ; CHECKOO-NEXT: [[TMP8:%.*]] = load i64, ptr [[FLOW81]], align 8
91 ; CHECKOO-NEXT: [[FLOW83:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[MUL]], i32 7
92 ; CHECKOO-NEXT: [[TMP9:%.*]] = load i64, ptr [[FLOW83]], align 8
93 ; CHECKOO-NEXT: [[CMP84:%.*]] = icmp slt i64 [[TMP8]], [[TMP9]]
94 ; CHECKOO-NEXT: [[SPEC_SELECT_FROZEN:%.*]] = freeze i1 [[CMP84]]
95 ; CHECKOO-NEXT: br i1 [[SPEC_SELECT_FROZEN]], label [[SELECT_END:%.*]], label [[SELECT_FALSE:%.*]]
96 ; CHECKOO: select.false:
97 ; CHECKOO-NEXT: br label [[SELECT_END]]
98 ; CHECKOO: select.end:
99 ; CHECKOO-NEXT: [[SPEC_SELECT:%.*]] = phi i64 [ [[ADD]], [[IF_THEN]] ], [ [[MUL]], [[SELECT_FALSE]] ]
100 ; CHECKOO-NEXT: br label [[IF_END87]]
102 ; CHECKOO-NEXT: [[CMP_1]] = phi i64 [ [[MUL]], [[WHILE_BODY]] ], [ [[SPEC_SELECT]], [[SELECT_END]] ]
103 ; CHECKOO-NEXT: [[CMP16_NOT:%.*]] = icmp sgt i64 [[CMP_1]], [[MA]]
104 ; CHECKOO-NEXT: br i1 [[CMP16_NOT]], label [[WHILE_END]], label [[LAND_RHS]]
105 ; CHECKOO: while.end:
106 ; CHECKOO-NEXT: ret void
108 ; CHECKII-LABEL: @replace(
109 ; CHECKII-NEXT: entry:
110 ; CHECKII-NEXT: [[T1:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], ptr [[NEWST:%.*]], i64 0, i32 2
111 ; CHECKII-NEXT: store ptr [[T:%.*]], ptr [[T1]], align 8
112 ; CHECKII-NEXT: [[H3:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 3
113 ; CHECKII-NEXT: store ptr [[H:%.*]], ptr [[H3]], align 8
114 ; CHECKII-NEXT: [[ORG_C:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 8
115 ; CHECKII-NEXT: store i64 [[C:%.*]], ptr [[ORG_C]], align 8
116 ; CHECKII-NEXT: [[C6:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 1
117 ; CHECKII-NEXT: store i64 [[C]], ptr [[C6]], align 8
118 ; CHECKII-NEXT: [[FLOW:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 7
119 ; CHECKII-NEXT: store i64 [[RC:%.*]], ptr [[FLOW]], align 8
120 ; CHECKII-NEXT: [[CONV:%.*]] = trunc i64 [[N:%.*]] to i32
121 ; CHECKII-NEXT: store i32 [[CONV]], ptr [[NEWST]], align 8
122 ; CHECKII-NEXT: [[FLOW10:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 1, i32 7
123 ; CHECKII-NEXT: [[TMP0:%.*]] = load i64, ptr [[FLOW10]], align 8
124 ; CHECKII-NEXT: [[FLOW12:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 2, i32 7
125 ; CHECKII-NEXT: [[TMP1:%.*]] = load i64, ptr [[FLOW12]], align 8
126 ; CHECKII-NEXT: [[CMP13:%.*]] = icmp sgt i64 [[TMP0]], [[TMP1]]
127 ; CHECKII-NEXT: [[CONV15:%.*]] = select i1 [[CMP13]], i64 2, i64 3
128 ; CHECKII-NEXT: [[CMP16_NOT149:%.*]] = icmp sgt i64 [[CONV15]], [[MA:%.*]]
129 ; CHECKII-NEXT: br i1 [[CMP16_NOT149]], label [[WHILE_END:%.*]], label [[LAND_RHS:%.*]]
131 ; CHECKII-NEXT: [[CMP_0151:%.*]] = phi i64 [ [[CMP_1:%.*]], [[IF_END87:%.*]] ], [ [[CONV15]], [[ENTRY:%.*]] ]
132 ; CHECKII-NEXT: [[POS_0150:%.*]] = phi i64 [ [[CMP_0151]], [[IF_END87]] ], [ 1, [[ENTRY]] ]
133 ; CHECKII-NEXT: [[SUB:%.*]] = add nsw i64 [[CMP_0151]], -1
134 ; CHECKII-NEXT: [[FLOW19:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 7
135 ; CHECKII-NEXT: [[TMP2:%.*]] = load i64, ptr [[FLOW19]], align 8
136 ; CHECKII-NEXT: [[CMP20:%.*]] = icmp sgt i64 [[TMP2]], [[RC]]
137 ; CHECKII-NEXT: br i1 [[CMP20]], label [[WHILE_BODY:%.*]], label [[WHILE_END]]
138 ; CHECKII: while.body:
139 ; CHECKII-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]]
140 ; CHECKII-NEXT: [[T24:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 2
141 ; CHECKII-NEXT: [[TMP3:%.*]] = load ptr, ptr [[T24]], align 8
142 ; CHECKII-NEXT: [[SUB25:%.*]] = add nsw i64 [[POS_0150]], -1
143 ; CHECKII-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]]
144 ; CHECKII-NEXT: [[T27:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 2
145 ; CHECKII-NEXT: store ptr [[TMP3]], ptr [[T27]], align 8
146 ; CHECKII-NEXT: [[H30:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 3
147 ; CHECKII-NEXT: [[TMP4:%.*]] = load ptr, ptr [[H30]], align 8
148 ; CHECKII-NEXT: [[H33:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 3
149 ; CHECKII-NEXT: store ptr [[TMP4]], ptr [[H33]], align 8
150 ; CHECKII-NEXT: [[C36:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 1
151 ; CHECKII-NEXT: [[TMP5:%.*]] = load i64, ptr [[C36]], align 8
152 ; CHECKII-NEXT: [[C39:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 1
153 ; CHECKII-NEXT: store i64 [[TMP5]], ptr [[C39]], align 8
154 ; CHECKII-NEXT: [[TMP6:%.*]] = load i64, ptr [[C36]], align 8
155 ; CHECKII-NEXT: [[ORG_C45:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 8
156 ; CHECKII-NEXT: store i64 [[TMP6]], ptr [[ORG_C45]], align 8
157 ; CHECKII-NEXT: [[FLOW51:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 7
158 ; CHECKII-NEXT: store i64 [[TMP2]], ptr [[FLOW51]], align 8
159 ; CHECKII-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX18]], align 8
160 ; CHECKII-NEXT: store i32 [[TMP7]], ptr [[ARRAYIDX26]], align 8
161 ; CHECKII-NEXT: store ptr [[T]], ptr [[T24]], align 8
162 ; CHECKII-NEXT: store ptr [[H]], ptr [[H30]], align 8
163 ; CHECKII-NEXT: store i64 [[C]], ptr [[C36]], align 8
164 ; CHECKII-NEXT: [[ORG_C69:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 8
165 ; CHECKII-NEXT: store i64 [[C]], ptr [[ORG_C69]], align 8
166 ; CHECKII-NEXT: store i64 [[RC]], ptr [[FLOW19]], align 8
167 ; CHECKII-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX18]], align 8
168 ; CHECKII-NEXT: [[MUL:%.*]] = shl nsw i64 [[CMP_0151]], 1
169 ; CHECKII-NEXT: [[ADD:%.*]] = or i64 [[MUL]], 1
170 ; CHECKII-NEXT: [[CMP77_NOT:%.*]] = icmp sgt i64 [[ADD]], [[MA]]
171 ; CHECKII-NEXT: br i1 [[CMP77_NOT]], label [[IF_END87]], label [[IF_THEN:%.*]]
173 ; CHECKII-NEXT: [[SUB79:%.*]] = add nsw i64 [[MUL]], -1
174 ; CHECKII-NEXT: [[FLOW81:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB79]], i32 7
175 ; CHECKII-NEXT: [[TMP8:%.*]] = load i64, ptr [[FLOW81]], align 8
176 ; CHECKII-NEXT: [[FLOW83:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[MUL]], i32 7
177 ; CHECKII-NEXT: [[TMP9:%.*]] = load i64, ptr [[FLOW83]], align 8
178 ; CHECKII-NEXT: [[CMP84:%.*]] = icmp slt i64 [[TMP8]], [[TMP9]]
179 ; CHECKII-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP84]], i64 [[ADD]], i64 [[MUL]]
180 ; CHECKII-NEXT: br label [[IF_END87]]
182 ; CHECKII-NEXT: [[CMP_1]] = phi i64 [ [[MUL]], [[WHILE_BODY]] ], [ [[SPEC_SELECT]], [[IF_THEN]] ]
183 ; CHECKII-NEXT: [[CMP16_NOT:%.*]] = icmp sgt i64 [[CMP_1]], [[MA]]
184 ; CHECKII-NEXT: br i1 [[CMP16_NOT]], label [[WHILE_END]], label [[LAND_RHS]]
185 ; CHECKII: while.end:
186 ; CHECKII-NEXT: ret void
189 %t1 = getelementptr inbounds %struct.st, ptr %newst, i64 0, i32 2
190 store ptr %t, ptr %t1, align 8
191 %h3 = getelementptr inbounds %struct.st, ptr %newst, i64 0, i32 3
192 store ptr %h, ptr %h3, align 8
193 %org_c = getelementptr inbounds %struct.st, ptr %newst, i64 0, i32 8
194 store i64 %c, ptr %org_c, align 8
195 %c6 = getelementptr inbounds %struct.st, ptr %newst, i64 0, i32 1
196 store i64 %c, ptr %c6, align 8
197 %flow = getelementptr inbounds %struct.st, ptr %newst, i64 0, i32 7
198 store i64 %rc, ptr %flow, align 8
199 %conv = trunc i64 %n to i32
200 store i32 %conv, ptr %newst, align 8
201 %flow10 = getelementptr inbounds %struct.st, ptr %newst, i64 1, i32 7
202 %0 = load i64, ptr %flow10, align 8
203 %flow12 = getelementptr inbounds %struct.st, ptr %newst, i64 2, i32 7
204 %1 = load i64, ptr %flow12, align 8
205 %cmp13 = icmp sgt i64 %0, %1
206 %conv15 = select i1 %cmp13, i64 2, i64 3
207 %cmp16.not149 = icmp sgt i64 %conv15, %ma
208 br i1 %cmp16.not149, label %while.end, label %land.rhs
210 land.rhs: ; preds = %entry, %if.end87
211 %cmp.0151 = phi i64 [ %cmp.1, %if.end87 ], [ %conv15, %entry ]
212 %pos.0150 = phi i64 [ %cmp.0151, %if.end87 ], [ 1, %entry ]
213 %sub = add nsw i64 %cmp.0151, -1
214 %flow19 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub, i32 7
215 %2 = load i64, ptr %flow19, align 8
216 %cmp20 = icmp sgt i64 %2, %rc
217 br i1 %cmp20, label %while.body, label %while.end
219 while.body: ; preds = %land.rhs
220 %arrayidx18 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub
221 %t24 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub, i32 2
222 %3 = load ptr, ptr %t24, align 8
223 %sub25 = add nsw i64 %pos.0150, -1
224 %arrayidx26 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25
225 %t27 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25, i32 2
226 store ptr %3, ptr %t27, align 8
227 %h30 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub, i32 3
228 %4 = load ptr, ptr %h30, align 8
229 %h33 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25, i32 3
230 store ptr %4, ptr %h33, align 8
231 %c36 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub, i32 1
232 %5 = load i64, ptr %c36, align 8
233 %c39 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25, i32 1
234 store i64 %5, ptr %c39, align 8
235 %6 = load i64, ptr %c36, align 8
236 %org_c45 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25, i32 8
237 store i64 %6, ptr %org_c45, align 8
238 %flow51 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25, i32 7
239 store i64 %2, ptr %flow51, align 8
240 %7 = load i32, ptr %arrayidx18, align 8
241 store i32 %7, ptr %arrayidx26, align 8
242 store ptr %t, ptr %t24, align 8
243 store ptr %h, ptr %h30, align 8
244 store i64 %c, ptr %c36, align 8
245 %org_c69 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub, i32 8
246 store i64 %c, ptr %org_c69, align 8
247 store i64 %rc, ptr %flow19, align 8
248 store i32 %conv, ptr %arrayidx18, align 8
249 %mul = shl nsw i64 %cmp.0151, 1
250 %add = or i64 %mul, 1
251 %cmp77.not = icmp sgt i64 %add, %ma
252 br i1 %cmp77.not, label %if.end87, label %if.then
254 if.then: ; preds = %while.body
255 %sub79 = add nsw i64 %mul, -1
256 %flow81 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub79, i32 7
257 %8 = load i64, ptr %flow81, align 8
258 %flow83 = getelementptr inbounds %struct.st, ptr %newst, i64 %mul, i32 7
259 %9 = load i64, ptr %flow83, align 8
260 %cmp84 = icmp slt i64 %8, %9
261 %spec.select = select i1 %cmp84, i64 %add, i64 %mul
264 if.end87: ; preds = %if.then, %while.body
265 %cmp.1 = phi i64 [ %mul, %while.body ], [ %spec.select, %if.then ]
266 %cmp16.not = icmp sgt i64 %cmp.1, %ma
267 br i1 %cmp16.not, label %while.end, label %land.rhs
269 while.end: ; preds = %land.rhs, %if.end87, %entry
274 define void @replace_or(ptr nocapture noundef %newst, ptr noundef %t, ptr noundef %h, i64 noundef %c, i64 noundef %rc, i64 noundef %ma, i64 noundef %n) {
275 ; CHECKOO-LABEL: @replace_or(
276 ; CHECKOO-NEXT: entry:
277 ; CHECKOO-NEXT: [[T1:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], ptr [[NEWST:%.*]], i64 0, i32 2
278 ; CHECKOO-NEXT: store ptr [[T:%.*]], ptr [[T1]], align 8
279 ; CHECKOO-NEXT: [[H3:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 3
280 ; CHECKOO-NEXT: store ptr [[H:%.*]], ptr [[H3]], align 8
281 ; CHECKOO-NEXT: [[ORG_C:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 8
282 ; CHECKOO-NEXT: store i64 [[C:%.*]], ptr [[ORG_C]], align 8
283 ; CHECKOO-NEXT: [[C6:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 1
284 ; CHECKOO-NEXT: store i64 [[C]], ptr [[C6]], align 8
285 ; CHECKOO-NEXT: [[FLOW:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 7
286 ; CHECKOO-NEXT: store i64 [[RC:%.*]], ptr [[FLOW]], align 8
287 ; CHECKOO-NEXT: [[CONV:%.*]] = trunc i64 [[N:%.*]] to i32
288 ; CHECKOO-NEXT: store i32 [[CONV]], ptr [[NEWST]], align 8
289 ; CHECKOO-NEXT: [[FLOW10:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 1, i32 7
290 ; CHECKOO-NEXT: [[TMP0:%.*]] = load i64, ptr [[FLOW10]], align 8
291 ; CHECKOO-NEXT: [[FLOW12:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 2, i32 7
292 ; CHECKOO-NEXT: [[TMP1:%.*]] = load i64, ptr [[FLOW12]], align 8
293 ; CHECKOO-NEXT: [[CMP13:%.*]] = icmp sgt i64 [[TMP0]], [[TMP1]]
294 ; CHECKOO-NEXT: [[CONV15:%.*]] = select i1 [[CMP13]], i64 2, i64 3
295 ; CHECKOO-NEXT: [[CMP16_NOT149:%.*]] = icmp sgt i64 [[CONV15]], [[MA:%.*]]
296 ; CHECKOO-NEXT: br i1 [[CMP16_NOT149]], label [[WHILE_END:%.*]], label [[LAND_RHS:%.*]]
298 ; CHECKOO-NEXT: [[CMP_0151:%.*]] = phi i64 [ [[CMP_1:%.*]], [[IF_END87:%.*]] ], [ [[CONV15]], [[ENTRY:%.*]] ]
299 ; CHECKOO-NEXT: [[POS_0150:%.*]] = phi i64 [ [[CMP_0151]], [[IF_END87]] ], [ 1, [[ENTRY]] ]
300 ; CHECKOO-NEXT: [[SUB:%.*]] = add nsw i64 [[CMP_0151]], -1
301 ; CHECKOO-NEXT: [[FLOW19:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 7
302 ; CHECKOO-NEXT: [[TMP2:%.*]] = load i64, ptr [[FLOW19]], align 8
303 ; CHECKOO-NEXT: [[CMP20:%.*]] = icmp sgt i64 [[TMP2]], [[RC]]
304 ; CHECKOO-NEXT: br i1 [[CMP20]], label [[WHILE_BODY:%.*]], label [[WHILE_END]]
305 ; CHECKOO: while.body:
306 ; CHECKOO-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]]
307 ; CHECKOO-NEXT: [[T24:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 2
308 ; CHECKOO-NEXT: [[TMP3:%.*]] = load ptr, ptr [[T24]], align 8
309 ; CHECKOO-NEXT: [[SUB25:%.*]] = add nsw i64 [[POS_0150]], -1
310 ; CHECKOO-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]]
311 ; CHECKOO-NEXT: [[T27:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 2
312 ; CHECKOO-NEXT: store ptr [[TMP3]], ptr [[T27]], align 8
313 ; CHECKOO-NEXT: [[H30:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 3
314 ; CHECKOO-NEXT: [[TMP4:%.*]] = load ptr, ptr [[H30]], align 8
315 ; CHECKOO-NEXT: [[H33:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 3
316 ; CHECKOO-NEXT: store ptr [[TMP4]], ptr [[H33]], align 8
317 ; CHECKOO-NEXT: [[C36:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 1
318 ; CHECKOO-NEXT: [[TMP5:%.*]] = load i64, ptr [[C36]], align 8
319 ; CHECKOO-NEXT: [[C39:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 1
320 ; CHECKOO-NEXT: store i64 [[TMP5]], ptr [[C39]], align 8
321 ; CHECKOO-NEXT: [[ORG_C45:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 8
322 ; CHECKOO-NEXT: store i64 [[TMP5]], ptr [[ORG_C45]], align 8
323 ; CHECKOO-NEXT: [[FLOW51:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 7
324 ; CHECKOO-NEXT: store i64 [[TMP2]], ptr [[FLOW51]], align 8
325 ; CHECKOO-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX18]], align 8
326 ; CHECKOO-NEXT: store i32 [[TMP6]], ptr [[ARRAYIDX26]], align 8
327 ; CHECKOO-NEXT: store ptr [[T]], ptr [[T24]], align 8
328 ; CHECKOO-NEXT: store ptr [[H]], ptr [[H30]], align 8
329 ; CHECKOO-NEXT: store i64 [[C]], ptr [[C36]], align 8
330 ; CHECKOO-NEXT: [[ORG_C69:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 8
331 ; CHECKOO-NEXT: store i64 [[C]], ptr [[ORG_C69]], align 8
332 ; CHECKOO-NEXT: store i64 [[RC]], ptr [[FLOW19]], align 8
333 ; CHECKOO-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX18]], align 8
334 ; CHECKOO-NEXT: [[MUL:%.*]] = shl nsw i64 [[CMP_0151]], 1
335 ; CHECKOO-NEXT: [[CMP77_NOT_NOT:%.*]] = icmp slt i64 [[MUL]], [[MA]]
336 ; CHECKOO-NEXT: br i1 [[CMP77_NOT_NOT]], label [[IF_THEN:%.*]], label [[IF_END87]]
338 ; CHECKOO-NEXT: [[SUB79:%.*]] = add nsw i64 [[MUL]], -1
339 ; CHECKOO-NEXT: [[FLOW81:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB79]], i32 7
340 ; CHECKOO-NEXT: [[TMP7:%.*]] = load i64, ptr [[FLOW81]], align 8
341 ; CHECKOO-NEXT: [[FLOW83:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[MUL]], i32 7
342 ; CHECKOO-NEXT: [[TMP8:%.*]] = load i64, ptr [[FLOW83]], align 8
343 ; CHECKOO-NEXT: [[CMP84:%.*]] = icmp slt i64 [[TMP7]], [[TMP8]]
344 ; CHECKOO-NEXT: [[ADD:%.*]] = zext i1 [[CMP84]] to i64
345 ; CHECKOO-NEXT: [[CMP84_FROZEN:%.*]] = freeze i1 [[CMP84]]
346 ; CHECKOO-NEXT: br i1 [[CMP84_FROZEN]], label [[SELECT_END:%.*]], label [[SELECT_FALSE:%.*]]
347 ; CHECKOO: select.true.sink:
348 ; CHECKOO-NEXT: [[TMP9:%.*]] = or disjoint i64 [[MUL]], 1
349 ; CHECKOO-NEXT: br label [[SELECT_FALSE]]
350 ; CHECKOO: select.end:
351 ; CHECKOO-NEXT: [[SPEC_SELECT:%.*]] = phi i64 [ [[TMP9]], [[SELECT_END]] ], [ [[MUL]], [[IF_THEN]] ]
352 ; CHECKOO-NEXT: br label [[IF_END87]]
354 ; CHECKOO-NEXT: [[CMP_1]] = phi i64 [ [[MUL]], [[WHILE_BODY]] ], [ [[SPEC_SELECT]], [[SELECT_FALSE]] ]
355 ; CHECKOO-NEXT: [[CMP16_NOT:%.*]] = icmp sgt i64 [[CMP_1]], [[MA]]
356 ; CHECKOO-NEXT: br i1 [[CMP16_NOT]], label [[WHILE_END]], label [[LAND_RHS]]
357 ; CHECKOO: while.end:
358 ; CHECKOO-NEXT: ret void
360 ; CHECKII-LABEL: @replace_or(
361 ; CHECKII-NEXT: entry:
362 ; CHECKII-NEXT: [[T1:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], ptr [[NEWST:%.*]], i64 0, i32 2
363 ; CHECKII-NEXT: store ptr [[T:%.*]], ptr [[T1]], align 8
364 ; CHECKII-NEXT: [[H3:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 3
365 ; CHECKII-NEXT: store ptr [[H:%.*]], ptr [[H3]], align 8
366 ; CHECKII-NEXT: [[ORG_C:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 8
367 ; CHECKII-NEXT: store i64 [[C:%.*]], ptr [[ORG_C]], align 8
368 ; CHECKII-NEXT: [[C6:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 1
369 ; CHECKII-NEXT: store i64 [[C]], ptr [[C6]], align 8
370 ; CHECKII-NEXT: [[FLOW:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 0, i32 7
371 ; CHECKII-NEXT: store i64 [[RC:%.*]], ptr [[FLOW]], align 8
372 ; CHECKII-NEXT: [[CONV:%.*]] = trunc i64 [[N:%.*]] to i32
373 ; CHECKII-NEXT: store i32 [[CONV]], ptr [[NEWST]], align 8
374 ; CHECKII-NEXT: [[FLOW10:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 1, i32 7
375 ; CHECKII-NEXT: [[TMP0:%.*]] = load i64, ptr [[FLOW10]], align 8
376 ; CHECKII-NEXT: [[FLOW12:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 2, i32 7
377 ; CHECKII-NEXT: [[TMP1:%.*]] = load i64, ptr [[FLOW12]], align 8
378 ; CHECKII-NEXT: [[CMP13:%.*]] = icmp sgt i64 [[TMP0]], [[TMP1]]
379 ; CHECKII-NEXT: [[CONV15:%.*]] = select i1 [[CMP13]], i64 2, i64 3
380 ; CHECKII-NEXT: [[CMP16_NOT149:%.*]] = icmp sgt i64 [[CONV15]], [[MA:%.*]]
381 ; CHECKII-NEXT: br i1 [[CMP16_NOT149]], label [[WHILE_END:%.*]], label [[LAND_RHS:%.*]]
383 ; CHECKII-NEXT: [[CMP_0151:%.*]] = phi i64 [ [[CMP_1:%.*]], [[IF_END87:%.*]] ], [ [[CONV15]], [[ENTRY:%.*]] ]
384 ; CHECKII-NEXT: [[POS_0150:%.*]] = phi i64 [ [[CMP_0151]], [[IF_END87]] ], [ 1, [[ENTRY]] ]
385 ; CHECKII-NEXT: [[SUB:%.*]] = add nsw i64 [[CMP_0151]], -1
386 ; CHECKII-NEXT: [[FLOW19:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 7
387 ; CHECKII-NEXT: [[TMP2:%.*]] = load i64, ptr [[FLOW19]], align 8
388 ; CHECKII-NEXT: [[CMP20:%.*]] = icmp sgt i64 [[TMP2]], [[RC]]
389 ; CHECKII-NEXT: br i1 [[CMP20]], label [[WHILE_BODY:%.*]], label [[WHILE_END]]
390 ; CHECKII: while.body:
391 ; CHECKII-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]]
392 ; CHECKII-NEXT: [[T24:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 2
393 ; CHECKII-NEXT: [[TMP3:%.*]] = load ptr, ptr [[T24]], align 8
394 ; CHECKII-NEXT: [[SUB25:%.*]] = add nsw i64 [[POS_0150]], -1
395 ; CHECKII-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]]
396 ; CHECKII-NEXT: [[T27:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 2
397 ; CHECKII-NEXT: store ptr [[TMP3]], ptr [[T27]], align 8
398 ; CHECKII-NEXT: [[H30:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 3
399 ; CHECKII-NEXT: [[TMP4:%.*]] = load ptr, ptr [[H30]], align 8
400 ; CHECKII-NEXT: [[H33:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 3
401 ; CHECKII-NEXT: store ptr [[TMP4]], ptr [[H33]], align 8
402 ; CHECKII-NEXT: [[C36:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 1
403 ; CHECKII-NEXT: [[TMP5:%.*]] = load i64, ptr [[C36]], align 8
404 ; CHECKII-NEXT: [[C39:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 1
405 ; CHECKII-NEXT: store i64 [[TMP5]], ptr [[C39]], align 8
406 ; CHECKII-NEXT: [[ORG_C45:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 8
407 ; CHECKII-NEXT: store i64 [[TMP5]], ptr [[ORG_C45]], align 8
408 ; CHECKII-NEXT: [[FLOW51:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB25]], i32 7
409 ; CHECKII-NEXT: store i64 [[TMP2]], ptr [[FLOW51]], align 8
410 ; CHECKII-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX18]], align 8
411 ; CHECKII-NEXT: store i32 [[TMP6]], ptr [[ARRAYIDX26]], align 8
412 ; CHECKII-NEXT: store ptr [[T]], ptr [[T24]], align 8
413 ; CHECKII-NEXT: store ptr [[H]], ptr [[H30]], align 8
414 ; CHECKII-NEXT: store i64 [[C]], ptr [[C36]], align 8
415 ; CHECKII-NEXT: [[ORG_C69:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB]], i32 8
416 ; CHECKII-NEXT: store i64 [[C]], ptr [[ORG_C69]], align 8
417 ; CHECKII-NEXT: store i64 [[RC]], ptr [[FLOW19]], align 8
418 ; CHECKII-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX18]], align 8
419 ; CHECKII-NEXT: [[MUL:%.*]] = shl nsw i64 [[CMP_0151]], 1
420 ; CHECKII-NEXT: [[CMP77_NOT_NOT:%.*]] = icmp slt i64 [[MUL]], [[MA]]
421 ; CHECKII-NEXT: br i1 [[CMP77_NOT_NOT]], label [[IF_THEN:%.*]], label [[IF_END87]]
423 ; CHECKII-NEXT: [[SUB79:%.*]] = add nsw i64 [[MUL]], -1
424 ; CHECKII-NEXT: [[FLOW81:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[SUB79]], i32 7
425 ; CHECKII-NEXT: [[TMP7:%.*]] = load i64, ptr [[FLOW81]], align 8
426 ; CHECKII-NEXT: [[FLOW83:%.*]] = getelementptr inbounds [[STRUCT_ST]], ptr [[NEWST]], i64 [[MUL]], i32 7
427 ; CHECKII-NEXT: [[TMP8:%.*]] = load i64, ptr [[FLOW83]], align 8
428 ; CHECKII-NEXT: [[CMP84:%.*]] = icmp slt i64 [[TMP7]], [[TMP8]]
429 ; CHECKII-NEXT: [[ADD:%.*]] = zext i1 [[CMP84]] to i64
430 ; CHECKII-NEXT: [[SPEC_SELECT:%.*]] = or disjoint i64 [[MUL]], [[ADD]]
431 ; CHECKII-NEXT: br label [[IF_END87]]
433 ; CHECKII-NEXT: [[CMP_1]] = phi i64 [ [[MUL]], [[WHILE_BODY]] ], [ [[SPEC_SELECT]], [[IF_THEN]] ]
434 ; CHECKII-NEXT: [[CMP16_NOT:%.*]] = icmp sgt i64 [[CMP_1]], [[MA]]
435 ; CHECKII-NEXT: br i1 [[CMP16_NOT]], label [[WHILE_END]], label [[LAND_RHS]]
436 ; CHECKII: while.end:
437 ; CHECKII-NEXT: ret void
440 %t1 = getelementptr inbounds %struct.st, ptr %newst, i64 0, i32 2
441 store ptr %t, ptr %t1, align 8
442 %h3 = getelementptr inbounds %struct.st, ptr %newst, i64 0, i32 3
443 store ptr %h, ptr %h3, align 8
444 %org_c = getelementptr inbounds %struct.st, ptr %newst, i64 0, i32 8
445 store i64 %c, ptr %org_c, align 8
446 %c6 = getelementptr inbounds %struct.st, ptr %newst, i64 0, i32 1
447 store i64 %c, ptr %c6, align 8
448 %flow = getelementptr inbounds %struct.st, ptr %newst, i64 0, i32 7
449 store i64 %rc, ptr %flow, align 8
450 %conv = trunc i64 %n to i32
451 store i32 %conv, ptr %newst, align 8
452 %flow10 = getelementptr inbounds %struct.st, ptr %newst, i64 1, i32 7
453 %0 = load i64, ptr %flow10, align 8
454 %flow12 = getelementptr inbounds %struct.st, ptr %newst, i64 2, i32 7
455 %1 = load i64, ptr %flow12, align 8
456 %cmp13 = icmp sgt i64 %0, %1
457 %conv15 = select i1 %cmp13, i64 2, i64 3
458 %cmp16.not149 = icmp sgt i64 %conv15, %ma
459 br i1 %cmp16.not149, label %while.end, label %land.rhs
461 land.rhs: ; preds = %entry, %if.end87
462 %cmp.0151 = phi i64 [ %cmp.1, %if.end87 ], [ %conv15, %entry ]
463 %pos.0150 = phi i64 [ %cmp.0151, %if.end87 ], [ 1, %entry ]
464 %sub = add nsw i64 %cmp.0151, -1
465 %flow19 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub, i32 7
466 %2 = load i64, ptr %flow19, align 8
467 %cmp20 = icmp sgt i64 %2, %rc
468 br i1 %cmp20, label %while.body, label %while.end
470 while.body: ; preds = %land.rhs
471 %arrayidx18 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub
472 %t24 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub, i32 2
473 %3 = load ptr, ptr %t24, align 8
474 %sub25 = add nsw i64 %pos.0150, -1
475 %arrayidx26 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25
476 %t27 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25, i32 2
477 store ptr %3, ptr %t27, align 8
478 %h30 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub, i32 3
479 %4 = load ptr, ptr %h30, align 8
480 %h33 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25, i32 3
481 store ptr %4, ptr %h33, align 8
482 %c36 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub, i32 1
483 %5 = load i64, ptr %c36, align 8
484 %c39 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25, i32 1
485 store i64 %5, ptr %c39, align 8
486 %org_c45 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25, i32 8
487 store i64 %5, ptr %org_c45, align 8
488 %flow51 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub25, i32 7
489 store i64 %2, ptr %flow51, align 8
490 %6 = load i32, ptr %arrayidx18, align 8
491 store i32 %6, ptr %arrayidx26, align 8
492 store ptr %t, ptr %t24, align 8
493 store ptr %h, ptr %h30, align 8
494 store i64 %c, ptr %c36, align 8
495 %org_c69 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub, i32 8
496 store i64 %c, ptr %org_c69, align 8
497 store i64 %rc, ptr %flow19, align 8
498 store i32 %conv, ptr %arrayidx18, align 8
499 %mul = shl nsw i64 %cmp.0151, 1
500 %cmp77.not.not = icmp slt i64 %mul, %ma
501 br i1 %cmp77.not.not, label %if.then, label %if.end87
503 if.then: ; preds = %while.body
504 %sub79 = add nsw i64 %mul, -1
505 %flow81 = getelementptr inbounds %struct.st, ptr %newst, i64 %sub79, i32 7
506 %7 = load i64, ptr %flow81, align 8
507 %flow83 = getelementptr inbounds %struct.st, ptr %newst, i64 %mul, i32 7
508 %8 = load i64, ptr %flow83, align 8
509 %cmp84 = icmp slt i64 %7, %8
510 %add = zext i1 %cmp84 to i64
511 %spec.select = or disjoint i64 %mul, %add
514 if.end87: ; preds = %if.then, %while.body
515 %cmp.1 = phi i64 [ %mul, %while.body ], [ %spec.select, %if.then ]
516 %cmp16.not = icmp sgt i64 %cmp.1, %ma
517 br i1 %cmp16.not, label %while.end, label %land.rhs
519 while.end: ; preds = %if.end87, %land.rhs, %entry
524 ; This `or` is not transformed as it is not the last instruction in the block
525 define i32 @or_notatendofblock(ptr nocapture noundef %x, i32 noundef %n, ptr nocapture noundef readonly %z) {
526 ; CHECKOO-LABEL: @or_notatendofblock(
527 ; CHECKOO-NEXT: entry:
528 ; CHECKOO-NEXT: [[CMP19:%.*]] = icmp sgt i32 [[N:%.*]], 0
529 ; CHECKOO-NEXT: br i1 [[CMP19]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
530 ; CHECKOO: for.body.preheader:
531 ; CHECKOO-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext nneg i32 [[N]] to i64
532 ; CHECKOO-NEXT: br label [[FOR_BODY:%.*]]
533 ; CHECKOO: for.cond.cleanup:
534 ; CHECKOO-NEXT: [[Y_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[Y_1:%.*]], [[IF_END:%.*]] ]
535 ; CHECKOO-NEXT: ret i32 [[Y_0_LCSSA]]
537 ; CHECKOO-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[IF_END]] ]
538 ; CHECKOO-NEXT: [[Y_020:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[Y_1]], [[IF_END]] ]
539 ; CHECKOO-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[X:%.*]], i64 [[INDVARS_IV]]
540 ; CHECKOO-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
541 ; CHECKOO-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[Y_020]]
542 ; CHECKOO-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[ADD]], 0
543 ; CHECKOO-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END]], label [[IF_THEN:%.*]]
545 ; CHECKOO-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[Z:%.*]], i64 [[INDVARS_IV]]
546 ; CHECKOO-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX4]], align 4
547 ; CHECKOO-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP0]], [[TMP1]]
548 ; CHECKOO-NEXT: [[DIV1:%.*]] = sdiv i32 [[DIV]], [[TMP1]]
549 ; CHECKOO-NEXT: [[DIV2:%.*]] = sdiv i32 [[DIV1]], [[TMP1]]
550 ; CHECKOO-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[DIV2]], 0
551 ; CHECKOO-NEXT: [[CONV:%.*]] = zext i1 [[CMP5]] to i32
552 ; CHECKOO-NEXT: [[OR1:%.*]] = or i32 [[CONV]], [[ADD]]
553 ; CHECKOO-NEXT: [[OR:%.*]] = add i32 [[OR1]], 1
554 ; CHECKOO-NEXT: br label [[IF_END]]
556 ; CHECKOO-NEXT: [[Y_1]] = phi i32 [ [[OR]], [[IF_THEN]] ], [ 0, [[FOR_BODY]] ]
557 ; CHECKOO-NEXT: store i32 [[Y_1]], ptr [[ARRAYIDX]], align 4
558 ; CHECKOO-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
559 ; CHECKOO-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
560 ; CHECKOO-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]]
562 ; CHECKII-LABEL: @or_notatendofblock(
563 ; CHECKII-NEXT: entry:
564 ; CHECKII-NEXT: [[CMP19:%.*]] = icmp sgt i32 [[N:%.*]], 0
565 ; CHECKII-NEXT: br i1 [[CMP19]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
566 ; CHECKII: for.body.preheader:
567 ; CHECKII-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext nneg i32 [[N]] to i64
568 ; CHECKII-NEXT: br label [[FOR_BODY:%.*]]
569 ; CHECKII: for.cond.cleanup:
570 ; CHECKII-NEXT: [[Y_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[Y_1:%.*]], [[IF_END:%.*]] ]
571 ; CHECKII-NEXT: ret i32 [[Y_0_LCSSA]]
573 ; CHECKII-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[IF_END]] ]
574 ; CHECKII-NEXT: [[Y_020:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[Y_1]], [[IF_END]] ]
575 ; CHECKII-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[X:%.*]], i64 [[INDVARS_IV]]
576 ; CHECKII-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
577 ; CHECKII-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[Y_020]]
578 ; CHECKII-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[ADD]], 0
579 ; CHECKII-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END]], label [[IF_THEN:%.*]]
581 ; CHECKII-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[Z:%.*]], i64 [[INDVARS_IV]]
582 ; CHECKII-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX4]], align 4
583 ; CHECKII-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP0]], [[TMP1]]
584 ; CHECKII-NEXT: [[DIV1:%.*]] = sdiv i32 [[DIV]], [[TMP1]]
585 ; CHECKII-NEXT: [[DIV2:%.*]] = sdiv i32 [[DIV1]], [[TMP1]]
586 ; CHECKII-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[DIV2]], 0
587 ; CHECKII-NEXT: [[CONV:%.*]] = zext i1 [[CMP5]] to i32
588 ; CHECKII-NEXT: [[OR1:%.*]] = or i32 [[CONV]], [[ADD]]
589 ; CHECKII-NEXT: [[OR:%.*]] = add i32 [[OR1]], 1
590 ; CHECKII-NEXT: br label [[IF_END]]
592 ; CHECKII-NEXT: [[Y_1]] = phi i32 [ [[OR]], [[IF_THEN]] ], [ 0, [[FOR_BODY]] ]
593 ; CHECKII-NEXT: store i32 [[Y_1]], ptr [[ARRAYIDX]], align 4
594 ; CHECKII-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
595 ; CHECKII-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
596 ; CHECKII-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]]
599 %cmp19 = icmp sgt i32 %n, 0
600 br i1 %cmp19, label %for.body.preheader, label %for.cond.cleanup
603 %wide.trip.count = zext nneg i32 %n to i64
607 %y.0.lcssa = phi i32 [ 0, %entry ], [ %y.1, %if.end ]
611 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %if.end ]
612 %y.020 = phi i32 [ 0, %for.body.preheader ], [ %y.1, %if.end ]
613 %arrayidx = getelementptr inbounds i32, ptr %x, i64 %indvars.iv
614 %0 = load i32, ptr %arrayidx, align 4
615 %add = add nsw i32 %0, %y.020
616 %tobool.not = icmp eq i32 %add, 0
617 br i1 %tobool.not, label %if.end, label %if.then
620 %arrayidx4 = getelementptr inbounds i32, ptr %z, i64 %indvars.iv
621 %1 = load i32, ptr %arrayidx4, align 4
622 %div = sdiv i32 %0, %1
623 %div1 = sdiv i32 %div, %1
624 %div2 = sdiv i32 %div1, %1
625 %cmp5 = icmp sgt i32 %div2, 0
626 %conv = zext i1 %cmp5 to i32
627 %or1 = or i32 %conv, %add
628 %or = add i32 %or1, 1
632 %y.1 = phi i32 [ %or, %if.then ], [ 0, %for.body ]
633 store i32 %y.1, ptr %arrayidx, align 4
634 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
635 %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
636 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
640 ; Similar to the last test, an artificial test with the or as the last instruction and a select in the same group.
641 define i32 @or_samegroup(ptr nocapture noundef %x, i32 noundef %n, ptr nocapture noundef readonly %z) {
642 ; CHECKOO-LABEL: @or_samegroup(
643 ; CHECKOO-NEXT: entry:
644 ; CHECKOO-NEXT: [[CMP19:%.*]] = icmp sgt i32 [[N:%.*]], 0
645 ; CHECKOO-NEXT: br i1 [[CMP19]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
646 ; CHECKOO: for.body.preheader:
647 ; CHECKOO-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext nneg i32 [[N]] to i64
648 ; CHECKOO-NEXT: br label [[FOR_BODY:%.*]]
649 ; CHECKOO: for.cond.cleanup:
650 ; CHECKOO-NEXT: [[Y_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[Y_1:%.*]], [[IF_END:%.*]] ]
651 ; CHECKOO-NEXT: ret i32 [[Y_0_LCSSA]]
653 ; CHECKOO-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[IF_END]] ]
654 ; CHECKOO-NEXT: [[Y_020:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[Y_1]], [[IF_END]] ]
655 ; CHECKOO-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[X:%.*]], i64 [[INDVARS_IV]]
656 ; CHECKOO-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
657 ; CHECKOO-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[Y_020]]
658 ; CHECKOO-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[ADD]], 0
659 ; CHECKOO-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END]], label [[IF_THEN:%.*]]
661 ; CHECKOO-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[Z:%.*]], i64 [[INDVARS_IV]]
662 ; CHECKOO-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX4]], align 4
663 ; CHECKOO-NEXT: [[DIV:%.*]] = sdiv i32 [[Y_020]], [[TMP1]]
664 ; CHECKOO-NEXT: [[DIV1:%.*]] = sdiv i32 [[DIV]], [[TMP1]]
665 ; CHECKOO-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[DIV1]], 0
666 ; CHECKOO-NEXT: [[CONV:%.*]] = zext i1 [[CMP5]] to i32
667 ; CHECKOO-NEXT: [[SEL_FROZEN:%.*]] = freeze i1 [[CMP5]]
668 ; CHECKOO-NEXT: br i1 [[SEL_FROZEN]], label [[SELECT_END:%.*]], label [[SELECT_FALSE:%.*]]
669 ; CHECKOO: select.true.sink:
670 ; CHECKOO-NEXT: [[TMP2:%.*]] = or i32 1, [[ADD]]
671 ; CHECKOO-NEXT: br label [[SELECT_FALSE]]
672 ; CHECKOO: select.end:
673 ; CHECKOO-NEXT: [[SEL:%.*]] = phi i32 [ [[ADD]], [[SELECT_END]] ], [ 1, [[IF_THEN]] ]
674 ; CHECKOO-NEXT: [[OR:%.*]] = phi i32 [ [[TMP2]], [[SELECT_END]] ], [ 1, [[IF_THEN]] ]
675 ; CHECKOO-NEXT: br label [[IF_END]]
677 ; CHECKOO-NEXT: [[Y_1]] = phi i32 [ [[SEL]], [[SELECT_FALSE]] ], [ 0, [[FOR_BODY]] ]
678 ; CHECKOO-NEXT: store i32 [[Y_1]], ptr [[ARRAYIDX]], align 4
679 ; CHECKOO-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
680 ; CHECKOO-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
681 ; CHECKOO-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]]
683 ; CHECKII-LABEL: @or_samegroup(
684 ; CHECKII-NEXT: entry:
685 ; CHECKII-NEXT: [[CMP19:%.*]] = icmp sgt i32 [[N:%.*]], 0
686 ; CHECKII-NEXT: br i1 [[CMP19]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
687 ; CHECKII: for.body.preheader:
688 ; CHECKII-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext nneg i32 [[N]] to i64
689 ; CHECKII-NEXT: br label [[FOR_BODY:%.*]]
690 ; CHECKII: for.cond.cleanup:
691 ; CHECKII-NEXT: [[Y_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[Y_1:%.*]], [[IF_END:%.*]] ]
692 ; CHECKII-NEXT: ret i32 [[Y_0_LCSSA]]
694 ; CHECKII-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[IF_END]] ]
695 ; CHECKII-NEXT: [[Y_020:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[Y_1]], [[IF_END]] ]
696 ; CHECKII-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[X:%.*]], i64 [[INDVARS_IV]]
697 ; CHECKII-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
698 ; CHECKII-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[Y_020]]
699 ; CHECKII-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[ADD]], 0
700 ; CHECKII-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END]], label [[IF_THEN:%.*]]
702 ; CHECKII-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[Z:%.*]], i64 [[INDVARS_IV]]
703 ; CHECKII-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX4]], align 4
704 ; CHECKII-NEXT: [[DIV:%.*]] = sdiv i32 [[Y_020]], [[TMP1]]
705 ; CHECKII-NEXT: [[DIV1:%.*]] = sdiv i32 [[DIV]], [[TMP1]]
706 ; CHECKII-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[DIV1]], 0
707 ; CHECKII-NEXT: [[CONV:%.*]] = zext i1 [[CMP5]] to i32
708 ; CHECKII-NEXT: [[SEL:%.*]] = select i1 [[CMP5]], i32 [[ADD]], i32 1
709 ; CHECKII-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[SEL]]
710 ; CHECKII-NEXT: br label [[IF_END]]
712 ; CHECKII-NEXT: [[Y_1]] = phi i32 [ [[SEL]], [[IF_THEN]] ], [ 0, [[FOR_BODY]] ]
713 ; CHECKII-NEXT: store i32 [[Y_1]], ptr [[ARRAYIDX]], align 4
714 ; CHECKII-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
715 ; CHECKII-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
716 ; CHECKII-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]]
719 %cmp19 = icmp sgt i32 %n, 0
720 br i1 %cmp19, label %for.body.preheader, label %for.cond.cleanup
723 %wide.trip.count = zext nneg i32 %n to i64
727 %y.0.lcssa = phi i32 [ 0, %entry ], [ %y.1, %if.end ]
731 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %if.end ]
732 %y.020 = phi i32 [ 0, %for.body.preheader ], [ %y.1, %if.end ]
733 %arrayidx = getelementptr inbounds i32, ptr %x, i64 %indvars.iv
734 %0 = load i32, ptr %arrayidx, align 4
735 %add = add nsw i32 %0, %y.020
736 %tobool.not = icmp eq i32 %add, 0
737 br i1 %tobool.not, label %if.end, label %if.then
740 %arrayidx4 = getelementptr inbounds i32, ptr %z, i64 %indvars.iv
741 %1 = load i32, ptr %arrayidx4, align 4
742 %div = sdiv i32 %y.020, %1
743 %div1 = sdiv i32 %div, %1
744 %cmp5 = icmp sgt i32 %div1, 0
745 %conv = zext i1 %cmp5 to i32
746 %sel = select i1 %cmp5, i32 %add, i32 1
747 %or = or i32 %conv, %sel
751 %y.1 = phi i32 [ %sel, %if.then ], [ 0, %for.body ]
752 store i32 %y.1, ptr %arrayidx, align 4
753 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
754 %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
755 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
758 ; Same test again with a one use value group of values on the or
759 define i32 @or_oneusevalues(ptr nocapture noundef %x, i32 noundef %n, ptr nocapture noundef readonly %z) {
760 ; CHECKOO-LABEL: @or_oneusevalues(
761 ; CHECKOO-NEXT: entry:
762 ; CHECKOO-NEXT: [[CMP19:%.*]] = icmp sgt i32 [[N:%.*]], 0
763 ; CHECKOO-NEXT: br i1 [[CMP19]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
764 ; CHECKOO: for.body.preheader:
765 ; CHECKOO-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext nneg i32 [[N]] to i64
766 ; CHECKOO-NEXT: br label [[FOR_BODY:%.*]]
767 ; CHECKOO: for.cond.cleanup:
768 ; CHECKOO-NEXT: [[Y_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[Y_1:%.*]], [[IF_END:%.*]] ]
769 ; CHECKOO-NEXT: ret i32 [[Y_0_LCSSA]]
771 ; CHECKOO-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[IF_END]] ]
772 ; CHECKOO-NEXT: [[Y_020:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[Y_1]], [[IF_END]] ]
773 ; CHECKOO-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[X:%.*]], i64 [[INDVARS_IV]]
774 ; CHECKOO-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
775 ; CHECKOO-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[Y_020]]
776 ; CHECKOO-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[ADD]], 0
777 ; CHECKOO-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END]], label [[IF_THEN:%.*]]
779 ; CHECKOO-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[Z:%.*]], i64 [[INDVARS_IV]]
780 ; CHECKOO-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX4]], align 4
781 ; CHECKOO-NEXT: [[DIV:%.*]] = sdiv i32 [[Y_020]], [[TMP1]]
782 ; CHECKOO-NEXT: [[DIV1:%.*]] = sdiv i32 [[DIV]], [[TMP1]]
783 ; CHECKOO-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[DIV1]], 0
784 ; CHECKOO-NEXT: [[CONV:%.*]] = zext i1 [[CMP5]] to i32
785 ; CHECKOO-NEXT: [[ADD1:%.*]] = add i32 [[ADD]], 1
786 ; CHECKOO-NEXT: [[ADD2:%.*]] = or i32 [[ADD1]], 1
787 ; CHECKOO-NEXT: [[CMP5_FROZEN:%.*]] = freeze i1 [[CMP5]]
788 ; CHECKOO-NEXT: br i1 [[CMP5_FROZEN]], label [[SELECT_END:%.*]], label [[SELECT_FALSE:%.*]]
789 ; CHECKOO: select.true.sink:
790 ; CHECKOO-NEXT: [[TMP2:%.*]] = or i32 1, [[ADD2]]
791 ; CHECKOO-NEXT: br label [[SELECT_FALSE]]
792 ; CHECKOO: select.end:
793 ; CHECKOO-NEXT: [[OR:%.*]] = phi i32 [ [[TMP2]], [[SELECT_END]] ], [ [[ADD2]], [[IF_THEN]] ]
794 ; CHECKOO-NEXT: br label [[IF_END]]
796 ; CHECKOO-NEXT: [[Y_1]] = phi i32 [ [[OR]], [[SELECT_FALSE]] ], [ 0, [[FOR_BODY]] ]
797 ; CHECKOO-NEXT: store i32 [[Y_1]], ptr [[ARRAYIDX]], align 4
798 ; CHECKOO-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
799 ; CHECKOO-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
800 ; CHECKOO-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]]
802 ; CHECKII-LABEL: @or_oneusevalues(
803 ; CHECKII-NEXT: entry:
804 ; CHECKII-NEXT: [[CMP19:%.*]] = icmp sgt i32 [[N:%.*]], 0
805 ; CHECKII-NEXT: br i1 [[CMP19]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
806 ; CHECKII: for.body.preheader:
807 ; CHECKII-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext nneg i32 [[N]] to i64
808 ; CHECKII-NEXT: br label [[FOR_BODY:%.*]]
809 ; CHECKII: for.cond.cleanup:
810 ; CHECKII-NEXT: [[Y_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[Y_1:%.*]], [[IF_END:%.*]] ]
811 ; CHECKII-NEXT: ret i32 [[Y_0_LCSSA]]
813 ; CHECKII-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[IF_END]] ]
814 ; CHECKII-NEXT: [[Y_020:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[Y_1]], [[IF_END]] ]
815 ; CHECKII-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[X:%.*]], i64 [[INDVARS_IV]]
816 ; CHECKII-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
817 ; CHECKII-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[Y_020]]
818 ; CHECKII-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[ADD]], 0
819 ; CHECKII-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END]], label [[IF_THEN:%.*]]
821 ; CHECKII-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[Z:%.*]], i64 [[INDVARS_IV]]
822 ; CHECKII-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX4]], align 4
823 ; CHECKII-NEXT: [[DIV:%.*]] = sdiv i32 [[Y_020]], [[TMP1]]
824 ; CHECKII-NEXT: [[DIV1:%.*]] = sdiv i32 [[DIV]], [[TMP1]]
825 ; CHECKII-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[DIV1]], 0
826 ; CHECKII-NEXT: [[CONV:%.*]] = zext i1 [[CMP5]] to i32
827 ; CHECKII-NEXT: [[ADD1:%.*]] = add i32 [[ADD]], 1
828 ; CHECKII-NEXT: [[ADD2:%.*]] = or i32 [[ADD1]], 1
829 ; CHECKII-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[ADD2]]
830 ; CHECKII-NEXT: br label [[IF_END]]
832 ; CHECKII-NEXT: [[Y_1]] = phi i32 [ [[OR]], [[IF_THEN]] ], [ 0, [[FOR_BODY]] ]
833 ; CHECKII-NEXT: store i32 [[Y_1]], ptr [[ARRAYIDX]], align 4
834 ; CHECKII-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
835 ; CHECKII-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
836 ; CHECKII-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]]
839 %cmp19 = icmp sgt i32 %n, 0
840 br i1 %cmp19, label %for.body.preheader, label %for.cond.cleanup
843 %wide.trip.count = zext nneg i32 %n to i64
847 %y.0.lcssa = phi i32 [ 0, %entry ], [ %y.1, %if.end ]
851 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %if.end ]
852 %y.020 = phi i32 [ 0, %for.body.preheader ], [ %y.1, %if.end ]
853 %arrayidx = getelementptr inbounds i32, ptr %x, i64 %indvars.iv
854 %0 = load i32, ptr %arrayidx, align 4
855 %add = add nsw i32 %0, %y.020
856 %tobool.not = icmp eq i32 %add, 0
857 br i1 %tobool.not, label %if.end, label %if.then
860 %arrayidx4 = getelementptr inbounds i32, ptr %z, i64 %indvars.iv
861 %1 = load i32, ptr %arrayidx4, align 4
862 %div = sdiv i32 %y.020, %1
863 %div1 = sdiv i32 %div, %1
864 %cmp5 = icmp sgt i32 %div1, 0
865 %conv = zext i1 %cmp5 to i32
866 %add1 = add i32 %add, 1
867 %add2 = or i32 %add1, 1
868 %or = or i32 %conv, %add2
872 %y.1 = phi i32 [ %or, %if.then ], [ 0, %for.body ]
873 store i32 %y.1, ptr %arrayidx, align 4
874 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
875 %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
876 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
879 declare i64 @payload(i64, ptr, ptr, i64)
881 define void @outer_latch_heuristic(ptr %dst, ptr %src, i64 %p, i64 %dim) {
882 ; CHECKOO-LABEL: @outer_latch_heuristic(
883 ; CHECKOO-NEXT: entry:
884 ; CHECKOO-NEXT: br label [[OUTER_LOOP:%.*]]
885 ; CHECKOO: outer.loop:
886 ; CHECKOO-NEXT: [[K_020_US:%.*]] = phi i64 [ [[INC7_US:%.*]], [[SELECT_END:%.*]] ], [ 0, [[ENTRY:%.*]] ]
887 ; CHECKOO-NEXT: [[J:%.*]] = phi i64 [ [[J_NEXT:%.*]], [[SELECT_END]] ], [ 0, [[ENTRY]] ]
888 ; CHECKOO-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], [[SELECT_END]] ], [ 0, [[ENTRY]] ]
889 ; CHECKOO-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]]
890 ; CHECKOO-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX_US]], align 8
891 ; CHECKOO-NEXT: [[ARRAYIDX1_US:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]
892 ; CHECKOO-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARRAYIDX1_US]], align 8
893 ; CHECKOO-NEXT: br label [[INNER_LOOP:%.*]]
894 ; CHECKOO: inner.loop:
895 ; CHECKOO-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[DIM:%.*]], [[OUTER_LOOP]] ], [ [[LSR_IV_NEXT:%.*]], [[INNER_LOOP]] ]
896 ; CHECKOO-NEXT: [[DIFF_04_I_US:%.*]] = phi i64 [ [[CALL_I_US:%.*]], [[INNER_LOOP]] ], [ 0, [[OUTER_LOOP]] ]
897 ; CHECKOO-NEXT: [[CALL_I_US]] = tail call i64 @payload(i64 [[DIFF_04_I_US]], ptr [[TMP0]], ptr [[TMP1]], i64 [[P:%.*]])
898 ; CHECKOO-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -1
899 ; CHECKOO-NEXT: [[EXITCOND_NOT_I_US:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
900 ; CHECKOO-NEXT: br i1 [[EXITCOND_NOT_I_US]], label [[LATCH:%.*]], label [[INNER_LOOP]]
902 ; CHECKOO-NEXT: [[CMP2_US:%.*]] = icmp sgt i64 [[CALL_I_US]], -1
903 ; CHECKOO-NEXT: [[DIFF_0_LCSSA_I_LOBIT_US:%.*]] = lshr i64 [[CALL_I_US]], 63
904 ; CHECKOO-NEXT: [[CMP2_US_FROZEN:%.*]] = freeze i1 [[CMP2_US]]
905 ; CHECKOO-NEXT: br i1 [[CMP2_US_FROZEN]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_FALSE_SINK:%.*]]
906 ; CHECKOO: select.true.sink:
907 ; CHECKOO-NEXT: [[TMP2:%.*]] = add nsw i64 [[J]], 1
908 ; CHECKOO-NEXT: br label [[SELECT_END]]
909 ; CHECKOO: select.false.sink:
910 ; CHECKOO-NEXT: [[TMP3:%.*]] = add nsw i64 1, [[I]]
911 ; CHECKOO-NEXT: br label [[SELECT_END]]
912 ; CHECKOO: select.end:
913 ; CHECKOO-NEXT: [[I_NEXT]] = phi i64 [ [[I]], [[SELECT_TRUE_SINK]] ], [ [[TMP3]], [[SELECT_FALSE_SINK]] ]
914 ; CHECKOO-NEXT: [[J_NEXT]] = phi i64 [ [[TMP2]], [[SELECT_TRUE_SINK]] ], [ [[J]], [[SELECT_FALSE_SINK]] ]
915 ; CHECKOO-NEXT: [[COND_IN_US:%.*]] = phi ptr [ [[ARRAYIDX1_US]], [[SELECT_TRUE_SINK]] ], [ [[ARRAYIDX_US]], [[SELECT_FALSE_SINK]] ]
916 ; CHECKOO-NEXT: [[INC4_US:%.*]] = zext i1 [[CMP2_US]] to i64
917 ; CHECKOO-NEXT: [[COND_US:%.*]] = load ptr, ptr [[COND_IN_US]], align 8
918 ; CHECKOO-NEXT: [[ARRAYIDX6_US:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[K_020_US]]
919 ; CHECKOO-NEXT: store ptr [[COND_US]], ptr [[ARRAYIDX6_US]], align 8
920 ; CHECKOO-NEXT: [[INC7_US]] = add i64 [[K_020_US]], 1
921 ; CHECKOO-NEXT: [[EXITCOND23_NOT:%.*]] = icmp eq i64 [[K_020_US]], 1000
922 ; CHECKOO-NEXT: br i1 [[EXITCOND23_NOT]], label [[EXIT:%.*]], label [[OUTER_LOOP]]
924 ; CHECKOO-NEXT: ret void
926 ; CHECKII-LABEL: @outer_latch_heuristic(
927 ; CHECKII-NEXT: entry:
928 ; CHECKII-NEXT: br label [[OUTER_LOOP:%.*]]
929 ; CHECKII: outer.loop:
930 ; CHECKII-NEXT: [[K_020_US:%.*]] = phi i64 [ [[INC7_US:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
931 ; CHECKII-NEXT: [[J:%.*]] = phi i64 [ [[J_NEXT:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
932 ; CHECKII-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
933 ; CHECKII-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]]
934 ; CHECKII-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX_US]], align 8
935 ; CHECKII-NEXT: [[ARRAYIDX1_US:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]
936 ; CHECKII-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARRAYIDX1_US]], align 8
937 ; CHECKII-NEXT: br label [[INNER_LOOP:%.*]]
938 ; CHECKII: inner.loop:
939 ; CHECKII-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[DIM:%.*]], [[OUTER_LOOP]] ], [ [[LSR_IV_NEXT:%.*]], [[INNER_LOOP]] ]
940 ; CHECKII-NEXT: [[DIFF_04_I_US:%.*]] = phi i64 [ [[CALL_I_US:%.*]], [[INNER_LOOP]] ], [ 0, [[OUTER_LOOP]] ]
941 ; CHECKII-NEXT: [[CALL_I_US]] = tail call i64 @payload(i64 [[DIFF_04_I_US]], ptr [[TMP0]], ptr [[TMP1]], i64 [[P:%.*]])
942 ; CHECKII-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -1
943 ; CHECKII-NEXT: [[EXITCOND_NOT_I_US:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
944 ; CHECKII-NEXT: br i1 [[EXITCOND_NOT_I_US]], label [[LATCH]], label [[INNER_LOOP]]
946 ; CHECKII-NEXT: [[CMP2_US:%.*]] = icmp sgt i64 [[CALL_I_US]], -1
947 ; CHECKII-NEXT: [[DIFF_0_LCSSA_I_LOBIT_US:%.*]] = lshr i64 [[CALL_I_US]], 63
948 ; CHECKII-NEXT: [[I_NEXT]] = add nsw i64 [[DIFF_0_LCSSA_I_LOBIT_US]], [[I]]
949 ; CHECKII-NEXT: [[INC4_US:%.*]] = zext i1 [[CMP2_US]] to i64
950 ; CHECKII-NEXT: [[J_NEXT]] = add nsw i64 [[J]], [[INC4_US]]
951 ; CHECKII-NEXT: [[COND_IN_US:%.*]] = select i1 [[CMP2_US]], ptr [[ARRAYIDX1_US]], ptr [[ARRAYIDX_US]]
952 ; CHECKII-NEXT: [[COND_US:%.*]] = load ptr, ptr [[COND_IN_US]], align 8
953 ; CHECKII-NEXT: [[ARRAYIDX6_US:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[K_020_US]]
954 ; CHECKII-NEXT: store ptr [[COND_US]], ptr [[ARRAYIDX6_US]], align 8
955 ; CHECKII-NEXT: [[INC7_US]] = add i64 [[K_020_US]], 1
956 ; CHECKII-NEXT: [[EXITCOND23_NOT:%.*]] = icmp eq i64 [[K_020_US]], 1000
957 ; CHECKII-NEXT: br i1 [[EXITCOND23_NOT]], label [[EXIT:%.*]], label [[OUTER_LOOP]]
959 ; CHECKII-NEXT: ret void
965 %k.020.us = phi i64 [ %inc7.us, %latch ], [ 0, %entry ]
966 %j = phi i64 [ %j.next, %latch ], [ 0, %entry ]
967 %i = phi i64 [ %i.next, %latch ], [ 0, %entry ]
968 %arrayidx.us = getelementptr inbounds ptr, ptr %src, i64 %i
969 %4 = load ptr, ptr %arrayidx.us, align 8
970 %arrayidx1.us = getelementptr inbounds ptr, ptr %src, i64 %j
971 %5 = load ptr, ptr %arrayidx1.us, align 8
975 %lsr.iv = phi i64 [ %dim, %outer.loop ], [ %lsr.iv.next, %inner.loop ]
976 %diff.04.i.us = phi i64 [ %call.i.us, %inner.loop ], [ 0, %outer.loop ]
977 %call.i.us = tail call i64 @payload(i64 %diff.04.i.us, ptr %4, ptr %5, i64 %p)
978 %lsr.iv.next = add i64 %lsr.iv, -1
979 %exitcond.not.i.us = icmp eq i64 %lsr.iv.next, 0
980 br i1 %exitcond.not.i.us, label %latch, label %inner.loop
983 %cmp2.us = icmp sgt i64 %call.i.us, -1
984 %diff.0.lcssa.i.lobit.us = lshr i64 %call.i.us, 63
985 %i.next = add nsw i64 %diff.0.lcssa.i.lobit.us, %i
986 %inc4.us = zext i1 %cmp2.us to i64
987 %j.next = add nsw i64 %j, %inc4.us
988 %cond.in.us = select i1 %cmp2.us, ptr %arrayidx1.us, ptr %arrayidx.us
989 %cond.us = load ptr, ptr %cond.in.us, align 8
990 %arrayidx6.us = getelementptr inbounds ptr, ptr %dst, i64 %k.020.us
991 store ptr %cond.us, ptr %arrayidx6.us, align 8
992 %inc7.us = add i64 %k.020.us, 1
993 %exitcond23.not = icmp eq i64 %k.020.us, 1000
994 br i1 %exitcond23.not, label %exit, label %outer.loop