1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt -passes='simple-loop-unswitch<nontrivial>' -S < %s | FileCheck %s 3 4; Non-trivial loop unswitching of select instruction. 5 6declare i1 @foo() 7declare i1 @bar(i32) 8declare i32 @llvm.vector.reduce.add.v2i32(<2 x i32>) 9 10define i32 @basic(i32 %N, i1 %cond, i32 %select_input) { 11; CHECK-LABEL: define i32 @basic 12; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]], i32 [[SELECT_INPUT:%.*]]) { 13; CHECK-NEXT: entry: 14; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]] 15; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 16; CHECK: entry.split.us: 17; CHECK-NEXT: br label [[FOR_COND_US:%.*]] 18; CHECK: for.cond.us: 19; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[ADD_US:%.*]], [[TMP1:%.*]] ] 20; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[INC_US:%.*]], [[TMP1]] ] 21; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]] 22; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US:%.*]] 23; CHECK: for.body.us: 24; CHECK-NEXT: br label [[TMP0:%.*]] 25; CHECK: 0: 26; CHECK-NEXT: br label [[TMP1]] 27; CHECK: 1: 28; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[SELECT_INPUT]], [[TMP0]] ] 29; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 [[UNSWITCHED_SELECT_US]], [[RES_US]] 30; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1 31; CHECK-NEXT: br label [[FOR_COND_US]] 32; CHECK: for.cond.cleanup.split.us: 33; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ] 34; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]] 35; CHECK: entry.split: 36; CHECK-NEXT: br label [[FOR_COND:%.*]] 37; CHECK: for.cond: 38; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[ADD:%.*]], [[TMP2:%.*]] ] 39; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[INC:%.*]], [[TMP2]] ] 40; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]] 41; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT:%.*]] 42; CHECK: for.body: 43; CHECK-NEXT: br label [[TMP2]] 44; CHECK: 2: 45; CHECK-NEXT: [[ADD]] = add nuw nsw i32 42, [[RES]] 46; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1 47; CHECK-NEXT: br label [[FOR_COND]] 48; CHECK: for.cond.cleanup.split: 49; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ] 50; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 51; CHECK: for.cond.cleanup: 52; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US]] ] 53; CHECK-NEXT: ret i32 [[DOTUS_PHI]] 54; 55entry: 56 br label %for.cond 57 58for.cond: ; preds = %for.body, %entry 59 %res = phi i32 [ 0, %entry ], [ %add, %for.body ] 60 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ] 61 %cmp = icmp slt i32 %i, %N 62 br i1 %cmp, label %for.body, label %for.cond.cleanup 63 64for.body: ; preds = %for.cond 65 %cond1 = select i1 %cond, i32 %select_input, i32 42 66 %add = add nuw nsw i32 %cond1, %res 67 %inc = add nuw nsw i32 %i, 1 68 br label %for.cond 69 70for.cond.cleanup: ; preds = %for.cond 71 ret i32 %res 72} 73 74define i32 @basic_veccond(i32 %N, <2 x i1> %cond, <2 x i32> %select_input) { 75; CHECK-LABEL: define i32 @basic_veccond 76; CHECK-SAME: (i32 [[N:%.*]], <2 x i1> [[COND:%.*]], <2 x i32> [[SELECT_INPUT:%.*]]) { 77; CHECK-NEXT: entry: 78; CHECK-NEXT: br label [[FOR_COND:%.*]] 79; CHECK: for.cond: 80; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY:%.*]] ] 81; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ] 82; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]] 83; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] 84; CHECK: for.body: 85; CHECK-NEXT: [[COND1:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[SELECT_INPUT]], <2 x i32> splat (i32 42) 86; CHECK-NEXT: [[VREDUCE:%.*]] = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> [[COND1]]) 87; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[VREDUCE]], [[RES]] 88; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1 89; CHECK-NEXT: br label [[FOR_COND]] 90; CHECK: for.cond.cleanup: 91; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ] 92; CHECK-NEXT: ret i32 [[RES_LCSSA]] 93; 94entry: 95 br label %for.cond 96 97for.cond: ; preds = %for.body, %entry 98 %res = phi i32 [ 0, %entry ], [ %add, %for.body ] 99 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ] 100 %cmp = icmp slt i32 %i, %N 101 br i1 %cmp, label %for.body, label %for.cond.cleanup 102 103for.body: ; preds = %for.cond 104 %cond1 = select <2 x i1> %cond, <2 x i32> %select_input, <2 x i32> <i32 42, i32 42> 105 %vreduce = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> %cond1) 106 %add = add nuw nsw i32 %vreduce, %res 107 %inc = add nuw nsw i32 %i, 1 108 br label %for.cond 109 110for.cond.cleanup: ; preds = %for.cond 111 ret i32 %res 112} 113 114define i32 @select_phi_input(i32 %N, i1 %cond) { 115; CHECK-LABEL: define i32 @select_phi_input 116; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]]) { 117; CHECK-NEXT: entry: 118; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]] 119; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 120; CHECK: entry.split.us: 121; CHECK-NEXT: br label [[FOR_COND_US:%.*]] 122; CHECK: for.cond.us: 123; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[ADD_US:%.*]], [[TMP1:%.*]] ] 124; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[INC_US:%.*]], [[TMP1]] ] 125; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]] 126; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US:%.*]] 127; CHECK: for.body.us: 128; CHECK-NEXT: br label [[TMP0:%.*]] 129; CHECK: 0: 130; CHECK-NEXT: br label [[TMP1]] 131; CHECK: 1: 132; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_US]], [[TMP0]] ] 133; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 [[UNSWITCHED_SELECT_US]], [[RES_US]] 134; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1 135; CHECK-NEXT: br label [[FOR_COND_US]] 136; CHECK: for.cond.cleanup.split.us: 137; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ] 138; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]] 139; CHECK: entry.split: 140; CHECK-NEXT: br label [[FOR_COND:%.*]] 141; CHECK: for.cond: 142; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[ADD:%.*]], [[TMP2:%.*]] ] 143; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[INC:%.*]], [[TMP2]] ] 144; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]] 145; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT:%.*]] 146; CHECK: for.body: 147; CHECK-NEXT: br label [[TMP2]] 148; CHECK: 2: 149; CHECK-NEXT: [[ADD]] = add nuw nsw i32 42, [[RES]] 150; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1 151; CHECK-NEXT: br label [[FOR_COND]] 152; CHECK: for.cond.cleanup.split: 153; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ] 154; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 155; CHECK: for.cond.cleanup: 156; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US]] ] 157; CHECK-NEXT: ret i32 [[DOTUS_PHI]] 158; 159entry: 160 br label %for.cond 161 162for.cond: ; preds = %for.body, %entry 163 %res = phi i32 [ 0, %entry ], [ %add, %for.body ] 164 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ] 165 %cmp = icmp slt i32 %i, %N 166 br i1 %cmp, label %for.body, label %for.cond.cleanup 167 168for.body: ; preds = %for.cond 169 %cond1 = select i1 %cond, i32 %i, i32 42 170 %add = add nuw nsw i32 %cond1, %res 171 %inc = add nuw nsw i32 %i, 1 172 br label %for.cond 173 174for.cond.cleanup: ; preds = %for.cond 175 ret i32 %res 176} 177 178define i32 @basic_cond_noundef(i32 %N, i1 noundef %cond) { 179; CHECK-LABEL: define i32 @basic_cond_noundef 180; CHECK-SAME: (i32 [[N:%.*]], i1 noundef [[COND:%.*]]) { 181; CHECK-NEXT: entry: 182; CHECK-NEXT: br i1 [[COND]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 183; CHECK: entry.split.us: 184; CHECK-NEXT: br label [[FOR_COND_US:%.*]] 185; CHECK: for.cond.us: 186; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[ADD_US:%.*]], [[TMP1:%.*]] ] 187; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[INC_US:%.*]], [[TMP1]] ] 188; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]] 189; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US:%.*]] 190; CHECK: for.body.us: 191; CHECK-NEXT: br label [[TMP0:%.*]] 192; CHECK: 0: 193; CHECK-NEXT: br label [[TMP1]] 194; CHECK: 1: 195; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_US]], [[TMP0]] ] 196; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 [[UNSWITCHED_SELECT_US]], [[RES_US]] 197; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1 198; CHECK-NEXT: br label [[FOR_COND_US]] 199; CHECK: for.cond.cleanup.split.us: 200; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ] 201; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]] 202; CHECK: entry.split: 203; CHECK-NEXT: br label [[FOR_COND:%.*]] 204; CHECK: for.cond: 205; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[ADD:%.*]], [[TMP2:%.*]] ] 206; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[INC:%.*]], [[TMP2]] ] 207; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]] 208; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT:%.*]] 209; CHECK: for.body: 210; CHECK-NEXT: br label [[TMP2]] 211; CHECK: 2: 212; CHECK-NEXT: [[ADD]] = add nuw nsw i32 42, [[RES]] 213; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1 214; CHECK-NEXT: br label [[FOR_COND]] 215; CHECK: for.cond.cleanup.split: 216; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ] 217; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 218; CHECK: for.cond.cleanup: 219; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US]] ] 220; CHECK-NEXT: ret i32 [[DOTUS_PHI]] 221; 222entry: 223 br label %for.cond 224 225for.cond: ; preds = %for.body, %entry 226 %res = phi i32 [ 0, %entry ], [ %add, %for.body ] 227 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ] 228 %cmp = icmp slt i32 %i, %N 229 br i1 %cmp, label %for.body, label %for.cond.cleanup 230 231for.body: ; preds = %for.cond 232 %cond1 = select i1 %cond, i32 %i, i32 42 233 %add = add nuw nsw i32 %cond1, %res 234 %inc = add nuw nsw i32 %i, 1 235 br label %for.cond 236 237for.cond.cleanup: ; preds = %for.cond 238 ret i32 %res 239} 240 241define i32 @cond_invariant(i32 %N) { 242; CHECK-LABEL: define i32 @cond_invariant 243; CHECK-SAME: (i32 [[N:%.*]]) { 244; CHECK-NEXT: entry: 245; CHECK-NEXT: br label [[FOR_COND:%.*]] 246; CHECK: for.cond: 247; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY:%.*]] ] 248; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ] 249; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]] 250; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] 251; CHECK: for.body: 252; CHECK-NEXT: [[COND:%.*]] = call i1 @foo() 253; CHECK-NEXT: [[COND1:%.*]] = select i1 [[COND]], i32 [[I]], i32 42 254; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[COND1]], [[RES]] 255; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1 256; CHECK-NEXT: br label [[FOR_COND]] 257; CHECK: for.cond.cleanup: 258; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ] 259; CHECK-NEXT: ret i32 [[RES_LCSSA]] 260; 261entry: 262 br label %for.cond 263 264for.cond: ; preds = %for.body, %entry 265 %res = phi i32 [ 0, %entry ], [ %add, %for.body ] 266 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ] 267 %cmp = icmp slt i32 %i, %N 268 br i1 %cmp, label %for.body, label %for.cond.cleanup 269 270for.body: ; preds = %for.cond 271 %cond = call i1 @foo() 272 %cond1 = select i1 %cond, i32 %i, i32 42 273 %add = add nuw nsw i32 %cond1, %res 274 %inc = add nuw nsw i32 %i, 1 275 br label %for.cond 276 277for.cond.cleanup: ; preds = %for.cond 278 ret i32 %res 279} 280 281define i32 @chained_select(i32 %N, i1 %cond, i1 %cond2) { 282; CHECK-LABEL: define i32 @chained_select 283; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]], i1 [[COND2:%.*]]) { 284; CHECK-NEXT: entry: 285; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]] 286; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 287; CHECK: entry.split.us: 288; CHECK-NEXT: [[COND2_FR13:%.*]] = freeze i1 [[COND2]] 289; CHECK-NEXT: br i1 [[COND2_FR13]], label [[ENTRY_SPLIT_US_SPLIT_US:%.*]], label [[ENTRY_SPLIT_US_SPLIT:%.*]] 290; CHECK: entry.split.us.split.us: 291; CHECK-NEXT: br label [[FOR_COND_US_US:%.*]] 292; CHECK: for.cond.us.us: 293; CHECK-NEXT: [[RES_US_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US_SPLIT_US]] ], [ [[ADD_US_US:%.*]], [[TMP3:%.*]] ] 294; CHECK-NEXT: [[I_US_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US_SPLIT_US]] ], [ [[INC_US_US:%.*]], [[TMP3]] ] 295; CHECK-NEXT: [[CMP_US_US:%.*]] = icmp slt i32 [[I_US_US]], [[N]] 296; CHECK-NEXT: br i1 [[CMP_US_US]], label [[FOR_BODY_US_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US_SPLIT_US:%.*]] 297; CHECK: for.body.us.us: 298; CHECK-NEXT: br label [[TMP0:%.*]] 299; CHECK: 0: 300; CHECK-NEXT: br label [[TMP1:%.*]] 301; CHECK: 1: 302; CHECK-NEXT: [[UNSWITCHED_SELECT_US_US:%.*]] = phi i32 [ [[I_US_US]], [[TMP0]] ] 303; CHECK-NEXT: br label [[TMP2:%.*]] 304; CHECK: 2: 305; CHECK-NEXT: br label [[TMP3]] 306; CHECK: 3: 307; CHECK-NEXT: [[UNSWITCHED_SELECT_US11:%.*]] = phi i32 [ [[UNSWITCHED_SELECT_US_US]], [[TMP2]] ] 308; CHECK-NEXT: [[ADD_US_US]] = add nuw nsw i32 [[UNSWITCHED_SELECT_US11]], [[RES_US_US]] 309; CHECK-NEXT: [[INC_US_US]] = add nuw nsw i32 [[I_US_US]], 1 310; CHECK-NEXT: br label [[FOR_COND_US_US]] 311; CHECK: for.cond.cleanup.split.us.split.us: 312; CHECK-NEXT: [[RES_LCSSA_US_US:%.*]] = phi i32 [ [[RES_US_US]], [[FOR_COND_US_US]] ] 313; CHECK-NEXT: br label [[FOR_COND_CLEANUP_SPLIT_US:%.*]] 314; CHECK: entry.split.us.split: 315; CHECK-NEXT: br label [[FOR_COND_US:%.*]] 316; CHECK: for.cond.us: 317; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US_SPLIT]] ], [ [[ADD_US:%.*]], [[TMP6:%.*]] ] 318; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US_SPLIT]] ], [ [[INC_US:%.*]], [[TMP6]] ] 319; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]] 320; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US_SPLIT:%.*]] 321; CHECK: for.body.us: 322; CHECK-NEXT: br label [[TMP4:%.*]] 323; CHECK: 4: 324; CHECK-NEXT: br label [[TMP5:%.*]] 325; CHECK: 5: 326; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_US]], [[TMP4]] ] 327; CHECK-NEXT: br label [[TMP6]] 328; CHECK: 6: 329; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 24, [[RES_US]] 330; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1 331; CHECK-NEXT: br label [[FOR_COND_US]] 332; CHECK: for.cond.cleanup.split.us.split: 333; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ] 334; CHECK-NEXT: br label [[FOR_COND_CLEANUP_SPLIT_US]] 335; CHECK: for.cond.cleanup.split.us: 336; CHECK-NEXT: [[DOTUS_PHI12:%.*]] = phi i32 [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US_SPLIT]] ], [ [[RES_LCSSA_US_US]], [[FOR_COND_CLEANUP_SPLIT_US_SPLIT_US]] ] 337; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]] 338; CHECK: entry.split: 339; CHECK-NEXT: [[COND2_FR:%.*]] = freeze i1 [[COND2]] 340; CHECK-NEXT: br i1 [[COND2_FR]], label [[ENTRY_SPLIT_SPLIT_US:%.*]], label [[ENTRY_SPLIT_SPLIT:%.*]] 341; CHECK: entry.split.split.us: 342; CHECK-NEXT: br label [[FOR_COND_US1:%.*]] 343; CHECK: for.cond.us1: 344; CHECK-NEXT: [[RES_US2:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_SPLIT_US]] ], [ [[ADD_US7:%.*]], [[TMP9:%.*]] ] 345; CHECK-NEXT: [[I_US3:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_SPLIT_US]] ], [ [[INC_US8:%.*]], [[TMP9]] ] 346; CHECK-NEXT: [[CMP_US4:%.*]] = icmp slt i32 [[I_US3]], [[N]] 347; CHECK-NEXT: br i1 [[CMP_US4]], label [[FOR_BODY_US5:%.*]], label [[FOR_COND_CLEANUP_SPLIT_SPLIT_US:%.*]] 348; CHECK: for.body.us5: 349; CHECK-NEXT: br label [[TMP7:%.*]] 350; CHECK: 7: 351; CHECK-NEXT: br label [[TMP8:%.*]] 352; CHECK: 8: 353; CHECK-NEXT: br label [[TMP9]] 354; CHECK: 9: 355; CHECK-NEXT: [[UNSWITCHED_SELECT_US6:%.*]] = phi i32 [ 42, [[TMP8]] ] 356; CHECK-NEXT: [[ADD_US7]] = add nuw nsw i32 [[UNSWITCHED_SELECT_US6]], [[RES_US2]] 357; CHECK-NEXT: [[INC_US8]] = add nuw nsw i32 [[I_US3]], 1 358; CHECK-NEXT: br label [[FOR_COND_US1]] 359; CHECK: for.cond.cleanup.split.split.us: 360; CHECK-NEXT: [[RES_LCSSA_US9:%.*]] = phi i32 [ [[RES_US2]], [[FOR_COND_US1]] ] 361; CHECK-NEXT: br label [[FOR_COND_CLEANUP_SPLIT:%.*]] 362; CHECK: entry.split.split: 363; CHECK-NEXT: br label [[FOR_COND:%.*]] 364; CHECK: for.cond: 365; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_SPLIT]] ], [ [[ADD:%.*]], [[TMP11:%.*]] ] 366; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_SPLIT]] ], [ [[INC:%.*]], [[TMP11]] ] 367; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]] 368; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT_SPLIT:%.*]] 369; CHECK: for.body: 370; CHECK-NEXT: br label [[TMP10:%.*]] 371; CHECK: 10: 372; CHECK-NEXT: br label [[TMP11]] 373; CHECK: 11: 374; CHECK-NEXT: [[ADD]] = add nuw nsw i32 24, [[RES]] 375; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1 376; CHECK-NEXT: br label [[FOR_COND]] 377; CHECK: for.cond.cleanup.split.split: 378; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ] 379; CHECK-NEXT: br label [[FOR_COND_CLEANUP_SPLIT]] 380; CHECK: for.cond.cleanup.split: 381; CHECK-NEXT: [[DOTUS_PHI10:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT_SPLIT]] ], [ [[RES_LCSSA_US9]], [[FOR_COND_CLEANUP_SPLIT_SPLIT_US]] ] 382; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 383; CHECK: for.cond.cleanup: 384; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[DOTUS_PHI10]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[DOTUS_PHI12]], [[FOR_COND_CLEANUP_SPLIT_US]] ] 385; CHECK-NEXT: ret i32 [[DOTUS_PHI]] 386; 387entry: 388 br label %for.cond 389 390for.cond: ; preds = %for.body, %entry 391 %res = phi i32 [ 0, %entry ], [ %add, %for.body ] 392 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ] 393 %cmp = icmp slt i32 %i, %N 394 br i1 %cmp, label %for.body, label %for.cond.cleanup 395 396for.body: ; preds = %for.cond 397 %select1 = select i1 %cond, i32 %i, i32 42 398 %select2 = select i1 %cond2, i32 %select1, i32 24 399 %add = add nuw nsw i32 %select2, %res 400 %inc = add nuw nsw i32 %i, 1 401 br label %for.cond 402 403for.cond.cleanup: ; preds = %for.cond 404 ret i32 %res 405} 406 407define i32 @select_in_if(i32 %N, i1 %cond) { 408; CHECK-LABEL: define i32 @select_in_if 409; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]]) { 410; CHECK-NEXT: entry: 411; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]] 412; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 413; CHECK: entry.split.us: 414; CHECK-NEXT: br label [[FOR_COND_US:%.*]] 415; CHECK: for.cond.us: 416; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[ADD_US:%.*]], [[FOR_BODY_END_US:%.*]] ] 417; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[INC_US:%.*]], [[FOR_BODY_END_US]] ] 418; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]] 419; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US:%.*]] 420; CHECK: for.body.us: 421; CHECK-NEXT: [[UREM_US:%.*]] = urem i32 [[I_US]], 2 422; CHECK-NEXT: [[IF_COND_US:%.*]] = icmp eq i32 [[UREM_US]], 0 423; CHECK-NEXT: br i1 [[IF_COND_US]], label [[FOR_BODY_IF_US:%.*]], label [[FOR_BODY_END_US]] 424; CHECK: for.body.if.us: 425; CHECK-NEXT: br label [[TMP0:%.*]] 426; CHECK: for.body.end.us: 427; CHECK-NEXT: [[P_US:%.*]] = phi i32 [ [[UNSWITCHED_SELECT_US:%.*]], [[TMP1:%.*]] ], [ 24, [[FOR_BODY_US]] ] 428; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 [[P_US]], [[RES_US]] 429; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1 430; CHECK-NEXT: br label [[FOR_COND_US]] 431; CHECK: 0: 432; CHECK-NEXT: br label [[TMP1]] 433; CHECK: 1: 434; CHECK-NEXT: [[UNSWITCHED_SELECT_US]] = phi i32 [ [[I_US]], [[TMP0]] ] 435; CHECK-NEXT: br label [[FOR_BODY_END_US]] 436; CHECK: for.cond.cleanup.split.us: 437; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ] 438; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]] 439; CHECK: entry.split: 440; CHECK-NEXT: br label [[FOR_COND:%.*]] 441; CHECK: for.cond: 442; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[ADD:%.*]], [[FOR_BODY_END:%.*]] ] 443; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[INC:%.*]], [[FOR_BODY_END]] ] 444; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]] 445; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT:%.*]] 446; CHECK: for.body: 447; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[I]], 2 448; CHECK-NEXT: [[IF_COND:%.*]] = icmp eq i32 [[UREM]], 0 449; CHECK-NEXT: br i1 [[IF_COND]], label [[FOR_BODY_IF:%.*]], label [[FOR_BODY_END]] 450; CHECK: for.body.if: 451; CHECK-NEXT: br label [[TMP2:%.*]] 452; CHECK: 2: 453; CHECK-NEXT: br label [[FOR_BODY_END]] 454; CHECK: for.body.end: 455; CHECK-NEXT: [[P:%.*]] = phi i32 [ 42, [[TMP2]] ], [ 24, [[FOR_BODY]] ] 456; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[P]], [[RES]] 457; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1 458; CHECK-NEXT: br label [[FOR_COND]] 459; CHECK: for.cond.cleanup.split: 460; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ] 461; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 462; CHECK: for.cond.cleanup: 463; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US]] ] 464; CHECK-NEXT: ret i32 [[DOTUS_PHI]] 465; 466entry: 467 br label %for.cond 468 469for.cond: ; preds = %for.body.end, %entry 470 %res = phi i32 [ 0, %entry ], [ %add, %for.body.end ] 471 %i = phi i32 [ 0, %entry ], [ %inc, %for.body.end ] 472 %cmp = icmp slt i32 %i, %N 473 br i1 %cmp, label %for.body, label %for.cond.cleanup 474 475for.body: ; preds = %for.cond 476 %urem = urem i32 %i, 2 477 %if.cond = icmp eq i32 %urem, 0 478 br i1 %if.cond, label %for.body.if, label %for.body.end 479 480for.body.if: ; preds = %for.body 481 %cond1 = select i1 %cond, i32 %i, i32 42 482 br label %for.body.end 483 484for.body.end: ; preds = %for.body, %for.body.if 485 %p = phi i32 [ %cond1, %for.body.if ], [ 24, %for.body ] 486 %add = add nuw nsw i32 %p, %res 487 %inc = add nuw nsw i32 %i, 1 488 br label %for.cond 489 490for.cond.cleanup: ; preds = %for.cond 491 ret i32 %res 492} 493 494define i32 @select_in_if_else(i32 %N, i1 %cond) { 495; CHECK-LABEL: define i32 @select_in_if_else 496; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]]) { 497; CHECK-NEXT: entry: 498; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]] 499; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 500; CHECK: entry.split.us: 501; CHECK-NEXT: br label [[FOR_COND_US:%.*]] 502; CHECK: for.cond.us: 503; CHECK-NEXT: [[RES_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[ADD_US:%.*]], [[FOR_BODY_END_US:%.*]] ] 504; CHECK-NEXT: [[I_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[INC_US:%.*]], [[FOR_BODY_END_US]] ] 505; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[I_US]], [[N]] 506; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_BODY_US:%.*]], label [[FOR_COND_CLEANUP_SPLIT_US:%.*]] 507; CHECK: for.body.us: 508; CHECK-NEXT: [[UREM_US:%.*]] = urem i32 [[I_US]], 2 509; CHECK-NEXT: [[IF_COND_US:%.*]] = icmp eq i32 [[UREM_US]], 0 510; CHECK-NEXT: br i1 [[IF_COND_US]], label [[FOR_BODY_IF_US:%.*]], label [[FOR_BODY_ELSE_US:%.*]] 511; CHECK: for.body.else.us: 512; CHECK-NEXT: br label [[TMP0:%.*]] 513; CHECK: for.body.if.us: 514; CHECK-NEXT: [[COND1A_US:%.*]] = select i1 true, i32 [[I_US]], i32 42 515; CHECK-NEXT: br label [[FOR_BODY_END_US]] 516; CHECK: for.body.end.us: 517; CHECK-NEXT: [[P_US:%.*]] = phi i32 [ [[COND1A_US]], [[FOR_BODY_IF_US]] ], [ [[UNSWITCHED_SELECT_US:%.*]], [[TMP1:%.*]] ] 518; CHECK-NEXT: [[ADD_US]] = add nuw nsw i32 [[P_US]], [[RES_US]] 519; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_US]], 1 520; CHECK-NEXT: br label [[FOR_COND_US]] 521; CHECK: 0: 522; CHECK-NEXT: br label [[TMP1]] 523; CHECK: 1: 524; CHECK-NEXT: [[UNSWITCHED_SELECT_US]] = phi i32 [ 24, [[TMP0]] ] 525; CHECK-NEXT: br label [[FOR_BODY_END_US]] 526; CHECK: for.cond.cleanup.split.us: 527; CHECK-NEXT: [[RES_LCSSA_US:%.*]] = phi i32 [ [[RES_US]], [[FOR_COND_US]] ] 528; CHECK-NEXT: br label [[FOR_COND_CLEANUP:%.*]] 529; CHECK: entry.split: 530; CHECK-NEXT: br label [[FOR_COND:%.*]] 531; CHECK: for.cond: 532; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[ADD:%.*]], [[FOR_BODY_END:%.*]] ] 533; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[INC:%.*]], [[FOR_BODY_END]] ] 534; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]] 535; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP_SPLIT:%.*]] 536; CHECK: for.body: 537; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[I]], 2 538; CHECK-NEXT: [[IF_COND:%.*]] = icmp eq i32 [[UREM]], 0 539; CHECK-NEXT: br i1 [[IF_COND]], label [[FOR_BODY_IF:%.*]], label [[FOR_BODY_ELSE:%.*]] 540; CHECK: for.body.if: 541; CHECK-NEXT: [[COND1A:%.*]] = select i1 false, i32 [[I]], i32 42 542; CHECK-NEXT: br label [[FOR_BODY_END]] 543; CHECK: for.body.else: 544; CHECK-NEXT: br label [[TMP2:%.*]] 545; CHECK: 2: 546; CHECK-NEXT: br label [[FOR_BODY_END]] 547; CHECK: for.body.end: 548; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[COND1A]], [[FOR_BODY_IF]] ], [ [[I]], [[TMP2]] ] 549; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[P]], [[RES]] 550; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1 551; CHECK-NEXT: br label [[FOR_COND]] 552; CHECK: for.cond.cleanup.split: 553; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ] 554; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 555; CHECK: for.cond.cleanup: 556; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RES_LCSSA]], [[FOR_COND_CLEANUP_SPLIT]] ], [ [[RES_LCSSA_US]], [[FOR_COND_CLEANUP_SPLIT_US]] ] 557; CHECK-NEXT: ret i32 [[DOTUS_PHI]] 558; 559entry: 560 br label %for.cond 561 562for.cond: ; preds = %for.body.end, %entry 563 %res = phi i32 [ 0, %entry ], [ %add, %for.body.end ] 564 %i = phi i32 [ 0, %entry ], [ %inc, %for.body.end ] 565 %cmp = icmp slt i32 %i, %N 566 br i1 %cmp, label %for.body, label %for.cond.cleanup 567 568for.body: ; preds = %for.cond 569 %urem = urem i32 %i, 2 570 %if.cond = icmp eq i32 %urem, 0 571 br i1 %if.cond, label %for.body.if, label %for.body.else 572 573for.body.if: ; preds = %for.body 574 %cond1a = select i1 %cond, i32 %i, i32 42 575 br label %for.body.end 576 577for.body.else: ; preds = %for.body 578 %cond1b = select i1 %cond, i32 24, i32 %i 579 br label %for.body.end 580 581for.body.end: ; preds = %for.body.if, %for.body.else 582 %p = phi i32 [ %cond1a, %for.body.if ], [ %cond1b, %for.body.else ] 583 %add = add nuw nsw i32 %p, %res 584 %inc = add nuw nsw i32 %i, 1 585 br label %for.cond 586 587for.cond.cleanup: ; preds = %for.cond 588 ret i32 %res 589} 590 591define dso_local void @select_nested_loop(i1 noundef zeroext %cond, i32 noundef %n, i32 noundef %m) { 592; CHECK-LABEL: define dso_local void @select_nested_loop 593; CHECK-SAME: (i1 noundef zeroext [[COND:%.*]], i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) { 594; CHECK-NEXT: entry: 595; CHECK-NEXT: [[CMP17_NOT:%.*]] = icmp eq i32 [[N]], 0 596; CHECK-NEXT: [[CMP215_NOT:%.*]] = icmp eq i32 [[M]], 0 597; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP17_NOT]], [[CMP215_NOT]] 598; CHECK-NEXT: br i1 [[OR_COND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]] 599; CHECK: for.cond1.preheader.us.preheader: 600; CHECK-NEXT: br i1 [[COND]], label [[FOR_COND1_PREHEADER_US_PREHEADER_SPLIT_US:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER_SPLIT:%.*]] 601; CHECK: for.cond1.preheader.us.preheader.split.us: 602; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US_US:%.*]] 603; CHECK: for.cond1.preheader.us.us: 604; CHECK-NEXT: [[I_018_US_US:%.*]] = phi i32 [ [[INC7_US_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER_SPLIT_US]] ] 605; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US_SPLIT_US_US:%.*]] 606; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us.us: 607; CHECK-NEXT: [[INC7_US_US]] = add nuw i32 [[I_018_US_US]], 1 608; CHECK-NEXT: [[EXITCOND21_NOT_US:%.*]] = icmp eq i32 [[INC7_US_US]], [[N]] 609; CHECK-NEXT: br i1 [[EXITCOND21_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_COND1_PREHEADER_US_US]] 610; CHECK: for.cond1.preheader.us.split.us.us: 611; CHECK-NEXT: br label [[FOR_BODY4_US_US_US:%.*]] 612; CHECK: for.body4.us.us.us: 613; CHECK-NEXT: [[J_016_US_US_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US_SPLIT_US_US]] ], [ [[INC_US_US_US:%.*]], [[TMP1:%.*]] ] 614; CHECK-NEXT: br label [[TMP0:%.*]] 615; CHECK: 0: 616; CHECK-NEXT: br label [[TMP1]] 617; CHECK: 1: 618; CHECK-NEXT: [[UNSWITCHED_SELECT_US_US:%.*]] = phi i32 [ [[I_018_US_US]], [[TMP0]] ] 619; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US_US]]) 620; CHECK-NEXT: [[INC_US_US_US]] = add nuw i32 [[J_016_US_US_US]], 1 621; CHECK-NEXT: [[EXITCOND_NOT_US_US:%.*]] = icmp eq i32 [[INC_US_US_US]], [[M]] 622; CHECK-NEXT: br i1 [[EXITCOND_NOT_US_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_SPLIT_US_US:%.*]], label [[FOR_BODY4_US_US_US]] 623; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us.split.us.us: 624; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_US]] 625; CHECK: for.cond.cleanup.loopexit.split.us: 626; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 627; CHECK: for.cond1.preheader.us.preheader.split: 628; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 629; CHECK: for.cond1.preheader.us: 630; CHECK-NEXT: [[I_018_US:%.*]] = phi i32 [ [[INC7_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER_SPLIT]] ] 631; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US_SPLIT:%.*]] 632; CHECK: for.cond1.preheader.us.split: 633; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]] 634; CHECK: for.body4.us: 635; CHECK-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US_SPLIT]] ], [ [[INC_US:%.*]], [[TMP2:%.*]] ] 636; CHECK-NEXT: br label [[TMP2]] 637; CHECK: 2: 638; CHECK-NEXT: tail call void @bar(i32 noundef [[J_016_US]]) 639; CHECK-NEXT: [[INC_US]] = add nuw i32 [[J_016_US]], 1 640; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC_US]], [[M]] 641; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_SPLIT:%.*]], label [[FOR_BODY4_US]] 642; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us.split: 643; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] 644; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us: 645; CHECK-NEXT: [[INC7_US]] = add nuw i32 [[I_018_US]], 1 646; CHECK-NEXT: [[EXITCOND21_NOT:%.*]] = icmp eq i32 [[INC7_US]], [[N]] 647; CHECK-NEXT: br i1 [[EXITCOND21_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_COND1_PREHEADER_US]] 648; CHECK: for.cond.cleanup.loopexit.split: 649; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]] 650; CHECK: for.cond.cleanup.loopexit: 651; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 652; CHECK: for.cond.cleanup: 653; CHECK-NEXT: ret void 654; 655entry: 656 %cmp17.not = icmp eq i32 %n, 0 657 %cmp215.not = icmp eq i32 %m, 0 658 %or.cond = or i1 %cmp17.not, %cmp215.not 659 br i1 %or.cond, label %for.cond.cleanup, label %for.cond1.preheader.us 660 661for.cond1.preheader.us: ; preds = %entry, %for.cond1.for.cond.cleanup3_crit_edge.us 662 %i.018.us = phi i32 [ %inc7.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %entry ] 663 br label %for.body4.us 664 665for.body4.us: ; preds = %for.cond1.preheader.us, %for.body4.us 666 %j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ] 667 %cond5.us = select i1 %cond, i32 %i.018.us, i32 %j.016.us 668 tail call void @bar(i32 noundef %cond5.us) #2 669 %inc.us = add nuw i32 %j.016.us, 1 670 %exitcond.not = icmp eq i32 %inc.us, %m 671 br i1 %exitcond.not, label %for.cond1.for.cond.cleanup3_crit_edge.us, label %for.body4.us 672 673for.cond1.for.cond.cleanup3_crit_edge.us: ; preds = %for.body4.us 674 %inc7.us = add nuw i32 %i.018.us, 1 675 %exitcond21.not = icmp eq i32 %inc7.us, %n 676 br i1 %exitcond21.not, label %for.cond.cleanup, label %for.cond1.preheader.us 677 678for.cond.cleanup: ; preds = %for.cond1.for.cond.cleanup3_crit_edge.us, %entry 679 ret void 680} 681 682define dso_local void @select_invariant_outer_loop(i1 noundef zeroext %cond, i32 noundef %n, i32 noundef %m) { 683; CHECK-LABEL: define dso_local void @select_invariant_outer_loop 684; CHECK-SAME: (i1 noundef zeroext [[COND:%.*]], i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) { 685; CHECK-NEXT: entry: 686; CHECK-NEXT: [[CMP20_NOT:%.*]] = icmp eq i32 [[N]], 0 687; CHECK-NEXT: [[CMP218_NOT:%.*]] = icmp eq i32 [[M]], 0 688; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP20_NOT]], [[CMP218_NOT]] 689; CHECK-NEXT: br i1 [[OR_COND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]] 690; CHECK: for.cond1.preheader.us.preheader: 691; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 692; CHECK: for.cond1.preheader.us: 693; CHECK-NEXT: [[I_021_US:%.*]] = phi i32 [ [[INC9_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] 694; CHECK-NEXT: [[REM_US:%.*]] = and i32 [[I_021_US]], 1 695; CHECK-NEXT: [[CMP5_US:%.*]] = icmp eq i32 [[REM_US]], 0 696; CHECK-NEXT: [[CMP5_US_FR:%.*]] = freeze i1 [[CMP5_US]] 697; CHECK-NEXT: br i1 [[CMP5_US_FR]], label [[FOR_COND1_PREHEADER_US_SPLIT_US:%.*]], label [[FOR_COND1_PREHEADER_US_SPLIT:%.*]] 698; CHECK: for.cond1.preheader.us.split.us: 699; CHECK-NEXT: br label [[FOR_BODY4_US_US:%.*]] 700; CHECK: for.body4.us.us: 701; CHECK-NEXT: [[J_019_US_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US_SPLIT_US]] ], [ [[INC_US_US:%.*]], [[TMP1:%.*]] ] 702; CHECK-NEXT: br label [[TMP0:%.*]] 703; CHECK: 0: 704; CHECK-NEXT: br label [[TMP1]] 705; CHECK: 1: 706; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_021_US]], [[TMP0]] ] 707; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]]) 708; CHECK-NEXT: [[INC_US_US]] = add nuw i32 [[J_019_US_US]], 1 709; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US_US]], [[M]] 710; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_SPLIT_US:%.*]], label [[FOR_BODY4_US_US]] 711; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us.split.us: 712; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] 713; CHECK: for.cond1.preheader.us.split: 714; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]] 715; CHECK: for.body4.us: 716; CHECK-NEXT: [[J_019_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US_SPLIT]] ], [ [[INC_US:%.*]], [[TMP2:%.*]] ] 717; CHECK-NEXT: br label [[TMP2]] 718; CHECK: 2: 719; CHECK-NEXT: tail call void @bar(i32 noundef [[J_019_US]]) 720; CHECK-NEXT: [[INC_US]] = add nuw i32 [[J_019_US]], 1 721; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC_US]], [[M]] 722; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US_SPLIT:%.*]], label [[FOR_BODY4_US]] 723; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us.split: 724; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] 725; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us: 726; CHECK-NEXT: [[INC9_US]] = add nuw i32 [[I_021_US]], 1 727; CHECK-NEXT: [[EXITCOND24_NOT:%.*]] = icmp eq i32 [[INC9_US]], [[N]] 728; CHECK-NEXT: br i1 [[EXITCOND24_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_COND1_PREHEADER_US]] 729; CHECK: for.cond.cleanup.loopexit: 730; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 731; CHECK: for.cond.cleanup: 732; CHECK-NEXT: ret void 733; 734entry: 735 %cmp20.not = icmp eq i32 %n, 0 736 %cmp218.not = icmp eq i32 %m, 0 737 %or.cond = or i1 %cmp20.not, %cmp218.not 738 br i1 %or.cond, label %for.cond.cleanup, label %for.cond1.preheader.us 739 740for.cond1.preheader.us: ; preds = %entry, %for.cond1.for.cond.cleanup3_crit_edge.us 741 %i.021.us = phi i32 [ %inc9.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %entry ] 742 %rem.us = and i32 %i.021.us, 1 743 %cmp5.us = icmp eq i32 %rem.us, 0 744 br label %for.body4.us 745 746for.body4.us: ; preds = %for.cond1.preheader.us, %for.body4.us 747 %j.019.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ] 748 %cond7.us = select i1 %cmp5.us, i32 %i.021.us, i32 %j.019.us 749 tail call void @bar(i32 noundef %cond7.us) #2 750 %inc.us = add nuw i32 %j.019.us, 1 751 %exitcond.not = icmp eq i32 %inc.us, %m 752 br i1 %exitcond.not, label %for.cond1.for.cond.cleanup3_crit_edge.us, label %for.body4.us 753 754for.cond1.for.cond.cleanup3_crit_edge.us: ; preds = %for.body4.us 755 %inc9.us = add nuw i32 %i.021.us, 1 756 %exitcond24.not = icmp eq i32 %inc9.us, %n 757 br i1 %exitcond24.not, label %for.cond.cleanup, label %for.cond1.preheader.us 758 759for.cond.cleanup: ; preds = %for.cond1.for.cond.cleanup3_crit_edge.us, %entry 760 ret void 761} 762 763; Unswitch %val should look through the trivial select and unswitch on %cond 764define dso_local i32 @trivial_select_cond(i32 noundef %n, i32 noundef %a, i32 noundef %b, i1 noundef %cond) { 765; CHECK-LABEL: define dso_local i32 @trivial_select_cond 766; CHECK-SAME: (i32 noundef [[N:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i1 noundef [[COND:%.*]]) { 767; CHECK-NEXT: entry: 768; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[N]], 0 769; CHECK-NEXT: [[TRIVIAL_COND:%.*]] = select i1 [[COND]], i1 true, i1 false 770; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 771; CHECK: for.body.preheader: 772; CHECK-NEXT: br i1 [[COND]], label [[FOR_BODY_PREHEADER_SPLIT_US:%.*]], label [[FOR_BODY_PREHEADER_SPLIT:%.*]] 773; CHECK: for.body.preheader.split.us: 774; CHECK-NEXT: br label [[FOR_BODY_US:%.*]] 775; CHECK: for.body.us: 776; CHECK-NEXT: [[I_03_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[TMP1:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT_US]] ] 777; CHECK-NEXT: br label [[TMP0:%.*]] 778; CHECK: 0: 779; CHECK-NEXT: br label [[TMP1]] 780; CHECK: 1: 781; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[A]], [[TMP0]] ] 782; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]]) 783; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_03_US]], 1 784; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US]], [[N]] 785; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_BODY_US]] 786; CHECK: for.cond.cleanup.loopexit.split.us: 787; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 788; CHECK: for.body.preheader.split: 789; CHECK-NEXT: br label [[FOR_BODY:%.*]] 790; CHECK: for.cond.cleanup.loopexit.split: 791; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]] 792; CHECK: for.cond.cleanup.loopexit: 793; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 794; CHECK: for.cond.cleanup: 795; CHECK-NEXT: ret i32 undef 796; CHECK: for.body: 797; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ [[INC:%.*]], [[TMP2:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT]] ] 798; CHECK-NEXT: br label [[TMP2]] 799; CHECK: 2: 800; CHECK-NEXT: tail call void @bar(i32 noundef [[B]]) 801; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_03]], 1 802; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[N]] 803; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_BODY]] 804; 805entry: 806 %cmp2 = icmp sgt i32 %n, 0 807 %trivial_cond = select i1 %cond, i1 true, i1 false 808 br i1 %cmp2, label %for.body, label %for.cond.cleanup 809 810for.cond.cleanup: ; preds = %for.body, %entry 811 ret i32 undef 812 813for.body: ; preds = %entry, %for.body 814 %i.03 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 815 %val = select i1 %trivial_cond, i32 %a, i32 %b 816 tail call void @bar(i32 noundef %val) 817 %inc = add nuw nsw i32 %i.03, 1 818 %exitcond.not = icmp eq i32 %inc, %n 819 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 820} 821 822; Test unswitch select when the condition is an AND whose LHS is invariant 823define i32 @and_lhs_invariant(i32 %num, i1 %cond) { 824; CHECK-LABEL: define i32 @and_lhs_invariant 825; CHECK-SAME: (i32 [[NUM:%.*]], i1 [[COND:%.*]]) { 826; CHECK-NEXT: entry: 827; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[NUM]], 0 828; CHECK-NEXT: br i1 [[CMP6]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 829; CHECK: for.body.preheader: 830; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]] 831; CHECK-NEXT: br i1 [[COND_FR]], label [[FOR_BODY_PREHEADER_SPLIT:%.*]], label [[FOR_BODY_PREHEADER_SPLIT_US:%.*]] 832; CHECK: for.body.preheader.split.us: 833; CHECK-NEXT: br label [[FOR_BODY_US:%.*]] 834; CHECK: for.body.us: 835; CHECK-NEXT: [[I_07_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[TMP0:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT_US]] ] 836; CHECK-NEXT: br label [[TMP0]] 837; CHECK: 0: 838; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ 0, [[FOR_BODY_US]] ] 839; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]]) 840; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_07_US]], 1 841; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US]], [[NUM]] 842; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_BODY_US]] 843; CHECK: for.cond.cleanup.loopexit.split.us: 844; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 845; CHECK: for.body.preheader.split: 846; CHECK-NEXT: br label [[FOR_BODY:%.*]] 847; CHECK: for.cond.cleanup.loopexit.split: 848; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]] 849; CHECK: for.cond.cleanup.loopexit: 850; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 851; CHECK: for.cond.cleanup: 852; CHECK-NEXT: ret i32 undef 853; CHECK: for.body: 854; CHECK-NEXT: [[I_07:%.*]] = phi i32 [ [[INC:%.*]], [[TMP3:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT]] ] 855; CHECK-NEXT: [[REM:%.*]] = and i32 [[I_07]], 1 856; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[REM]], 0 857; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[CMP1]] 858; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3]] 859; CHECK: 2: 860; CHECK-NEXT: br label [[TMP3]] 861; CHECK: 3: 862; CHECK-NEXT: [[UNSWITCHED_SELECT:%.*]] = phi i32 [ [[I_07]], [[TMP2]] ], [ 0, [[FOR_BODY]] ] 863; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT]]) 864; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_07]], 1 865; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]] 866; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_BODY]] 867; 868entry: 869 %cmp6 = icmp sgt i32 %num, 0 870 br i1 %cmp6, label %for.body, label %for.cond.cleanup 871 872for.cond.cleanup: ; preds = %for.body, %entry 873 ret i32 undef 874 875for.body: ; preds = %entry, %for.body 876 %i.07 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 877 %rem = and i32 %i.07, 1 878 %cmp1 = icmp eq i32 %rem, 0 879 %0 = and i1 %cond, %cmp1 880 %cond2 = select i1 %0, i32 %i.07, i32 0 881 tail call void @bar(i32 noundef %cond2) 882 %inc = add nuw nsw i32 %i.07, 1 883 %exitcond.not = icmp eq i32 %inc, %num 884 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 885} 886 887; Test unswitch select when the condition is an AND whose RHS is invariant 888define i32 @and_rhs_invariant(i32 %num, i1 %cond) { 889; CHECK-LABEL: define i32 @and_rhs_invariant 890; CHECK-SAME: (i32 [[NUM:%.*]], i1 [[COND:%.*]]) { 891; CHECK-NEXT: entry: 892; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[NUM]], 0 893; CHECK-NEXT: br i1 [[CMP6]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 894; CHECK: for.body.preheader: 895; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]] 896; CHECK-NEXT: br i1 [[COND_FR]], label [[FOR_BODY_PREHEADER_SPLIT:%.*]], label [[FOR_BODY_PREHEADER_SPLIT_US:%.*]] 897; CHECK: for.body.preheader.split.us: 898; CHECK-NEXT: br label [[FOR_BODY_US:%.*]] 899; CHECK: for.body.us: 900; CHECK-NEXT: [[I_07_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[TMP0:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT_US]] ] 901; CHECK-NEXT: br label [[TMP0]] 902; CHECK: 0: 903; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ 0, [[FOR_BODY_US]] ] 904; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]]) 905; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_07_US]], 1 906; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US]], [[NUM]] 907; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_BODY_US]] 908; CHECK: for.cond.cleanup.loopexit.split.us: 909; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 910; CHECK: for.body.preheader.split: 911; CHECK-NEXT: br label [[FOR_BODY:%.*]] 912; CHECK: for.cond.cleanup.loopexit.split: 913; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]] 914; CHECK: for.cond.cleanup.loopexit: 915; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 916; CHECK: for.cond.cleanup: 917; CHECK-NEXT: ret i32 undef 918; CHECK: for.body: 919; CHECK-NEXT: [[I_07:%.*]] = phi i32 [ [[INC:%.*]], [[TMP3:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT]] ] 920; CHECK-NEXT: [[REM:%.*]] = and i32 [[I_07]], 1 921; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[REM]], 0 922; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[CMP1]], true 923; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3]] 924; CHECK: 2: 925; CHECK-NEXT: br label [[TMP3]] 926; CHECK: 3: 927; CHECK-NEXT: [[UNSWITCHED_SELECT:%.*]] = phi i32 [ [[I_07]], [[TMP2]] ], [ 0, [[FOR_BODY]] ] 928; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT]]) 929; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_07]], 1 930; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]] 931; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_BODY]] 932; 933entry: 934 %cmp6 = icmp sgt i32 %num, 0 935 br i1 %cmp6, label %for.body, label %for.cond.cleanup 936 937for.cond.cleanup: ; preds = %for.body, %entry 938 ret i32 undef 939 940for.body: ; preds = %entry, %for.body 941 %i.07 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 942 %rem = and i32 %i.07, 1 943 %cmp1 = icmp eq i32 %rem, 0 944 %0 = and i1 %cmp1, %cond 945 %cond2 = select i1 %0, i32 %i.07, i32 0 946 tail call void @bar(i32 noundef %cond2) 947 %inc = add nuw nsw i32 %i.07, 1 948 %exitcond.not = icmp eq i32 %inc, %num 949 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 950} 951 952; Test unswitch select when the condition is an OR whose LHS is invariant 953define i32 @or_lhs_invariant(i32 %num, i1 %cond) { 954; CHECK-LABEL: define i32 @or_lhs_invariant 955; CHECK-SAME: (i32 [[NUM:%.*]], i1 [[COND:%.*]]) { 956; CHECK-NEXT: entry: 957; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[NUM]], 0 958; CHECK-NEXT: br i1 [[CMP6]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 959; CHECK: for.body.preheader: 960; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]] 961; CHECK-NEXT: br i1 [[COND_FR]], label [[FOR_BODY_PREHEADER_SPLIT_US:%.*]], label [[FOR_BODY_PREHEADER_SPLIT:%.*]] 962; CHECK: for.body.preheader.split.us: 963; CHECK-NEXT: br label [[FOR_BODY_US:%.*]] 964; CHECK: for.body.us: 965; CHECK-NEXT: [[I_07_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[TMP1:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT_US]] ] 966; CHECK-NEXT: br label [[TMP0:%.*]] 967; CHECK: 0: 968; CHECK-NEXT: br label [[TMP1]] 969; CHECK: 1: 970; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_07_US]], [[TMP0]] ] 971; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]]) 972; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_07_US]], 1 973; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US]], [[NUM]] 974; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_BODY_US]] 975; CHECK: for.cond.cleanup.loopexit.split.us: 976; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 977; CHECK: for.body.preheader.split: 978; CHECK-NEXT: br label [[FOR_BODY:%.*]] 979; CHECK: for.cond.cleanup.loopexit.split: 980; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]] 981; CHECK: for.cond.cleanup.loopexit: 982; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 983; CHECK: for.cond.cleanup: 984; CHECK-NEXT: ret i32 undef 985; CHECK: for.body: 986; CHECK-NEXT: [[I_07:%.*]] = phi i32 [ [[INC:%.*]], [[TMP4:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT]] ] 987; CHECK-NEXT: [[REM:%.*]] = and i32 [[I_07]], 1 988; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[REM]], 0 989; CHECK-NEXT: [[TMP2:%.*]] = or i1 false, [[CMP1]] 990; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4]] 991; CHECK: 3: 992; CHECK-NEXT: br label [[TMP4]] 993; CHECK: 4: 994; CHECK-NEXT: [[UNSWITCHED_SELECT:%.*]] = phi i32 [ [[I_07]], [[TMP3]] ], [ 0, [[FOR_BODY]] ] 995; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT]]) 996; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_07]], 1 997; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]] 998; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_BODY]] 999; 1000entry: 1001 %cmp6 = icmp sgt i32 %num, 0 1002 br i1 %cmp6, label %for.body, label %for.cond.cleanup 1003 1004for.cond.cleanup: ; preds = %for.body, %entry 1005 ret i32 undef 1006 1007for.body: ; preds = %entry, %for.body 1008 %i.07 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 1009 %rem = and i32 %i.07, 1 1010 %cmp1 = icmp eq i32 %rem, 0 1011 %0 = or i1 %cond, %cmp1 1012 %cond2 = select i1 %0, i32 %i.07, i32 0 1013 tail call void @bar(i32 noundef %cond2) 1014 %inc = add nuw nsw i32 %i.07, 1 1015 %exitcond.not = icmp eq i32 %inc, %num 1016 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1017} 1018 1019; Test unswitch select when the condition is an OR whose RHS is invariant 1020define i32 @or_rhs_invariant(i32 %num, i1 %cond) { 1021; CHECK-LABEL: define i32 @or_rhs_invariant 1022; CHECK-SAME: (i32 [[NUM:%.*]], i1 [[COND:%.*]]) { 1023; CHECK-NEXT: entry: 1024; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[NUM]], 0 1025; CHECK-NEXT: br i1 [[CMP6]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 1026; CHECK: for.body.preheader: 1027; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]] 1028; CHECK-NEXT: br i1 [[COND_FR]], label [[FOR_BODY_PREHEADER_SPLIT_US:%.*]], label [[FOR_BODY_PREHEADER_SPLIT:%.*]] 1029; CHECK: for.body.preheader.split.us: 1030; CHECK-NEXT: br label [[FOR_BODY_US:%.*]] 1031; CHECK: for.body.us: 1032; CHECK-NEXT: [[I_07_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[TMP1:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT_US]] ] 1033; CHECK-NEXT: br label [[TMP0:%.*]] 1034; CHECK: 0: 1035; CHECK-NEXT: br label [[TMP1]] 1036; CHECK: 1: 1037; CHECK-NEXT: [[UNSWITCHED_SELECT_US:%.*]] = phi i32 [ [[I_07_US]], [[TMP0]] ] 1038; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT_US]]) 1039; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[I_07_US]], 1 1040; CHECK-NEXT: [[EXITCOND_NOT_US:%.*]] = icmp eq i32 [[INC_US]], [[NUM]] 1041; CHECK-NEXT: br i1 [[EXITCOND_NOT_US]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT_US:%.*]], label [[FOR_BODY_US]] 1042; CHECK: for.cond.cleanup.loopexit.split.us: 1043; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 1044; CHECK: for.body.preheader.split: 1045; CHECK-NEXT: br label [[FOR_BODY:%.*]] 1046; CHECK: for.cond.cleanup.loopexit.split: 1047; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]] 1048; CHECK: for.cond.cleanup.loopexit: 1049; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 1050; CHECK: for.cond.cleanup: 1051; CHECK-NEXT: ret i32 undef 1052; CHECK: for.body: 1053; CHECK-NEXT: [[I_07:%.*]] = phi i32 [ [[INC:%.*]], [[TMP4:%.*]] ], [ 0, [[FOR_BODY_PREHEADER_SPLIT]] ] 1054; CHECK-NEXT: [[REM:%.*]] = and i32 [[I_07]], 1 1055; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[REM]], 0 1056; CHECK-NEXT: [[TMP2:%.*]] = or i1 [[CMP1]], false 1057; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4]] 1058; CHECK: 3: 1059; CHECK-NEXT: br label [[TMP4]] 1060; CHECK: 4: 1061; CHECK-NEXT: [[UNSWITCHED_SELECT:%.*]] = phi i32 [ [[I_07]], [[TMP3]] ], [ 0, [[FOR_BODY]] ] 1062; CHECK-NEXT: tail call void @bar(i32 noundef [[UNSWITCHED_SELECT]]) 1063; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_07]], 1 1064; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]] 1065; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_SPLIT:%.*]], label [[FOR_BODY]] 1066; 1067entry: 1068 %cmp6 = icmp sgt i32 %num, 0 1069 br i1 %cmp6, label %for.body, label %for.cond.cleanup 1070 1071for.cond.cleanup: ; preds = %for.body, %entry 1072 ret i32 undef 1073 1074for.body: ; preds = %entry, %for.body 1075 %i.07 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 1076 %rem = and i32 %i.07, 1 1077 %cmp1 = icmp eq i32 %rem, 0 1078 %0 = or i1 %cmp1, %cond 1079 %cond2 = select i1 %0, i32 %i.07, i32 0 1080 tail call void @bar(i32 noundef %cond2) 1081 %inc = add nuw nsw i32 %i.07, 1 1082 %exitcond.not = icmp eq i32 %inc, %num 1083 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1084} 1085