1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes 2; RUN: opt -passes='hardware-loops<force-hardware-loops;hardware-loop-decrement=1;hardware-loop-counter-bitwidth=32>' -S %s -o - | FileCheck %s --check-prefix=CHECK-DEC 3; RUN: opt -passes='hardware-loops<force-hardware-loops;hardware-loop-decrement=1;hardware-loop-counter-bitwidth=32;force-hardware-loop-phi>' -S %s -o - | FileCheck %s --check-prefix=CHECK-PHI 4 5define void @while_lt(i32 %i, i32 %N, ptr nocapture %A) strictfp { 6; CHECK-DEC: Function Attrs: strictfp 7; CHECK-DEC-LABEL: @while_lt( 8; CHECK-DEC-NEXT: entry: 9; CHECK-DEC-NEXT: [[CMP4:%.*]] = icmp ult i32 [[I:%.*]], [[N:%.*]] 10; CHECK-DEC-NEXT: br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]] 11; CHECK-DEC: while.body.preheader: 12; CHECK-DEC-NEXT: [[TMP0:%.*]] = sub i32 [[N]], [[I]] 13; CHECK-DEC-NEXT: call void @llvm.set.loop.iterations.i32(i32 [[TMP0]]) #[[ATTR0:[0-9]+]] 14; CHECK-DEC-NEXT: br label [[WHILE_BODY:%.*]] 15; CHECK-DEC: while.body: 16; CHECK-DEC-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ] 17; CHECK-DEC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 18; CHECK-DEC-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 19; CHECK-DEC-NEXT: [[INC]] = add nuw i32 [[I_ADDR_05]], 1 20; CHECK-DEC-NEXT: [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]] 21; CHECK-DEC-NEXT: br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]] 22; CHECK-DEC: while.end: 23; CHECK-DEC-NEXT: ret void 24; 25; CHECK-PHI: Function Attrs: strictfp 26; CHECK-PHI-LABEL: @while_lt( 27; CHECK-PHI-NEXT: entry: 28; CHECK-PHI-NEXT: [[CMP4:%.*]] = icmp ult i32 [[I:%.*]], [[N:%.*]] 29; CHECK-PHI-NEXT: br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]] 30; CHECK-PHI: while.body.preheader: 31; CHECK-PHI-NEXT: [[TMP0:%.*]] = sub i32 [[N]], [[I]] 32; CHECK-PHI-NEXT: [[TMP1:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP0]]) #[[ATTR0:[0-9]+]] 33; CHECK-PHI-NEXT: br label [[WHILE_BODY:%.*]] 34; CHECK-PHI: while.body: 35; CHECK-PHI-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ] 36; CHECK-PHI-NEXT: [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP3:%.*]], [[WHILE_BODY]] ] 37; CHECK-PHI-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 38; CHECK-PHI-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 39; CHECK-PHI-NEXT: [[INC]] = add nuw i32 [[I_ADDR_05]], 1 40; CHECK-PHI-NEXT: [[TMP3]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP2]], i32 1) #[[ATTR0]] 41; CHECK-PHI-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0 42; CHECK-PHI-NEXT: br i1 [[TMP4]], label [[WHILE_BODY]], label [[WHILE_END]] 43; CHECK-PHI: while.end: 44; CHECK-PHI-NEXT: ret void 45; 46entry: 47 %cmp4 = icmp ult i32 %i, %N 48 br i1 %cmp4, label %while.body, label %while.end 49 50while.body: 51 %i.addr.05 = phi i32 [ %inc, %while.body ], [ %i, %entry ] 52 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05 53 store i32 %i.addr.05, ptr %arrayidx, align 4 54 %inc = add nuw i32 %i.addr.05, 1 55 %exitcond = icmp eq i32 %inc, %N 56 br i1 %exitcond, label %while.end, label %while.body 57 58while.end: 59 ret void 60} 61 62define void @while_gt(i32 %i, i32 %N, ptr nocapture %A) strictfp { 63; CHECK-DEC: Function Attrs: strictfp 64; CHECK-DEC-LABEL: @while_gt( 65; CHECK-DEC-NEXT: entry: 66; CHECK-DEC-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[I:%.*]], [[N:%.*]] 67; CHECK-DEC-NEXT: br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]] 68; CHECK-DEC: while.body.preheader: 69; CHECK-DEC-NEXT: [[TMP0:%.*]] = sub i32 [[I]], [[N]] 70; CHECK-DEC-NEXT: call void @llvm.set.loop.iterations.i32(i32 [[TMP0]]) #[[ATTR0]] 71; CHECK-DEC-NEXT: br label [[WHILE_BODY:%.*]] 72; CHECK-DEC: while.body: 73; CHECK-DEC-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ] 74; CHECK-DEC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 75; CHECK-DEC-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 76; CHECK-DEC-NEXT: [[DEC]] = add nsw i32 [[I_ADDR_05]], -1 77; CHECK-DEC-NEXT: [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]] 78; CHECK-DEC-NEXT: br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]] 79; CHECK-DEC: while.end: 80; CHECK-DEC-NEXT: ret void 81; 82; CHECK-PHI: Function Attrs: strictfp 83; CHECK-PHI-LABEL: @while_gt( 84; CHECK-PHI-NEXT: entry: 85; CHECK-PHI-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[I:%.*]], [[N:%.*]] 86; CHECK-PHI-NEXT: br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]] 87; CHECK-PHI: while.body.preheader: 88; CHECK-PHI-NEXT: [[TMP0:%.*]] = sub i32 [[I]], [[N]] 89; CHECK-PHI-NEXT: [[TMP1:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP0]]) #[[ATTR0]] 90; CHECK-PHI-NEXT: br label [[WHILE_BODY:%.*]] 91; CHECK-PHI: while.body: 92; CHECK-PHI-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ] 93; CHECK-PHI-NEXT: [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP3:%.*]], [[WHILE_BODY]] ] 94; CHECK-PHI-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 95; CHECK-PHI-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 96; CHECK-PHI-NEXT: [[DEC]] = add nsw i32 [[I_ADDR_05]], -1 97; CHECK-PHI-NEXT: [[TMP3]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP2]], i32 1) #[[ATTR0]] 98; CHECK-PHI-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0 99; CHECK-PHI-NEXT: br i1 [[TMP4]], label [[WHILE_BODY]], label [[WHILE_END]] 100; CHECK-PHI: while.end: 101; CHECK-PHI-NEXT: ret void 102; 103entry: 104 %cmp4 = icmp sgt i32 %i, %N 105 br i1 %cmp4, label %while.body, label %while.end 106 107while.body: 108 %i.addr.05 = phi i32 [ %dec, %while.body ], [ %i, %entry ] 109 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05 110 store i32 %i.addr.05, ptr %arrayidx, align 4 111 %dec = add nsw i32 %i.addr.05, -1 112 %cmp = icmp sgt i32 %dec, %N 113 br i1 %cmp, label %while.body, label %while.end 114 115while.end: 116 ret void 117} 118 119define void @while_gte(i32 %i, i32 %N, ptr nocapture %A) strictfp { 120; CHECK-DEC: Function Attrs: strictfp 121; CHECK-DEC-LABEL: @while_gte( 122; CHECK-DEC-NEXT: entry: 123; CHECK-DEC-NEXT: [[CMP4:%.*]] = icmp slt i32 [[I:%.*]], [[N:%.*]] 124; CHECK-DEC-NEXT: br i1 [[CMP4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 125; CHECK-DEC: while.body.preheader: 126; CHECK-DEC-NEXT: [[TMP0:%.*]] = add i32 [[I]], 1 127; CHECK-DEC-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[N]] 128; CHECK-DEC-NEXT: call void @llvm.set.loop.iterations.i32(i32 [[TMP1]]) #[[ATTR0]] 129; CHECK-DEC-NEXT: br label [[WHILE_BODY:%.*]] 130; CHECK-DEC: while.body: 131; CHECK-DEC-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ] 132; CHECK-DEC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 133; CHECK-DEC-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 134; CHECK-DEC-NEXT: [[DEC]] = add nsw i32 [[I_ADDR_05]], -1 135; CHECK-DEC-NEXT: [[TMP2:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]] 136; CHECK-DEC-NEXT: br i1 [[TMP2]], label [[WHILE_BODY]], label [[WHILE_END]] 137; CHECK-DEC: while.end: 138; CHECK-DEC-NEXT: ret void 139; 140; CHECK-PHI: Function Attrs: strictfp 141; CHECK-PHI-LABEL: @while_gte( 142; CHECK-PHI-NEXT: entry: 143; CHECK-PHI-NEXT: [[CMP4:%.*]] = icmp slt i32 [[I:%.*]], [[N:%.*]] 144; CHECK-PHI-NEXT: br i1 [[CMP4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 145; CHECK-PHI: while.body.preheader: 146; CHECK-PHI-NEXT: [[TMP0:%.*]] = add i32 [[I]], 1 147; CHECK-PHI-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[N]] 148; CHECK-PHI-NEXT: [[TMP2:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP1]]) #[[ATTR0]] 149; CHECK-PHI-NEXT: br label [[WHILE_BODY:%.*]] 150; CHECK-PHI: while.body: 151; CHECK-PHI-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ] 152; CHECK-PHI-NEXT: [[TMP3:%.*]] = phi i32 [ [[TMP2]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP4:%.*]], [[WHILE_BODY]] ] 153; CHECK-PHI-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 154; CHECK-PHI-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 155; CHECK-PHI-NEXT: [[DEC]] = add nsw i32 [[I_ADDR_05]], -1 156; CHECK-PHI-NEXT: [[TMP4]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP3]], i32 1) #[[ATTR0]] 157; CHECK-PHI-NEXT: [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0 158; CHECK-PHI-NEXT: br i1 [[TMP5]], label [[WHILE_BODY]], label [[WHILE_END]] 159; CHECK-PHI: while.end: 160; CHECK-PHI-NEXT: ret void 161; 162entry: 163 %cmp4 = icmp slt i32 %i, %N 164 br i1 %cmp4, label %while.end, label %while.body 165 166while.body: 167 %i.addr.05 = phi i32 [ %dec, %while.body ], [ %i, %entry ] 168 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05 169 store i32 %i.addr.05, ptr %arrayidx, align 4 170 %dec = add nsw i32 %i.addr.05, -1 171 %cmp = icmp sgt i32 %i.addr.05, %N 172 br i1 %cmp, label %while.body, label %while.end 173 174while.end: 175 ret void 176} 177 178define void @while_ne(i32 %N, ptr nocapture %A) strictfp { 179; CHECK-DEC: Function Attrs: strictfp 180; CHECK-DEC-LABEL: @while_ne( 181; CHECK-DEC-NEXT: entry: 182; CHECK-DEC-NEXT: [[CMP:%.*]] = icmp ne i32 [[N:%.*]], 0 183; CHECK-DEC-NEXT: br i1 [[CMP]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]] 184; CHECK-DEC: while.body.preheader: 185; CHECK-DEC-NEXT: call void @llvm.set.loop.iterations.i32(i32 [[N]]) #[[ATTR0]] 186; CHECK-DEC-NEXT: br label [[WHILE_BODY:%.*]] 187; CHECK-DEC: while.body: 188; CHECK-DEC-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 189; CHECK-DEC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 190; CHECK-DEC-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 191; CHECK-DEC-NEXT: [[INC]] = add nuw i32 [[I_ADDR_05]], 1 192; CHECK-DEC-NEXT: [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]] 193; CHECK-DEC-NEXT: br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]] 194; CHECK-DEC: while.end: 195; CHECK-DEC-NEXT: ret void 196; 197; CHECK-PHI: Function Attrs: strictfp 198; CHECK-PHI-LABEL: @while_ne( 199; CHECK-PHI-NEXT: entry: 200; CHECK-PHI-NEXT: [[CMP:%.*]] = icmp ne i32 [[N:%.*]], 0 201; CHECK-PHI-NEXT: br i1 [[CMP]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]] 202; CHECK-PHI: while.body.preheader: 203; CHECK-PHI-NEXT: [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) #[[ATTR0]] 204; CHECK-PHI-NEXT: br label [[WHILE_BODY:%.*]] 205; CHECK-PHI: while.body: 206; CHECK-PHI-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 207; CHECK-PHI-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP2:%.*]], [[WHILE_BODY]] ] 208; CHECK-PHI-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 209; CHECK-PHI-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 210; CHECK-PHI-NEXT: [[INC]] = add nuw i32 [[I_ADDR_05]], 1 211; CHECK-PHI-NEXT: [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1) #[[ATTR0]] 212; CHECK-PHI-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 213; CHECK-PHI-NEXT: br i1 [[TMP3]], label [[WHILE_BODY]], label [[WHILE_END]] 214; CHECK-PHI: while.end: 215; CHECK-PHI-NEXT: ret void 216; 217entry: 218 %cmp = icmp ne i32 %N, 0 219 br i1 %cmp, label %while.body, label %while.end 220 221while.body: 222 %i.addr.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ] 223 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05 224 store i32 %i.addr.05, ptr %arrayidx, align 4 225 %inc = add nuw i32 %i.addr.05, 1 226 %exitcond = icmp eq i32 %inc, %N 227 br i1 %exitcond, label %while.end, label %while.body 228 229while.end: 230 ret void 231} 232 233define void @while_eq(i32 %N, ptr nocapture %A) strictfp { 234; CHECK-DEC: Function Attrs: strictfp 235; CHECK-DEC-LABEL: @while_eq( 236; CHECK-DEC-NEXT: entry: 237; CHECK-DEC-NEXT: [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0 238; CHECK-DEC-NEXT: br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 239; CHECK-DEC: while.body.preheader: 240; CHECK-DEC-NEXT: call void @llvm.set.loop.iterations.i32(i32 [[N]]) #[[ATTR0]] 241; CHECK-DEC-NEXT: br label [[WHILE_BODY:%.*]] 242; CHECK-DEC: while.body: 243; CHECK-DEC-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 244; CHECK-DEC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 245; CHECK-DEC-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 246; CHECK-DEC-NEXT: [[INC]] = add nuw i32 [[I_ADDR_05]], 1 247; CHECK-DEC-NEXT: [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]] 248; CHECK-DEC-NEXT: br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]] 249; CHECK-DEC: while.end: 250; CHECK-DEC-NEXT: ret void 251; 252; CHECK-PHI: Function Attrs: strictfp 253; CHECK-PHI-LABEL: @while_eq( 254; CHECK-PHI-NEXT: entry: 255; CHECK-PHI-NEXT: [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0 256; CHECK-PHI-NEXT: br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 257; CHECK-PHI: while.body.preheader: 258; CHECK-PHI-NEXT: [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) #[[ATTR0]] 259; CHECK-PHI-NEXT: br label [[WHILE_BODY:%.*]] 260; CHECK-PHI: while.body: 261; CHECK-PHI-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 262; CHECK-PHI-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP2:%.*]], [[WHILE_BODY]] ] 263; CHECK-PHI-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 264; CHECK-PHI-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 265; CHECK-PHI-NEXT: [[INC]] = add nuw i32 [[I_ADDR_05]], 1 266; CHECK-PHI-NEXT: [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1) #[[ATTR0]] 267; CHECK-PHI-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 268; CHECK-PHI-NEXT: br i1 [[TMP3]], label [[WHILE_BODY]], label [[WHILE_END]] 269; CHECK-PHI: while.end: 270; CHECK-PHI-NEXT: ret void 271; 272entry: 273 %cmp = icmp eq i32 %N, 0 274 br i1 %cmp, label %while.end, label %while.body 275 276while.body: 277 %i.addr.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ] 278 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05 279 store i32 %i.addr.05, ptr %arrayidx, align 4 280 %inc = add nuw i32 %i.addr.05, 1 281 %exitcond = icmp eq i32 %inc, %N 282 br i1 %exitcond, label %while.end, label %while.body 283 284while.end: 285 ret void 286} 287 288define void @while_preheader_eq(i32 %N, ptr nocapture %A) strictfp { 289; CHECK-DEC: Function Attrs: strictfp 290; CHECK-DEC-LABEL: @while_preheader_eq( 291; CHECK-DEC-NEXT: entry: 292; CHECK-DEC-NEXT: br label [[PREHEADER:%.*]] 293; CHECK-DEC: preheader: 294; CHECK-DEC-NEXT: [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0 295; CHECK-DEC-NEXT: br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 296; CHECK-DEC: while.body.preheader: 297; CHECK-DEC-NEXT: call void @llvm.set.loop.iterations.i32(i32 [[N]]) #[[ATTR0]] 298; CHECK-DEC-NEXT: br label [[WHILE_BODY:%.*]] 299; CHECK-DEC: while.body: 300; CHECK-DEC-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 301; CHECK-DEC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 302; CHECK-DEC-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 303; CHECK-DEC-NEXT: [[INC]] = add nuw i32 [[I_ADDR_05]], 1 304; CHECK-DEC-NEXT: [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]] 305; CHECK-DEC-NEXT: br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]] 306; CHECK-DEC: while.end: 307; CHECK-DEC-NEXT: ret void 308; 309; CHECK-PHI: Function Attrs: strictfp 310; CHECK-PHI-LABEL: @while_preheader_eq( 311; CHECK-PHI-NEXT: entry: 312; CHECK-PHI-NEXT: br label [[PREHEADER:%.*]] 313; CHECK-PHI: preheader: 314; CHECK-PHI-NEXT: [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0 315; CHECK-PHI-NEXT: br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 316; CHECK-PHI: while.body.preheader: 317; CHECK-PHI-NEXT: [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) #[[ATTR0]] 318; CHECK-PHI-NEXT: br label [[WHILE_BODY:%.*]] 319; CHECK-PHI: while.body: 320; CHECK-PHI-NEXT: [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 321; CHECK-PHI-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP2:%.*]], [[WHILE_BODY]] ] 322; CHECK-PHI-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]] 323; CHECK-PHI-NEXT: store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4 324; CHECK-PHI-NEXT: [[INC]] = add nuw i32 [[I_ADDR_05]], 1 325; CHECK-PHI-NEXT: [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1) #[[ATTR0]] 326; CHECK-PHI-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 327; CHECK-PHI-NEXT: br i1 [[TMP3]], label [[WHILE_BODY]], label [[WHILE_END]] 328; CHECK-PHI: while.end: 329; CHECK-PHI-NEXT: ret void 330; 331entry: 332 br label %preheader 333 334preheader: 335 %cmp = icmp eq i32 %N, 0 336 br i1 %cmp, label %while.end, label %while.body 337 338while.body: 339 %i.addr.05 = phi i32 [ %inc, %while.body ], [ 0, %preheader ] 340 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05 341 store i32 %i.addr.05, ptr %arrayidx, align 4 342 %inc = add nuw i32 %i.addr.05, 1 343 %exitcond = icmp eq i32 %inc, %N 344 br i1 %exitcond, label %while.end, label %while.body 345 346while.end: 347 ret void 348} 349 350define void @nested(ptr nocapture %A, i32 %N) strictfp { 351; CHECK-DEC: Function Attrs: strictfp 352; CHECK-DEC-LABEL: @nested( 353; CHECK-DEC-NEXT: entry: 354; CHECK-DEC-NEXT: [[CMP20:%.*]] = icmp eq i32 [[N:%.*]], 0 355; CHECK-DEC-NEXT: br i1 [[CMP20]], label [[WHILE_END7:%.*]], label [[WHILE_COND1_PREHEADER_US:%.*]] 356; CHECK-DEC: while.cond1.preheader.us: 357; CHECK-DEC-NEXT: [[I_021_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[WHILE_COND1_WHILE_END_CRIT_EDGE_US:%.*]] ], [ 0, [[ENTRY:%.*]] ] 358; CHECK-DEC-NEXT: [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]] 359; CHECK-DEC-NEXT: call void @llvm.set.loop.iterations.i32(i32 [[N]]) #[[ATTR0]] 360; CHECK-DEC-NEXT: br label [[WHILE_BODY3_US:%.*]] 361; CHECK-DEC: while.body3.us: 362; CHECK-DEC-NEXT: [[J_019_US:%.*]] = phi i32 [ 0, [[WHILE_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[WHILE_BODY3_US]] ] 363; CHECK-DEC-NEXT: [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]] 364; CHECK-DEC-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[ADD_US]] 365; CHECK-DEC-NEXT: store i32 [[ADD_US]], ptr [[ARRAYIDX_US]], align 4 366; CHECK-DEC-NEXT: [[INC_US]] = add nuw i32 [[J_019_US]], 1 367; CHECK-DEC-NEXT: [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]] 368; CHECK-DEC-NEXT: br i1 [[TMP0]], label [[WHILE_BODY3_US]], label [[WHILE_COND1_WHILE_END_CRIT_EDGE_US]] 369; CHECK-DEC: while.cond1.while.end_crit_edge.us: 370; CHECK-DEC-NEXT: [[INC6_US]] = add nuw i32 [[I_021_US]], 1 371; CHECK-DEC-NEXT: [[EXITCOND23:%.*]] = icmp eq i32 [[INC6_US]], [[N]] 372; CHECK-DEC-NEXT: br i1 [[EXITCOND23]], label [[WHILE_END7]], label [[WHILE_COND1_PREHEADER_US]] 373; CHECK-DEC: while.end7: 374; CHECK-DEC-NEXT: ret void 375; 376; CHECK-PHI: Function Attrs: strictfp 377; CHECK-PHI-LABEL: @nested( 378; CHECK-PHI-NEXT: entry: 379; CHECK-PHI-NEXT: [[CMP20:%.*]] = icmp eq i32 [[N:%.*]], 0 380; CHECK-PHI-NEXT: br i1 [[CMP20]], label [[WHILE_END7:%.*]], label [[WHILE_COND1_PREHEADER_US:%.*]] 381; CHECK-PHI: while.cond1.preheader.us: 382; CHECK-PHI-NEXT: [[I_021_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[WHILE_COND1_WHILE_END_CRIT_EDGE_US:%.*]] ], [ 0, [[ENTRY:%.*]] ] 383; CHECK-PHI-NEXT: [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]] 384; CHECK-PHI-NEXT: [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) #[[ATTR0]] 385; CHECK-PHI-NEXT: br label [[WHILE_BODY3_US:%.*]] 386; CHECK-PHI: while.body3.us: 387; CHECK-PHI-NEXT: [[J_019_US:%.*]] = phi i32 [ 0, [[WHILE_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[WHILE_BODY3_US]] ] 388; CHECK-PHI-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_COND1_PREHEADER_US]] ], [ [[TMP2:%.*]], [[WHILE_BODY3_US]] ] 389; CHECK-PHI-NEXT: [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]] 390; CHECK-PHI-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[ADD_US]] 391; CHECK-PHI-NEXT: store i32 [[ADD_US]], ptr [[ARRAYIDX_US]], align 4 392; CHECK-PHI-NEXT: [[INC_US]] = add nuw i32 [[J_019_US]], 1 393; CHECK-PHI-NEXT: [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1) #[[ATTR0]] 394; CHECK-PHI-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 395; CHECK-PHI-NEXT: br i1 [[TMP3]], label [[WHILE_BODY3_US]], label [[WHILE_COND1_WHILE_END_CRIT_EDGE_US]] 396; CHECK-PHI: while.cond1.while.end_crit_edge.us: 397; CHECK-PHI-NEXT: [[INC6_US]] = add nuw i32 [[I_021_US]], 1 398; CHECK-PHI-NEXT: [[EXITCOND23:%.*]] = icmp eq i32 [[INC6_US]], [[N]] 399; CHECK-PHI-NEXT: br i1 [[EXITCOND23]], label [[WHILE_END7]], label [[WHILE_COND1_PREHEADER_US]] 400; CHECK-PHI: while.end7: 401; CHECK-PHI-NEXT: ret void 402; 403entry: 404 %cmp20 = icmp eq i32 %N, 0 405 br i1 %cmp20, label %while.end7, label %while.cond1.preheader.us 406 407while.cond1.preheader.us: 408 %i.021.us = phi i32 [ %inc6.us, %while.cond1.while.end_crit_edge.us ], [ 0, %entry ] 409 %mul.us = mul i32 %i.021.us, %N 410 br label %while.body3.us 411 412while.body3.us: 413 %j.019.us = phi i32 [ 0, %while.cond1.preheader.us ], [ %inc.us, %while.body3.us ] 414 %add.us = add i32 %j.019.us, %mul.us 415 %arrayidx.us = getelementptr inbounds i32, ptr %A, i32 %add.us 416 store i32 %add.us, ptr %arrayidx.us, align 4 417 %inc.us = add nuw i32 %j.019.us, 1 418 %exitcond = icmp eq i32 %inc.us, %N 419 br i1 %exitcond, label %while.cond1.while.end_crit_edge.us, label %while.body3.us 420 421while.cond1.while.end_crit_edge.us: 422 %inc6.us = add nuw i32 %i.021.us, 1 423 %exitcond23 = icmp eq i32 %inc6.us, %N 424 br i1 %exitcond23, label %while.end7, label %while.cond1.preheader.us 425 426while.end7: 427 ret void 428} 429