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