xref: /llvm-project/llvm/test/CodeGen/AArch64/selectopt.ll (revision 3469996d0d057d99a33ec34ee3c80e5d4fa3afcb)
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
17
18%struct.st = type { i32, i64, ptr, ptr, i16, ptr, ptr, i64, i64 }
19
20; This test has a select at the end of if.then, which is better transformed to a branch on OoO cores.
21
22define 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:%.*]]
45; CHECKOO:       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:%.*]]
87; CHECKOO:       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]]
101; CHECKOO:       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
107;
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:%.*]]
130; CHECKII:       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:%.*]]
172; CHECKII:       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]]
181; CHECKII:       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
187;
188entry:
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
209
210land.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
218
219while.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
253
254if.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
262  br label %if.end87
263
264if.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
268
269while.end:                                        ; preds = %land.rhs, %if.end87, %entry
270  ret void
271}
272
273
274define 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:%.*]]
297; CHECKOO:       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]]
337; CHECKOO:       if.then:
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]]
353; CHECKOO:       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
359;
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:%.*]]
382; CHECKII:       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]]
422; CHECKII:       if.then:
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]]
432; CHECKII:       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
438;
439entry:
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
460
461land.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
469
470while.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
502
503if.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
512  br label %if.end87
513
514if.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
518
519while.end:                                        ; preds = %if.end87, %land.rhs, %entry
520  ret void
521}
522
523
524; This `or` is not transformed as it is not the last instruction in the block
525define 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]]
536; CHECKOO:       for.body:
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:%.*]]
544; CHECKOO:       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]]
555; CHECKOO:       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]]
561;
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]]
572; CHECKII:       for.body:
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:%.*]]
580; CHECKII:       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]]
591; CHECKII:       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]]
597;
598entry:
599  %cmp19 = icmp sgt i32 %n, 0
600  br i1 %cmp19, label %for.body.preheader, label %for.cond.cleanup
601
602for.body.preheader:
603  %wide.trip.count = zext nneg i32 %n to i64
604  br label %for.body
605
606for.cond.cleanup:
607  %y.0.lcssa = phi i32 [ 0, %entry ], [ %y.1, %if.end ]
608  ret i32 %y.0.lcssa
609
610for.body:
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
618
619if.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
629  br label %if.end
630
631if.end:
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
637}
638
639
640; Similar to the last test, an artificial test with the or as the last instruction and a select in the same group.
641define 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]]
652; CHECKOO:       for.body:
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:%.*]]
660; CHECKOO:       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]]
676; CHECKOO:       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]]
682;
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]]
693; CHECKII:       for.body:
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:%.*]]
701; CHECKII:       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]]
711; CHECKII:       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]]
717;
718entry:
719  %cmp19 = icmp sgt i32 %n, 0
720  br i1 %cmp19, label %for.body.preheader, label %for.cond.cleanup
721
722for.body.preheader:
723  %wide.trip.count = zext nneg i32 %n to i64
724  br label %for.body
725
726for.cond.cleanup:
727  %y.0.lcssa = phi i32 [ 0, %entry ], [ %y.1, %if.end ]
728  ret i32 %y.0.lcssa
729
730for.body:
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
738
739if.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
748  br label %if.end
749
750if.end:
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
756}
757
758; Same test again with a one use value group of values on the or
759define 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]]
770; CHECKOO:       for.body:
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:%.*]]
778; CHECKOO:       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]]
795; CHECKOO:       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]]
801;
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]]
812; CHECKII:       for.body:
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:%.*]]
820; CHECKII:       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]]
831; CHECKII:       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]]
837;
838entry:
839  %cmp19 = icmp sgt i32 %n, 0
840  br i1 %cmp19, label %for.body.preheader, label %for.cond.cleanup
841
842for.body.preheader:
843  %wide.trip.count = zext nneg i32 %n to i64
844  br label %for.body
845
846for.cond.cleanup:
847  %y.0.lcssa = phi i32 [ 0, %entry ], [ %y.1, %if.end ]
848  ret i32 %y.0.lcssa
849
850for.body:
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
858
859if.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
869  br label %if.end
870
871if.end:
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
877}
878
879declare i64 @payload(i64, ptr, ptr, i64)
880
881define 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]]
901; CHECKOO:       latch:
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]]
923; CHECKOO:       exit:
924; CHECKOO-NEXT:    ret void
925;
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]]
945; CHECKII:       latch:
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]]
958; CHECKII:       exit:
959; CHECKII-NEXT:    ret void
960;
961entry:
962  br label %outer.loop
963
964outer.loop:
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
972  br label %inner.loop
973
974inner.loop:
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
981
982latch:
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
995
996exit:
997  ret void
998}
999