1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 3; RUN: opt < %s -S -passes='loop-simplify,loop(loop-flatten),adce,verify' -loop-flatten-widen-iv=true \ 4; RUN: -loop-flatten-version-loops=false -verify-loop-info -verify-dom-info -verify-scev \ 5; RUN: -loop-flatten-cost-threshold=6 | \ 6; RUN: FileCheck %s --check-prefix=CHECK 7 8; RUN: opt < %s -S -passes='loop-simplify,loop(loop-flatten),adce,verify' -loop-flatten-widen-iv=false \ 9; RUN: -loop-flatten-version-loops=false -verify-loop-info -verify-dom-info -verify-scev | \ 10; RUN: FileCheck %s --check-prefix=DONTWIDEN 11 12target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" 13 14; DONTWIDEN-NOT: %flatten.tripcount 15; DONTWIDEN-NOT: %flatten.trunciv 16 17; Function Attrs: nounwind 18define void @foo(ptr %A, i32 %N, i32 %M) { 19; CHECK-LABEL: @foo( 20; CHECK-NEXT: entry: 21; CHECK-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0 22; CHECK-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]] 23; CHECK: for.cond1.preheader.lr.ph: 24; CHECK-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0 25; CHECK-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]] 26; CHECK: for.cond1.preheader.us.preheader: 27; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[M]] to i64 28; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[N]] to i64 29; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]] 30; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 31; CHECK: for.cond1.preheader.us: 32; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] 33; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]] 34; CHECK: for.body4.us: 35; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVAR2]] 36; CHECK-NEXT: tail call void @f(ptr [[ARRAYIDX_US]]) 37; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] 38; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us: 39; CHECK-NEXT: [[INDVAR_NEXT3]] = add nuw nsw i64 [[INDVAR2]], 1 40; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]] 41; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 42; CHECK: for.cond.cleanup.loopexit: 43; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 44; CHECK: for.cond.cleanup: 45; CHECK-NEXT: ret void 46; 47; DONTWIDEN-LABEL: @foo( 48; DONTWIDEN-NEXT: entry: 49; DONTWIDEN-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0 50; DONTWIDEN-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]] 51; DONTWIDEN: for.cond1.preheader.lr.ph: 52; DONTWIDEN-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0 53; DONTWIDEN-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]] 54; DONTWIDEN: for.cond1.preheader.us.preheader: 55; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 56; DONTWIDEN: for.cond1.preheader.us: 57; DONTWIDEN-NEXT: [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] 58; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul nsw i32 [[I_018_US]], [[M]] 59; DONTWIDEN-NEXT: br label [[FOR_BODY4_US:%.*]] 60; DONTWIDEN: for.body4.us: 61; DONTWIDEN-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ] 62; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add nsw i32 [[J_016_US]], [[MUL_US]] 63; DONTWIDEN-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64 64; DONTWIDEN-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 65; DONTWIDEN-NEXT: tail call void @f(ptr [[ARRAYIDX_US]]) 66; DONTWIDEN-NEXT: [[INC_US]] = add nuw nsw i32 [[J_016_US]], 1 67; DONTWIDEN-NEXT: [[CMP2_US:%.*]] = icmp slt i32 [[INC_US]], [[M]] 68; DONTWIDEN-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] 69; DONTWIDEN: for.cond1.for.cond.cleanup3_crit_edge.us: 70; DONTWIDEN-NEXT: [[INC6_US]] = add nuw nsw i32 [[I_018_US]], 1 71; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[INC6_US]], [[N]] 72; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 73; DONTWIDEN: for.cond.cleanup.loopexit: 74; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 75; DONTWIDEN: for.cond.cleanup: 76; DONTWIDEN-NEXT: ret void 77; 78entry: 79 %cmp17 = icmp sgt i32 %N, 0 80 br i1 %cmp17, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup 81 82for.cond1.preheader.lr.ph: 83 %cmp215 = icmp sgt i32 %M, 0 84 br i1 %cmp215, label %for.cond1.preheader.us.preheader, label %for.cond.cleanup 85 86for.cond1.preheader.us.preheader: 87 br label %for.cond1.preheader.us 88 89for.cond1.preheader.us: 90 %i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ] 91 %mul.us = mul nsw i32 %i.018.us, %M 92 br label %for.body4.us 93 94for.body4.us: 95 %j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ] 96 %add.us = add nsw i32 %j.016.us, %mul.us 97 %idxprom.us = sext i32 %add.us to i64 98 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 99 tail call void @f(ptr %arrayidx.us) #2 100 %inc.us = add nuw nsw i32 %j.016.us, 1 101 %cmp2.us = icmp slt i32 %inc.us, %M 102 br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us 103 104for.cond1.for.cond.cleanup3_crit_edge.us: 105 %inc6.us = add nuw nsw i32 %i.018.us, 1 106 %cmp.us = icmp slt i32 %inc6.us, %N 107 br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup 108 109for.cond.cleanup: 110 ret void 111} 112 113; This test case corresponds to this input: 114; 115; for (int i = 0; i < N; ++i) 116; for (int j = 0; j < M; ++j) 117; f(A[i*M+j]); 118; 119; It is very similar to test case @foo above, but the CFG is slightly 120; different, making the analysis slightly different. 121; 122define void @foo2_sext(ptr nocapture readonly %A, i32 %N, i32 %M) { 123; CHECK-LABEL: @foo2_sext( 124; CHECK-NEXT: entry: 125; CHECK-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0 126; CHECK-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]] 127; CHECK: for.cond1.preheader.lr.ph: 128; CHECK-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0 129; CHECK-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]] 130; CHECK: for.cond1.preheader.preheader: 131; CHECK-NEXT: br label [[FOR_COND1_PREHEADER:%.*]] 132; CHECK: for.cond1.preheader.us.preheader: 133; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[M]] to i64 134; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[N]] to i64 135; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]] 136; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 137; CHECK: for.cond1.preheader.us: 138; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] 139; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]] 140; CHECK: for.body4.us: 141; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVAR2]] 142; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4 143; CHECK-NEXT: tail call void @g(i32 [[TMP2]]) 144; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] 145; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us: 146; CHECK-NEXT: [[INDVAR_NEXT3]] = add nuw nsw i64 [[INDVAR2]], 1 147; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]] 148; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 149; CHECK: for.cond1.preheader: 150; CHECK-NEXT: [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ] 151; CHECK-NEXT: [[INC6]] = add nuw nsw i32 [[I_018]], 1 152; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC6]], [[N]] 153; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]] 154; CHECK: for.cond.cleanup.loopexit: 155; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 156; CHECK: for.cond.cleanup.loopexit19: 157; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 158; CHECK: for.cond.cleanup: 159; CHECK-NEXT: ret void 160; 161; DONTWIDEN-LABEL: @foo2_sext( 162; DONTWIDEN-NEXT: entry: 163; DONTWIDEN-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0 164; DONTWIDEN-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]] 165; DONTWIDEN: for.cond1.preheader.lr.ph: 166; DONTWIDEN-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0 167; DONTWIDEN-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]] 168; DONTWIDEN: for.cond1.preheader.preheader: 169; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER:%.*]] 170; DONTWIDEN: for.cond1.preheader.us.preheader: 171; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 172; DONTWIDEN: for.cond1.preheader.us: 173; DONTWIDEN-NEXT: [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] 174; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul nsw i32 [[I_018_US]], [[M]] 175; DONTWIDEN-NEXT: br label [[FOR_BODY4_US:%.*]] 176; DONTWIDEN: for.body4.us: 177; DONTWIDEN-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ] 178; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add nsw i32 [[J_016_US]], [[MUL_US]] 179; DONTWIDEN-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64 180; DONTWIDEN-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 181; DONTWIDEN-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4 182; DONTWIDEN-NEXT: tail call void @g(i32 [[TMP0]]) 183; DONTWIDEN-NEXT: [[INC_US]] = add nuw nsw i32 [[J_016_US]], 1 184; DONTWIDEN-NEXT: [[CMP2_US:%.*]] = icmp slt i32 [[INC_US]], [[M]] 185; DONTWIDEN-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] 186; DONTWIDEN: for.cond1.for.cond.cleanup3_crit_edge.us: 187; DONTWIDEN-NEXT: [[INC6_US]] = add nuw nsw i32 [[I_018_US]], 1 188; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[INC6_US]], [[N]] 189; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 190; DONTWIDEN: for.cond1.preheader: 191; DONTWIDEN-NEXT: [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ] 192; DONTWIDEN-NEXT: [[INC6]] = add nuw nsw i32 [[I_018]], 1 193; DONTWIDEN-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC6]], [[N]] 194; DONTWIDEN-NEXT: br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]] 195; DONTWIDEN: for.cond.cleanup.loopexit: 196; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 197; DONTWIDEN: for.cond.cleanup.loopexit19: 198; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 199; DONTWIDEN: for.cond.cleanup: 200; DONTWIDEN-NEXT: ret void 201; 202entry: 203 %cmp17 = icmp sgt i32 %N, 0 204 br i1 %cmp17, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup 205 206for.cond1.preheader.lr.ph: 207 %cmp215 = icmp sgt i32 %M, 0 208 br i1 %cmp215, label %for.cond1.preheader.us.preheader, label %for.cond1.preheader.preheader 209 210for.cond1.preheader.preheader: 211 br label %for.cond1.preheader 212 213for.cond1.preheader.us.preheader: 214 br label %for.cond1.preheader.us 215 216for.cond1.preheader.us: 217 %i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ] 218 %mul.us = mul nsw i32 %i.018.us, %M 219 br label %for.body4.us 220 221for.body4.us: 222 %j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ] 223 %add.us = add nsw i32 %j.016.us, %mul.us 224 %idxprom.us = sext i32 %add.us to i64 225 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 226 %0 = load i32, ptr %arrayidx.us, align 4 227 tail call void @g(i32 %0) 228 %inc.us = add nuw nsw i32 %j.016.us, 1 229 %cmp2.us = icmp slt i32 %inc.us, %M 230 br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us 231 232for.cond1.for.cond.cleanup3_crit_edge.us: 233 %inc6.us = add nuw nsw i32 %i.018.us, 1 234 %cmp.us = icmp slt i32 %inc6.us, %N 235 br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup.loopexit 236 237for.cond1.preheader: 238 %i.018 = phi i32 [ %inc6, %for.cond1.preheader ], [ 0, %for.cond1.preheader.preheader ] 239 %inc6 = add nuw nsw i32 %i.018, 1 240 %cmp = icmp slt i32 %inc6, %N 241 br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup.loopexit19 242 243for.cond.cleanup.loopexit: 244 br label %for.cond.cleanup 245 246for.cond.cleanup.loopexit19: 247 br label %for.cond.cleanup 248 249for.cond.cleanup: 250 ret void 251} 252 253; This test case corresponds to this input: 254; 255; void foo2_zext(unsigned *A, ..) { 256; for (unsigned i = 0; i < N; ++i) 257; for (unsigned j = 0; j < M; ++j) 258; f(A[i*M+j]); 259; 260define void @foo2_zext(ptr nocapture readonly %A, i32 %N, i32 %M) { 261; CHECK-LABEL: @foo2_zext( 262; CHECK-NEXT: entry: 263; CHECK-NEXT: [[CMP17_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0 264; CHECK-NEXT: br i1 [[CMP17_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]] 265; CHECK: for.cond1.preheader.lr.ph: 266; CHECK-NEXT: [[CMP215_NOT:%.*]] = icmp eq i32 [[M:%.*]], 0 267; CHECK-NEXT: br i1 [[CMP215_NOT]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]] 268; CHECK: for.cond1.preheader.us.preheader: 269; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[M]] to i64 270; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[N]] to i64 271; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]] 272; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 273; CHECK: for.cond1.preheader.preheader: 274; CHECK-NEXT: br label [[FOR_COND1_PREHEADER:%.*]] 275; CHECK: for.cond1.preheader.us: 276; CHECK-NEXT: [[INDVAR1:%.*]] = phi i64 [ [[INDVAR_NEXT2:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] 277; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR1]] to i32 278; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]] 279; CHECK: for.body4.us: 280; CHECK-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[FLATTEN_TRUNCIV]] to i64 281; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 282; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4 283; CHECK-NEXT: tail call void @g(i32 [[TMP2]]) 284; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] 285; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us: 286; CHECK-NEXT: [[INDVAR_NEXT2]] = add i64 [[INDVAR1]], 1 287; CHECK-NEXT: [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT2]], [[FLATTEN_TRIPCOUNT]] 288; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]] 289; CHECK: for.cond1.preheader: 290; CHECK-NEXT: [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ] 291; CHECK-NEXT: [[INC6]] = add i32 [[I_018]], 1 292; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[INC6]], [[N]] 293; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 294; CHECK: for.cond.cleanup.loopexit: 295; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 296; CHECK: for.cond.cleanup.loopexit19: 297; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 298; CHECK: for.cond.cleanup: 299; CHECK-NEXT: ret void 300; 301; DONTWIDEN-LABEL: @foo2_zext( 302; DONTWIDEN-NEXT: entry: 303; DONTWIDEN-NEXT: [[CMP17_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0 304; DONTWIDEN-NEXT: br i1 [[CMP17_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]] 305; DONTWIDEN: for.cond1.preheader.lr.ph: 306; DONTWIDEN-NEXT: [[CMP215_NOT:%.*]] = icmp eq i32 [[M:%.*]], 0 307; DONTWIDEN-NEXT: br i1 [[CMP215_NOT]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]] 308; DONTWIDEN: for.cond1.preheader.us.preheader: 309; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 310; DONTWIDEN: for.cond1.preheader.preheader: 311; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER:%.*]] 312; DONTWIDEN: for.cond1.preheader.us: 313; DONTWIDEN-NEXT: [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] 314; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul i32 [[I_018_US]], [[M]] 315; DONTWIDEN-NEXT: br label [[FOR_BODY4_US:%.*]] 316; DONTWIDEN: for.body4.us: 317; DONTWIDEN-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ] 318; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add i32 [[J_016_US]], [[MUL_US]] 319; DONTWIDEN-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64 320; DONTWIDEN-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 321; DONTWIDEN-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4 322; DONTWIDEN-NEXT: tail call void @g(i32 [[TMP0]]) 323; DONTWIDEN-NEXT: [[INC_US]] = add nuw i32 [[J_016_US]], 1 324; DONTWIDEN-NEXT: [[CMP2_US:%.*]] = icmp ult i32 [[INC_US]], [[M]] 325; DONTWIDEN-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] 326; DONTWIDEN: for.cond1.for.cond.cleanup3_crit_edge.us: 327; DONTWIDEN-NEXT: [[INC6_US]] = add i32 [[I_018_US]], 1 328; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp ult i32 [[INC6_US]], [[N]] 329; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]] 330; DONTWIDEN: for.cond1.preheader: 331; DONTWIDEN-NEXT: [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ] 332; DONTWIDEN-NEXT: [[INC6]] = add i32 [[I_018]], 1 333; DONTWIDEN-NEXT: [[CMP:%.*]] = icmp ult i32 [[INC6]], [[N]] 334; DONTWIDEN-NEXT: br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 335; DONTWIDEN: for.cond.cleanup.loopexit: 336; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 337; DONTWIDEN: for.cond.cleanup.loopexit19: 338; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 339; DONTWIDEN: for.cond.cleanup: 340; DONTWIDEN-NEXT: ret void 341; 342entry: 343 %cmp17.not = icmp eq i32 %N, 0 344 br i1 %cmp17.not, label %for.cond.cleanup, label %for.cond1.preheader.lr.ph 345 346for.cond1.preheader.lr.ph: 347 %cmp215.not = icmp eq i32 %M, 0 348 br i1 %cmp215.not, label %for.cond1.preheader.preheader, label %for.cond1.preheader.us.preheader 349 350for.cond1.preheader.us.preheader: 351 br label %for.cond1.preheader.us 352 353for.cond1.preheader.preheader: 354 br label %for.cond1.preheader 355 356for.cond1.preheader.us: 357 %i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ] 358 %mul.us = mul i32 %i.018.us, %M 359 br label %for.body4.us 360 361for.body4.us: 362 %j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ] 363 %add.us = add i32 %j.016.us, %mul.us 364 %idxprom.us = zext i32 %add.us to i64 365 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 366 %0 = load i32, ptr %arrayidx.us, align 4 367 tail call void @g(i32 %0) 368 %inc.us = add nuw i32 %j.016.us, 1 369 %cmp2.us = icmp ult i32 %inc.us, %M 370 br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us 371 372for.cond1.for.cond.cleanup3_crit_edge.us: 373 %inc6.us = add i32 %i.018.us, 1 374 %cmp.us = icmp ult i32 %inc6.us, %N 375 br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup.loopexit19 376 377for.cond1.preheader: 378 %i.018 = phi i32 [ %inc6, %for.cond1.preheader ], [ 0, %for.cond1.preheader.preheader ] 379 %inc6 = add i32 %i.018, 1 380 %cmp = icmp ult i32 %inc6, %N 381 br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup.loopexit 382 383for.cond.cleanup.loopexit: 384 br label %for.cond.cleanup 385 386for.cond.cleanup.loopexit19: 387 br label %for.cond.cleanup 388 389for.cond.cleanup: 390 ret void 391} 392 393define void @zext(i32 %N, ptr nocapture %A, i16 %val) { 394; CHECK-LABEL: @zext( 395; CHECK-NEXT: entry: 396; CHECK-NEXT: [[CMP20_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0 397; CHECK-NEXT: br i1 [[CMP20_NOT]], label [[FOR_END9:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]] 398; CHECK: for.cond1.preheader.us.preheader: 399; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[N]] to i64 400; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[N]] to i64 401; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]] 402; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 403; CHECK: for.cond1.preheader.us: 404; CHECK-NEXT: [[INDVAR1:%.*]] = phi i64 [ [[INDVAR_NEXT2:%.*]], [[FOR_COND1_FOR_INC7_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] 405; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR1]] to i32 406; CHECK-NEXT: br label [[FOR_BODY3_US:%.*]] 407; CHECK: for.body3.us: 408; CHECK-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[FLATTEN_TRUNCIV]] to i64 409; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i16, ptr [[A:%.*]], i64 [[IDXPROM_US]] 410; CHECK-NEXT: [[TMP2:%.*]] = load i16, ptr [[ARRAYIDX_US]], align 2 411; CHECK-NEXT: [[ADD5_US:%.*]] = add i16 [[TMP2]], [[VAL:%.*]] 412; CHECK-NEXT: store i16 [[ADD5_US]], ptr [[ARRAYIDX_US]], align 2 413; CHECK-NEXT: br label [[FOR_COND1_FOR_INC7_CRIT_EDGE_US]] 414; CHECK: for.cond1.for.inc7_crit_edge.us: 415; CHECK-NEXT: [[INDVAR_NEXT2]] = add i64 [[INDVAR1]], 1 416; CHECK-NEXT: [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT2]], [[FLATTEN_TRIPCOUNT]] 417; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END9_LOOPEXIT:%.*]] 418; CHECK: for.end9.loopexit: 419; CHECK-NEXT: br label [[FOR_END9]] 420; CHECK: for.end9: 421; CHECK-NEXT: ret void 422; 423; DONTWIDEN-LABEL: @zext( 424; DONTWIDEN-NEXT: entry: 425; DONTWIDEN-NEXT: [[CMP20_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0 426; DONTWIDEN-NEXT: br i1 [[CMP20_NOT]], label [[FOR_END9:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]] 427; DONTWIDEN: for.cond1.preheader.us.preheader: 428; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 429; DONTWIDEN: for.cond1.preheader.us: 430; DONTWIDEN-NEXT: [[I_021_US:%.*]] = phi i32 [ [[INC8_US:%.*]], [[FOR_COND1_FOR_INC7_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] 431; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]] 432; DONTWIDEN-NEXT: br label [[FOR_BODY3_US:%.*]] 433; DONTWIDEN: for.body3.us: 434; DONTWIDEN-NEXT: [[J_019_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY3_US]] ] 435; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]] 436; DONTWIDEN-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64 437; DONTWIDEN-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i16, ptr [[A:%.*]], i64 [[IDXPROM_US]] 438; DONTWIDEN-NEXT: [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX_US]], align 2 439; DONTWIDEN-NEXT: [[ADD5_US:%.*]] = add i16 [[TMP0]], [[VAL:%.*]] 440; DONTWIDEN-NEXT: store i16 [[ADD5_US]], ptr [[ARRAYIDX_US]], align 2 441; DONTWIDEN-NEXT: [[INC_US]] = add nuw i32 [[J_019_US]], 1 442; DONTWIDEN-NEXT: [[CMP2_US:%.*]] = icmp ult i32 [[INC_US]], [[N]] 443; DONTWIDEN-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY3_US]], label [[FOR_COND1_FOR_INC7_CRIT_EDGE_US]] 444; DONTWIDEN: for.cond1.for.inc7_crit_edge.us: 445; DONTWIDEN-NEXT: [[INC8_US]] = add i32 [[I_021_US]], 1 446; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp ult i32 [[INC8_US]], [[N]] 447; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END9_LOOPEXIT:%.*]] 448; DONTWIDEN: for.end9.loopexit: 449; DONTWIDEN-NEXT: br label [[FOR_END9]] 450; DONTWIDEN: for.end9: 451; DONTWIDEN-NEXT: ret void 452; 453entry: 454 %cmp20.not = icmp eq i32 %N, 0 455 br i1 %cmp20.not, label %for.end9, label %for.cond1.preheader.us.preheader 456 457for.cond1.preheader.us.preheader: 458 br label %for.cond1.preheader.us 459 460for.cond1.preheader.us: 461 %i.021.us = phi i32 [ %inc8.us, %for.cond1.for.inc7_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ] 462 %mul.us = mul i32 %i.021.us, %N 463 br label %for.body3.us 464 465for.body3.us: 466 %j.019.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body3.us ] 467 %add.us = add i32 %j.019.us, %mul.us 468 %idxprom.us = zext i32 %add.us to i64 469 %arrayidx.us = getelementptr inbounds i16, ptr %A, i64 %idxprom.us 470 %0 = load i16, ptr %arrayidx.us, align 2 471 %add5.us = add i16 %0, %val 472 store i16 %add5.us, ptr %arrayidx.us, align 2 473 %inc.us = add nuw i32 %j.019.us, 1 474 %cmp2.us = icmp ult i32 %inc.us, %N 475 br i1 %cmp2.us, label %for.body3.us, label %for.cond1.for.inc7_crit_edge.us 476 477for.cond1.for.inc7_crit_edge.us: 478 %inc8.us = add i32 %i.021.us, 1 479 %cmp.us = icmp ult i32 %inc8.us, %N 480 br i1 %cmp.us, label %for.cond1.preheader.us, label %for.end9.loopexit 481 482for.end9.loopexit: 483 br label %for.end9 484 485for.end9: 486 ret void 487} 488 489; This IR corresponds to this input: 490; 491; void test(char n, char m) { 492; for(char i = 0; i < n; i++) 493; for(char j = 0; j < m; j++) { 494; char x = i*m+j; 495; use_32(x); 496; } 497; } 498; 499define void @test(i8 %n, i8 %m) { 500; CHECK-LABEL: @test( 501; CHECK-NEXT: entry: 502; CHECK-NEXT: [[CMP25_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0 503; CHECK-NEXT: br i1 [[CMP25_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]] 504; CHECK: for.cond3.preheader.lr.ph: 505; CHECK-NEXT: [[CMP623_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0 506; CHECK-NEXT: br i1 [[CMP623_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]] 507; CHECK: for.cond3.preheader.preheader: 508; CHECK-NEXT: br label [[FOR_COND3_PREHEADER:%.*]] 509; CHECK: for.cond3.preheader.us.preheader: 510; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[M]] to i64 511; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[N]] to i64 512; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]] 513; CHECK-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]] 514; CHECK: for.cond3.preheader.us: 515; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ] 516; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i8 517; CHECK-NEXT: br label [[FOR_BODY9_US:%.*]] 518; CHECK: for.body9.us: 519; CHECK-NEXT: [[CONV14_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i32 520; CHECK-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]]) 521; CHECK-NEXT: br label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]] 522; CHECK: for.cond3.for.cond.cleanup8_crit_edge.us: 523; CHECK-NEXT: [[INDVAR_NEXT3]] = add i64 [[INDVAR2]], 1 524; CHECK-NEXT: [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]] 525; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]] 526; CHECK: for.cond3.preheader: 527; CHECK-NEXT: [[I_026:%.*]] = phi i8 [ [[INC16:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ] 528; CHECK-NEXT: [[INC16]] = add i8 [[I_026]], 1 529; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[INC16]], [[N]] 530; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 531; CHECK: for.cond.cleanup.loopexit: 532; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 533; CHECK: for.cond.cleanup.loopexit1: 534; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 535; CHECK: for.cond.cleanup: 536; CHECK-NEXT: ret void 537; 538; DONTWIDEN-LABEL: @test( 539; DONTWIDEN-NEXT: entry: 540; DONTWIDEN-NEXT: [[CMP25_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0 541; DONTWIDEN-NEXT: br i1 [[CMP25_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]] 542; DONTWIDEN: for.cond3.preheader.lr.ph: 543; DONTWIDEN-NEXT: [[CMP623_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0 544; DONTWIDEN-NEXT: br i1 [[CMP623_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]] 545; DONTWIDEN: for.cond3.preheader.preheader: 546; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER:%.*]] 547; DONTWIDEN: for.cond3.preheader.us.preheader: 548; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]] 549; DONTWIDEN: for.cond3.preheader.us: 550; DONTWIDEN-NEXT: [[I_026_US:%.*]] = phi i8 [ [[INC16_US:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ] 551; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul i8 [[I_026_US]], [[M]] 552; DONTWIDEN-NEXT: br label [[FOR_BODY9_US:%.*]] 553; DONTWIDEN: for.body9.us: 554; DONTWIDEN-NEXT: [[J_024_US:%.*]] = phi i8 [ 0, [[FOR_COND3_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY9_US]] ] 555; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add i8 [[J_024_US]], [[MUL_US]] 556; DONTWIDEN-NEXT: [[CONV14_US:%.*]] = zext i8 [[ADD_US]] to i32 557; DONTWIDEN-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]]) 558; DONTWIDEN-NEXT: [[INC_US]] = add nuw i8 [[J_024_US]], 1 559; DONTWIDEN-NEXT: [[CMP6_US:%.*]] = icmp ult i8 [[INC_US]], [[M]] 560; DONTWIDEN-NEXT: br i1 [[CMP6_US]], label [[FOR_BODY9_US]], label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]] 561; DONTWIDEN: for.cond3.for.cond.cleanup8_crit_edge.us: 562; DONTWIDEN-NEXT: [[INC16_US]] = add i8 [[I_026_US]], 1 563; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp ult i8 [[INC16_US]], [[N]] 564; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]] 565; DONTWIDEN: for.cond3.preheader: 566; DONTWIDEN-NEXT: [[I_026:%.*]] = phi i8 [ [[INC16:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ] 567; DONTWIDEN-NEXT: [[INC16]] = add i8 [[I_026]], 1 568; DONTWIDEN-NEXT: [[CMP:%.*]] = icmp ult i8 [[INC16]], [[N]] 569; DONTWIDEN-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 570; DONTWIDEN: for.cond.cleanup.loopexit: 571; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 572; DONTWIDEN: for.cond.cleanup.loopexit1: 573; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 574; DONTWIDEN: for.cond.cleanup: 575; DONTWIDEN-NEXT: ret void 576; 577entry: 578 %cmp25.not = icmp eq i8 %n, 0 579 br i1 %cmp25.not, label %for.cond.cleanup, label %for.cond3.preheader.lr.ph 580 581for.cond3.preheader.lr.ph: 582 %cmp623.not = icmp eq i8 %m, 0 583 br i1 %cmp623.not, label %for.cond3.preheader.preheader, label %for.cond3.preheader.us.preheader 584 585for.cond3.preheader.preheader: 586 br label %for.cond3.preheader 587 588for.cond3.preheader.us.preheader: 589 br label %for.cond3.preheader.us 590 591for.cond3.preheader.us: 592 %i.026.us = phi i8 [ %inc16.us, %for.cond3.for.cond.cleanup8_crit_edge.us ], [ 0, %for.cond3.preheader.us.preheader ] 593 %mul.us = mul i8 %i.026.us, %m 594 br label %for.body9.us 595 596for.body9.us: 597 %j.024.us = phi i8 [ 0, %for.cond3.preheader.us ], [ %inc.us, %for.body9.us ] 598 %add.us = add i8 %j.024.us, %mul.us 599 %conv14.us = zext i8 %add.us to i32 600 %call.us = tail call i32 @use_32(i32 %conv14.us) #2 601 %inc.us = add nuw i8 %j.024.us, 1 602 %cmp6.us = icmp ult i8 %inc.us, %m 603 br i1 %cmp6.us, label %for.body9.us, label %for.cond3.for.cond.cleanup8_crit_edge.us 604 605for.cond3.for.cond.cleanup8_crit_edge.us: 606 %inc16.us = add i8 %i.026.us, 1 607 %cmp.us = icmp ult i8 %inc16.us, %n 608 br i1 %cmp.us, label %for.cond3.preheader.us, label %for.cond.cleanup 609 610for.cond3.preheader: 611 %i.026 = phi i8 [ %inc16, %for.cond3.preheader ], [ 0, %for.cond3.preheader.preheader ] 612 %inc16 = add i8 %i.026, 1 613 %cmp = icmp ult i8 %inc16, %n 614 br i1 %cmp, label %for.cond3.preheader, label %for.cond.cleanup 615 616for.cond.cleanup: 617 ret void 618} 619 620; This IR corresponds to this input: 621; 622; void test3(char n, char m) { 623; for(char i = 0; i < n; i++) 624; for(char j = 0; j < m; j++) { 625; char x = i*m+j; 626; use_32(x); 627; use_16(x); 628; use_32(x); 629; use_16(x); 630; use_64(x); 631; } 632; } 633; 634define void @test3(i8 %n, i8 %m) { 635; CHECK-LABEL: @test3( 636; CHECK-NEXT: entry: 637; CHECK-NEXT: [[CMP37_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0 638; CHECK-NEXT: br i1 [[CMP37_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]] 639; CHECK: for.cond3.preheader.lr.ph: 640; CHECK-NEXT: [[CMP635_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0 641; CHECK-NEXT: br i1 [[CMP635_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]] 642; CHECK: for.cond3.preheader.preheader: 643; CHECK-NEXT: br label [[FOR_COND3_PREHEADER:%.*]] 644; CHECK: for.cond3.preheader.us.preheader: 645; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[M]] to i64 646; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[N]] to i64 647; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]] 648; CHECK-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]] 649; CHECK: for.cond3.preheader.us: 650; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ] 651; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i8 652; CHECK-NEXT: br label [[FOR_BODY9_US:%.*]] 653; CHECK: for.body9.us: 654; CHECK-NEXT: [[CONV14_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i32 655; CHECK-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]]) 656; CHECK-NEXT: [[CONV15_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i16 657; CHECK-NEXT: [[CALL16_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]]) 658; CHECK-NEXT: [[CALL18_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]]) 659; CHECK-NEXT: [[CALL20_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]]) 660; CHECK-NEXT: [[CONV21_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i64 661; CHECK-NEXT: [[CALL22_US:%.*]] = tail call i32 @use_64(i64 [[CONV21_US]]) 662; CHECK-NEXT: br label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]] 663; CHECK: for.cond3.for.cond.cleanup8_crit_edge.us: 664; CHECK-NEXT: [[INDVAR_NEXT3]] = add i64 [[INDVAR2]], 1 665; CHECK-NEXT: [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]] 666; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]] 667; CHECK: for.cond3.preheader: 668; CHECK-NEXT: [[I_038:%.*]] = phi i8 [ [[INC24:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ] 669; CHECK-NEXT: [[INC24]] = add i8 [[I_038]], 1 670; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[INC24]], [[N]] 671; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 672; CHECK: for.cond.cleanup.loopexit: 673; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 674; CHECK: for.cond.cleanup.loopexit1: 675; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 676; CHECK: for.cond.cleanup: 677; CHECK-NEXT: ret void 678; 679; DONTWIDEN-LABEL: @test3( 680; DONTWIDEN-NEXT: entry: 681; DONTWIDEN-NEXT: [[CMP37_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0 682; DONTWIDEN-NEXT: br i1 [[CMP37_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]] 683; DONTWIDEN: for.cond3.preheader.lr.ph: 684; DONTWIDEN-NEXT: [[CMP635_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0 685; DONTWIDEN-NEXT: br i1 [[CMP635_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]] 686; DONTWIDEN: for.cond3.preheader.preheader: 687; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER:%.*]] 688; DONTWIDEN: for.cond3.preheader.us.preheader: 689; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]] 690; DONTWIDEN: for.cond3.preheader.us: 691; DONTWIDEN-NEXT: [[I_038_US:%.*]] = phi i8 [ [[INC24_US:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ] 692; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul i8 [[I_038_US]], [[M]] 693; DONTWIDEN-NEXT: br label [[FOR_BODY9_US:%.*]] 694; DONTWIDEN: for.body9.us: 695; DONTWIDEN-NEXT: [[J_036_US:%.*]] = phi i8 [ 0, [[FOR_COND3_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY9_US]] ] 696; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add i8 [[J_036_US]], [[MUL_US]] 697; DONTWIDEN-NEXT: [[CONV14_US:%.*]] = zext i8 [[ADD_US]] to i32 698; DONTWIDEN-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]]) 699; DONTWIDEN-NEXT: [[CONV15_US:%.*]] = zext i8 [[ADD_US]] to i16 700; DONTWIDEN-NEXT: [[CALL16_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]]) 701; DONTWIDEN-NEXT: [[CALL18_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]]) 702; DONTWIDEN-NEXT: [[CALL20_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]]) 703; DONTWIDEN-NEXT: [[CONV21_US:%.*]] = zext i8 [[ADD_US]] to i64 704; DONTWIDEN-NEXT: [[CALL22_US:%.*]] = tail call i32 @use_64(i64 [[CONV21_US]]) 705; DONTWIDEN-NEXT: [[INC_US]] = add nuw i8 [[J_036_US]], 1 706; DONTWIDEN-NEXT: [[CMP6_US:%.*]] = icmp ult i8 [[INC_US]], [[M]] 707; DONTWIDEN-NEXT: br i1 [[CMP6_US]], label [[FOR_BODY9_US]], label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]] 708; DONTWIDEN: for.cond3.for.cond.cleanup8_crit_edge.us: 709; DONTWIDEN-NEXT: [[INC24_US]] = add i8 [[I_038_US]], 1 710; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp ult i8 [[INC24_US]], [[N]] 711; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]] 712; DONTWIDEN: for.cond3.preheader: 713; DONTWIDEN-NEXT: [[I_038:%.*]] = phi i8 [ [[INC24:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ] 714; DONTWIDEN-NEXT: [[INC24]] = add i8 [[I_038]], 1 715; DONTWIDEN-NEXT: [[CMP:%.*]] = icmp ult i8 [[INC24]], [[N]] 716; DONTWIDEN-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 717; DONTWIDEN: for.cond.cleanup.loopexit: 718; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 719; DONTWIDEN: for.cond.cleanup.loopexit1: 720; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 721; DONTWIDEN: for.cond.cleanup: 722; DONTWIDEN-NEXT: ret void 723; 724entry: 725 %cmp37.not = icmp eq i8 %n, 0 726 br i1 %cmp37.not, label %for.cond.cleanup, label %for.cond3.preheader.lr.ph 727 728for.cond3.preheader.lr.ph: 729 %cmp635.not = icmp eq i8 %m, 0 730 br i1 %cmp635.not, label %for.cond3.preheader.preheader, label %for.cond3.preheader.us.preheader 731 732for.cond3.preheader.preheader: 733 br label %for.cond3.preheader 734 735for.cond3.preheader.us.preheader: 736 br label %for.cond3.preheader.us 737 738for.cond3.preheader.us: 739 %i.038.us = phi i8 [ %inc24.us, %for.cond3.for.cond.cleanup8_crit_edge.us ], [ 0, %for.cond3.preheader.us.preheader ] 740 %mul.us = mul i8 %i.038.us, %m 741 br label %for.body9.us 742 743for.body9.us: 744 %j.036.us = phi i8 [ 0, %for.cond3.preheader.us ], [ %inc.us, %for.body9.us ] 745 %add.us = add i8 %j.036.us, %mul.us 746 %conv14.us = zext i8 %add.us to i32 747 %call.us = tail call i32 @use_32(i32 %conv14.us) 748 %conv15.us = zext i8 %add.us to i16 749 %call16.us = tail call i32 @use_16(i16 %conv15.us) 750 %call18.us = tail call i32 @use_32(i32 %conv14.us) 751 %call20.us = tail call i32 @use_16(i16 %conv15.us) 752 %conv21.us = zext i8 %add.us to i64 753 %call22.us = tail call i32 @use_64(i64 %conv21.us) 754 %inc.us = add nuw i8 %j.036.us, 1 755 %cmp6.us = icmp ult i8 %inc.us, %m 756 br i1 %cmp6.us, label %for.body9.us, label %for.cond3.for.cond.cleanup8_crit_edge.us 757 758for.cond3.for.cond.cleanup8_crit_edge.us: 759 %inc24.us = add i8 %i.038.us, 1 760 %cmp.us = icmp ult i8 %inc24.us, %n 761 br i1 %cmp.us, label %for.cond3.preheader.us, label %for.cond.cleanup 762 763for.cond3.preheader: 764 %i.038 = phi i8 [ %inc24, %for.cond3.preheader ], [ 0, %for.cond3.preheader.preheader ] 765 %inc24 = add i8 %i.038, 1 766 %cmp = icmp ult i8 %inc24, %n 767 br i1 %cmp, label %for.cond3.preheader, label %for.cond.cleanup 768 769for.cond.cleanup: 770 ret void 771} 772 773; This IR corresponds to this input: 774; 775; void test4(short n, short m) { 776; for(short i = 0; i < n; i++) 777; for(short j = 0; j < m; j++) { 778; short x = i*m+j; 779; use_32(x); 780; use_16(x); 781; use_32(x); 782; use_16(x); 783; use_64(x); 784; } 785; } 786; 787define void @test4(i16 %n, i16 %m) { 788; CHECK-LABEL: @test4( 789; CHECK-NEXT: entry: 790; CHECK-NEXT: [[CMP38:%.*]] = icmp sgt i16 [[N:%.*]], 0 791; CHECK-NEXT: br i1 [[CMP38]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]] 792; CHECK: for.cond3.preheader.lr.ph: 793; CHECK-NEXT: [[CMP636:%.*]] = icmp sgt i16 [[M:%.*]], 0 794; CHECK-NEXT: br i1 [[CMP636]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]] 795; CHECK: for.cond3.preheader.preheader: 796; CHECK-NEXT: br label [[FOR_COND3_PREHEADER:%.*]] 797; CHECK: for.cond3.preheader.us.preheader: 798; CHECK-NEXT: [[TMP0:%.*]] = sext i16 [[M]] to i64 799; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[N]] to i64 800; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]] 801; CHECK-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]] 802; CHECK: for.cond3.preheader.us: 803; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ] 804; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i16 805; CHECK-NEXT: br label [[FOR_BODY9_US:%.*]] 806; CHECK: for.body9.us: 807; CHECK-NEXT: [[CONV14_US:%.*]] = sext i16 [[FLATTEN_TRUNCIV]] to i32 808; CHECK-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]]) 809; CHECK-NEXT: [[CALL15_US:%.*]] = tail call i32 @use_16(i16 [[FLATTEN_TRUNCIV]]) 810; CHECK-NEXT: [[CALL17_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]]) 811; CHECK-NEXT: [[CALL18_US:%.*]] = tail call i32 @use_16(i16 [[FLATTEN_TRUNCIV]]) 812; CHECK-NEXT: [[CONV19_US:%.*]] = sext i16 [[FLATTEN_TRUNCIV]] to i64 813; CHECK-NEXT: [[CALL20_US:%.*]] = tail call i32 @use_64(i64 [[CONV19_US]]) 814; CHECK-NEXT: br label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]] 815; CHECK: for.cond3.for.cond.cleanup8_crit_edge.us: 816; CHECK-NEXT: [[INDVAR_NEXT3]] = add i64 [[INDVAR2]], 1 817; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]] 818; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 819; CHECK: for.cond3.preheader: 820; CHECK-NEXT: [[I_039:%.*]] = phi i16 [ [[INC22:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ] 821; CHECK-NEXT: [[INC22]] = add i16 [[I_039]], 1 822; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[INC22]], [[N]] 823; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]] 824; CHECK: for.cond.cleanup.loopexit: 825; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 826; CHECK: for.cond.cleanup.loopexit1: 827; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 828; CHECK: for.cond.cleanup: 829; CHECK-NEXT: ret void 830; 831; DONTWIDEN-LABEL: @test4( 832; DONTWIDEN-NEXT: entry: 833; DONTWIDEN-NEXT: [[CMP38:%.*]] = icmp sgt i16 [[N:%.*]], 0 834; DONTWIDEN-NEXT: br i1 [[CMP38]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]] 835; DONTWIDEN: for.cond3.preheader.lr.ph: 836; DONTWIDEN-NEXT: [[CMP636:%.*]] = icmp sgt i16 [[M:%.*]], 0 837; DONTWIDEN-NEXT: br i1 [[CMP636]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]] 838; DONTWIDEN: for.cond3.preheader.preheader: 839; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER:%.*]] 840; DONTWIDEN: for.cond3.preheader.us.preheader: 841; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]] 842; DONTWIDEN: for.cond3.preheader.us: 843; DONTWIDEN-NEXT: [[I_039_US:%.*]] = phi i16 [ [[INC22_US:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ] 844; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul i16 [[I_039_US]], [[M]] 845; DONTWIDEN-NEXT: br label [[FOR_BODY9_US:%.*]] 846; DONTWIDEN: for.body9.us: 847; DONTWIDEN-NEXT: [[J_037_US:%.*]] = phi i16 [ 0, [[FOR_COND3_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY9_US]] ] 848; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add i16 [[J_037_US]], [[MUL_US]] 849; DONTWIDEN-NEXT: [[CONV14_US:%.*]] = sext i16 [[ADD_US]] to i32 850; DONTWIDEN-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]]) 851; DONTWIDEN-NEXT: [[CALL15_US:%.*]] = tail call i32 @use_16(i16 [[ADD_US]]) 852; DONTWIDEN-NEXT: [[CALL17_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]]) 853; DONTWIDEN-NEXT: [[CALL18_US:%.*]] = tail call i32 @use_16(i16 [[ADD_US]]) 854; DONTWIDEN-NEXT: [[CONV19_US:%.*]] = sext i16 [[ADD_US]] to i64 855; DONTWIDEN-NEXT: [[CALL20_US:%.*]] = tail call i32 @use_64(i64 [[CONV19_US]]) 856; DONTWIDEN-NEXT: [[INC_US]] = add nuw nsw i16 [[J_037_US]], 1 857; DONTWIDEN-NEXT: [[CMP6_US:%.*]] = icmp slt i16 [[INC_US]], [[M]] 858; DONTWIDEN-NEXT: br i1 [[CMP6_US]], label [[FOR_BODY9_US]], label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]] 859; DONTWIDEN: for.cond3.for.cond.cleanup8_crit_edge.us: 860; DONTWIDEN-NEXT: [[INC22_US]] = add i16 [[I_039_US]], 1 861; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp slt i16 [[INC22_US]], [[N]] 862; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 863; DONTWIDEN: for.cond3.preheader: 864; DONTWIDEN-NEXT: [[I_039:%.*]] = phi i16 [ [[INC22:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ] 865; DONTWIDEN-NEXT: [[INC22]] = add i16 [[I_039]], 1 866; DONTWIDEN-NEXT: [[CMP:%.*]] = icmp slt i16 [[INC22]], [[N]] 867; DONTWIDEN-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]] 868; DONTWIDEN: for.cond.cleanup.loopexit: 869; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 870; DONTWIDEN: for.cond.cleanup.loopexit1: 871; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 872; DONTWIDEN: for.cond.cleanup: 873; DONTWIDEN-NEXT: ret void 874; 875entry: 876 %cmp38 = icmp sgt i16 %n, 0 877 br i1 %cmp38, label %for.cond3.preheader.lr.ph, label %for.cond.cleanup 878 879for.cond3.preheader.lr.ph: 880 %cmp636 = icmp sgt i16 %m, 0 881 br i1 %cmp636, label %for.cond3.preheader.us.preheader, label %for.cond3.preheader.preheader 882 883for.cond3.preheader.preheader: 884 br label %for.cond3.preheader 885 886for.cond3.preheader.us.preheader: 887 br label %for.cond3.preheader.us 888 889for.cond3.preheader.us: 890 %i.039.us = phi i16 [ %inc22.us, %for.cond3.for.cond.cleanup8_crit_edge.us ], [ 0, %for.cond3.preheader.us.preheader ] 891 %mul.us = mul i16 %i.039.us, %m 892 br label %for.body9.us 893 894for.body9.us: 895 %j.037.us = phi i16 [ 0, %for.cond3.preheader.us ], [ %inc.us, %for.body9.us ] 896 %add.us = add i16 %j.037.us, %mul.us 897 %conv14.us = sext i16 %add.us to i32 898 %call.us = tail call i32 @use_32(i32 %conv14.us) #2 899 %call15.us = tail call i32 @use_16(i16 %add.us) #2 900 %call17.us = tail call i32 @use_32(i32 %conv14.us) #2 901 %call18.us = tail call i32 @use_16(i16 %add.us) #2 902 %conv19.us = sext i16 %add.us to i64 903 %call20.us = tail call i32 @use_64(i64 %conv19.us) #2 904 %inc.us = add nuw nsw i16 %j.037.us, 1 905 %cmp6.us = icmp slt i16 %inc.us, %m 906 br i1 %cmp6.us, label %for.body9.us, label %for.cond3.for.cond.cleanup8_crit_edge.us 907 908for.cond3.for.cond.cleanup8_crit_edge.us: 909 %inc22.us = add i16 %i.039.us, 1 910 %cmp.us = icmp slt i16 %inc22.us, %n 911 br i1 %cmp.us, label %for.cond3.preheader.us, label %for.cond.cleanup 912 913for.cond3.preheader: 914 %i.039 = phi i16 [ %inc22, %for.cond3.preheader ], [ 0, %for.cond3.preheader.preheader ] 915 %inc22 = add i16 %i.039, 1 916 %cmp = icmp slt i16 %inc22, %n 917 br i1 %cmp, label %for.cond3.preheader, label %for.cond.cleanup 918 919for.cond.cleanup: 920 ret void 921} 922 923; Identify trip count when it is constant and the IV has been widened. 924define i32 @constTripCount() { 925; CHECK-LABEL: @constTripCount( 926; CHECK-NEXT: entry: 927; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 20, 20 928; CHECK-NEXT: br label [[I_LOOP:%.*]] 929; CHECK: i.loop: 930; CHECK-NEXT: [[INDVAR1:%.*]] = phi i64 [ [[INDVAR_NEXT2:%.*]], [[J_LOOPDONE:%.*]] ], [ 0, [[ENTRY:%.*]] ] 931; CHECK-NEXT: br label [[J_LOOP:%.*]] 932; CHECK: j.loop: 933; CHECK-NEXT: call void @payload() 934; CHECK-NEXT: br label [[J_LOOPDONE]] 935; CHECK: j.loopdone: 936; CHECK-NEXT: [[INDVAR_NEXT2]] = add i64 [[INDVAR1]], 1 937; CHECK-NEXT: [[I_ATEND:%.*]] = icmp eq i64 [[INDVAR_NEXT2]], [[FLATTEN_TRIPCOUNT]] 938; CHECK-NEXT: br i1 [[I_ATEND]], label [[I_LOOPDONE:%.*]], label [[I_LOOP]] 939; CHECK: i.loopdone: 940; CHECK-NEXT: ret i32 0 941; 942; DONTWIDEN-LABEL: @constTripCount( 943; DONTWIDEN-NEXT: entry: 944; DONTWIDEN-NEXT: br label [[I_LOOP:%.*]] 945; DONTWIDEN: i.loop: 946; DONTWIDEN-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[J_LOOPDONE:%.*]] ] 947; DONTWIDEN-NEXT: br label [[J_LOOP:%.*]] 948; DONTWIDEN: j.loop: 949; DONTWIDEN-NEXT: [[J:%.*]] = phi i8 [ 0, [[I_LOOP]] ], [ [[J_INC:%.*]], [[J_LOOP]] ] 950; DONTWIDEN-NEXT: call void @payload() 951; DONTWIDEN-NEXT: [[J_INC]] = add i8 [[J]], 1 952; DONTWIDEN-NEXT: [[J_ATEND:%.*]] = icmp eq i8 [[J_INC]], 20 953; DONTWIDEN-NEXT: br i1 [[J_ATEND]], label [[J_LOOPDONE]], label [[J_LOOP]] 954; DONTWIDEN: j.loopdone: 955; DONTWIDEN-NEXT: [[I_INC]] = add i8 [[I]], 1 956; DONTWIDEN-NEXT: [[I_ATEND:%.*]] = icmp eq i8 [[I_INC]], 20 957; DONTWIDEN-NEXT: br i1 [[I_ATEND]], label [[I_LOOPDONE:%.*]], label [[I_LOOP]] 958; DONTWIDEN: i.loopdone: 959; DONTWIDEN-NEXT: ret i32 0 960; 961entry: 962 br label %i.loop 963 964i.loop: 965 %i = phi i8 [ 0, %entry ], [ %i.inc, %j.loopdone ] 966 br label %j.loop 967 968j.loop: 969 %j = phi i8 [ 0, %i.loop ], [ %j.inc, %j.loop ] 970 call void @payload() 971 %j.inc = add i8 %j, 1 972 %j.atend = icmp eq i8 %j.inc, 20 973 br i1 %j.atend, label %j.loopdone, label %j.loop 974 975j.loopdone: 976 %i.inc = add i8 %i, 1 977 %i.atend = icmp eq i8 %i.inc, 20 978 br i1 %i.atend, label %i.loopdone, label %i.loop 979 980i.loopdone: 981 ret i32 0 982} 983 984; Same as @foo, but M is sext from i16. This used to assert because we thought 985; this sext was from widening and try to look through it. 986define void @foo_M_sext(ptr %A, i32 %N, i16 %M) { 987; CHECK-LABEL: @foo_M_sext( 988; CHECK-NEXT: entry: 989; CHECK-NEXT: [[M2:%.*]] = sext i16 [[M:%.*]] to i32 990; CHECK-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0 991; CHECK-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]] 992; CHECK: for.cond1.preheader.lr.ph: 993; CHECK-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M2]], 0 994; CHECK-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]] 995; CHECK: for.cond1.preheader.us.preheader: 996; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[M2]] to i64 997; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[N]] to i64 998; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]] 999; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 1000; CHECK: for.cond1.preheader.us: 1001; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] 1002; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]] 1003; CHECK: for.body4.us: 1004; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVAR2]] 1005; CHECK-NEXT: tail call void @f(ptr [[ARRAYIDX_US]]) 1006; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] 1007; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us: 1008; CHECK-NEXT: [[INDVAR_NEXT3]] = add nuw nsw i64 [[INDVAR2]], 1 1009; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]] 1010; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 1011; CHECK: for.cond.cleanup.loopexit: 1012; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 1013; CHECK: for.cond.cleanup: 1014; CHECK-NEXT: ret void 1015; 1016; DONTWIDEN-LABEL: @foo_M_sext( 1017; DONTWIDEN-NEXT: entry: 1018; DONTWIDEN-NEXT: [[M2:%.*]] = sext i16 [[M:%.*]] to i32 1019; DONTWIDEN-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0 1020; DONTWIDEN-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]] 1021; DONTWIDEN: for.cond1.preheader.lr.ph: 1022; DONTWIDEN-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M2]], 0 1023; DONTWIDEN-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]] 1024; DONTWIDEN: for.cond1.preheader.us.preheader: 1025; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] 1026; DONTWIDEN: for.cond1.preheader.us: 1027; DONTWIDEN-NEXT: [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] 1028; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul nsw i32 [[I_018_US]], [[M2]] 1029; DONTWIDEN-NEXT: br label [[FOR_BODY4_US:%.*]] 1030; DONTWIDEN: for.body4.us: 1031; DONTWIDEN-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ] 1032; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add nsw i32 [[J_016_US]], [[MUL_US]] 1033; DONTWIDEN-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64 1034; DONTWIDEN-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 1035; DONTWIDEN-NEXT: tail call void @f(ptr [[ARRAYIDX_US]]) 1036; DONTWIDEN-NEXT: [[INC_US]] = add nuw nsw i32 [[J_016_US]], 1 1037; DONTWIDEN-NEXT: [[CMP2_US:%.*]] = icmp slt i32 [[INC_US]], [[M2]] 1038; DONTWIDEN-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] 1039; DONTWIDEN: for.cond1.for.cond.cleanup3_crit_edge.us: 1040; DONTWIDEN-NEXT: [[INC6_US]] = add nuw nsw i32 [[I_018_US]], 1 1041; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[INC6_US]], [[N]] 1042; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] 1043; DONTWIDEN: for.cond.cleanup.loopexit: 1044; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]] 1045; DONTWIDEN: for.cond.cleanup: 1046; DONTWIDEN-NEXT: ret void 1047; 1048entry: 1049 %M2 = sext i16 %M to i32 1050 %cmp17 = icmp sgt i32 %N, 0 1051 br i1 %cmp17, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup 1052 1053for.cond1.preheader.lr.ph: 1054 %cmp215 = icmp sgt i32 %M2, 0 1055 br i1 %cmp215, label %for.cond1.preheader.us.preheader, label %for.cond.cleanup 1056 1057for.cond1.preheader.us.preheader: 1058 br label %for.cond1.preheader.us 1059 1060for.cond1.preheader.us: 1061 %i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ] 1062 %mul.us = mul nsw i32 %i.018.us, %M2 1063 br label %for.body4.us 1064 1065for.body4.us: 1066 %j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ] 1067 %add.us = add nsw i32 %j.016.us, %mul.us 1068 %idxprom.us = sext i32 %add.us to i64 1069 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 1070 tail call void @f(ptr %arrayidx.us) #2 1071 %inc.us = add nuw nsw i32 %j.016.us, 1 1072 %cmp2.us = icmp slt i32 %inc.us, %M2 1073 br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us 1074 1075for.cond1.for.cond.cleanup3_crit_edge.us: 1076 %inc6.us = add nuw nsw i32 %i.018.us, 1 1077 %cmp.us = icmp slt i32 %inc6.us, %N 1078 br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup 1079 1080for.cond.cleanup: 1081 ret void 1082} 1083 1084declare void @payload() 1085declare dso_local i32 @use_32(i32) 1086declare dso_local i32 @use_16(i16) 1087declare dso_local i32 @use_64(i64) 1088declare dso_local void @g(i32) 1089 1090declare dso_local void @f(ptr %0) local_unnamed_addr #1 1091