1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -passes='indvars' -verify-loop-info -verify-dom-info -verify-scev | FileCheck %s 3 4target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" 5 6; This file covers proving non-negative IVs for IV widening on common 7; count down loop structures. Count down loops are tricky to prove 8; non-negative for since we canonicalize a sub to add, and loose the 9; sub nuw fact. 10 11; use(a[i]) loops 12; ------------------------------------------------------------------- 13 14define void @zext_postinc_constant_start(ptr %A) { 15; CHECK-LABEL: @zext_postinc_constant_start( 16; CHECK-NEXT: entry: 17; CHECK-NEXT: br label [[FOR_BODY:%.*]] 18; CHECK: for.body: 19; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 20; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 21; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 22; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 23; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6 24; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 25; CHECK: exit: 26; CHECK-NEXT: ret void 27; 28entry: 29 br label %for.body 30 31for.body: 32 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 33 %idxprom.us = zext i32 %j.016.us to i64 34 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 35 tail call void @use_ptr(ptr %arrayidx.us) 36 %inc.us = add nsw i32 %j.016.us, -1 37 %cmp2.us = icmp ugt i32 %inc.us, 6 38 br i1 %cmp2.us, label %for.body, label %exit 39 40exit: 41 ret void 42} 43 44 45define void @zext_preinc_constant_start(ptr %A) { 46; CHECK-LABEL: @zext_preinc_constant_start( 47; CHECK-NEXT: entry: 48; CHECK-NEXT: br label [[FOR_BODY:%.*]] 49; CHECK: for.body: 50; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 51; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 52; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 53; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 54; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6 55; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 56; CHECK: exit: 57; CHECK-NEXT: ret void 58; 59entry: 60 br label %for.body 61 62for.body: 63 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 64 %idxprom.us = zext i32 %j.016.us to i64 65 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 66 tail call void @use_ptr(ptr %arrayidx.us) 67 %inc.us = add nsw i32 %j.016.us, -1 68 %cmp2.us = icmp ugt i32 %j.016.us, 6 69 br i1 %cmp2.us, label %for.body, label %exit 70 71exit: 72 ret void 73} 74 75define void @zext_postinc(ptr %A, i32 %start) { 76; CHECK-LABEL: @zext_postinc( 77; CHECK-NEXT: entry: 78; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 79; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 80; CHECK: for.body.preheader: 81; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START]] to i64 82; CHECK-NEXT: br label [[FOR_BODY:%.*]] 83; CHECK: for.body: 84; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 85; CHECK-NEXT: [[J_016_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[FOR_BODY]] ], [ [[START]], [[FOR_BODY_PREHEADER]] ] 86; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 87; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 88; CHECK-NEXT: [[INC_US]] = add nsw i32 [[J_016_US]], -1 89; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[INC_US]], 6 90; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 91; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 92; CHECK: exit.loopexit: 93; CHECK-NEXT: br label [[EXIT]] 94; CHECK: exit: 95; CHECK-NEXT: ret void 96; 97entry: 98 %nonpos = icmp slt i32 %start, 2 99 br i1 %nonpos, label %exit, label %for.body 100 101for.body: 102 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 103 %idxprom.us = zext i32 %j.016.us to i64 104 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 105 tail call void @use_ptr(ptr %arrayidx.us) 106 %inc.us = add nsw i32 %j.016.us, -1 107 %cmp2.us = icmp ugt i32 %inc.us, 6 108 br i1 %cmp2.us, label %for.body, label %exit 109 110exit: 111 ret void 112} 113 114 115define void @zext_preinc(ptr %A, i32 %start) { 116; CHECK-LABEL: @zext_preinc( 117; CHECK-NEXT: entry: 118; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 119; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 120; CHECK: for.body.preheader: 121; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START]] to i64 122; CHECK-NEXT: br label [[FOR_BODY:%.*]] 123; CHECK: for.body: 124; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 125; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 126; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 127; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6 128; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 129; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 130; CHECK: exit.loopexit: 131; CHECK-NEXT: br label [[EXIT]] 132; CHECK: exit: 133; CHECK-NEXT: ret void 134; 135entry: 136 %nonpos = icmp slt i32 %start, 2 137 br i1 %nonpos, label %exit, label %for.body 138 139for.body: 140 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 141 %idxprom.us = zext i32 %j.016.us to i64 142 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 143 tail call void @use_ptr(ptr %arrayidx.us) 144 %inc.us = add nsw i32 %j.016.us, -1 145 %cmp2.us = icmp ugt i32 %j.016.us, 6 146 br i1 %cmp2.us, label %for.body, label %exit 147 148exit: 149 ret void 150} 151 152define void @sext_postinc_constant_start(ptr %A) { 153; CHECK-LABEL: @sext_postinc_constant_start( 154; CHECK-NEXT: entry: 155; CHECK-NEXT: br label [[FOR_BODY:%.*]] 156; CHECK: for.body: 157; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 158; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 159; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 160; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 161; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6 162; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 163; CHECK: exit: 164; CHECK-NEXT: ret void 165; 166entry: 167 br label %for.body 168 169for.body: 170 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 171 %idxprom.us = sext i32 %j.016.us to i64 172 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 173 tail call void @use_ptr(ptr %arrayidx.us) 174 %inc.us = add nsw i32 %j.016.us, -1 175 %cmp2.us = icmp ugt i32 %inc.us, 6 176 br i1 %cmp2.us, label %for.body, label %exit 177 178exit: 179 ret void 180} 181 182 183define void @sext_preinc_constant_start(ptr %A) { 184; CHECK-LABEL: @sext_preinc_constant_start( 185; CHECK-NEXT: entry: 186; CHECK-NEXT: br label [[FOR_BODY:%.*]] 187; CHECK: for.body: 188; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 189; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 190; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 191; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 192; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6 193; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 194; CHECK: exit: 195; CHECK-NEXT: ret void 196; 197entry: 198 br label %for.body 199 200for.body: 201 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 202 %idxprom.us = sext i32 %j.016.us to i64 203 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 204 tail call void @use_ptr(ptr %arrayidx.us) 205 %inc.us = add nsw i32 %j.016.us, -1 206 %cmp2.us = icmp ugt i32 %j.016.us, 6 207 br i1 %cmp2.us, label %for.body, label %exit 208 209exit: 210 ret void 211} 212 213define void @sext_postinc(ptr %A, i32 %start) { 214; CHECK-LABEL: @sext_postinc( 215; CHECK-NEXT: entry: 216; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 217; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 218; CHECK: for.body.preheader: 219; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[START]] to i64 220; CHECK-NEXT: br label [[FOR_BODY:%.*]] 221; CHECK: for.body: 222; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 223; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 224; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 225; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 226; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV_NEXT]] to i32 227; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[TMP1]], 6 228; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 229; CHECK: exit.loopexit: 230; CHECK-NEXT: br label [[EXIT]] 231; CHECK: exit: 232; CHECK-NEXT: ret void 233; 234entry: 235 %nonpos = icmp slt i32 %start, 2 236 br i1 %nonpos, label %exit, label %for.body 237 238for.body: 239 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 240 %idxprom.us = sext i32 %j.016.us to i64 241 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 242 tail call void @use_ptr(ptr %arrayidx.us) 243 %inc.us = add nsw i32 %j.016.us, -1 244 %cmp2.us = icmp ugt i32 %inc.us, 6 245 br i1 %cmp2.us, label %for.body, label %exit 246 247exit: 248 ret void 249} 250 251 252define void @sext_preinc(ptr %A, i32 %start) { 253; CHECK-LABEL: @sext_preinc( 254; CHECK-NEXT: entry: 255; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 256; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 257; CHECK: for.body.preheader: 258; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[START]] to i64 259; CHECK-NEXT: br label [[FOR_BODY:%.*]] 260; CHECK: for.body: 261; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 262; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 263; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 264; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 265; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32 266; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[TMP1]], 6 267; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 268; CHECK: exit.loopexit: 269; CHECK-NEXT: br label [[EXIT]] 270; CHECK: exit: 271; CHECK-NEXT: ret void 272; 273entry: 274 %nonpos = icmp slt i32 %start, 2 275 br i1 %nonpos, label %exit, label %for.body 276 277for.body: 278 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 279 %idxprom.us = sext i32 %j.016.us to i64 280 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 281 tail call void @use_ptr(ptr %arrayidx.us) 282 %inc.us = add nsw i32 %j.016.us, -1 283 %cmp2.us = icmp ugt i32 %j.016.us, 6 284 br i1 %cmp2.us, label %for.body, label %exit 285 286exit: 287 ret void 288} 289 290; use(a[i + 1]) loops 291; ------------------------------------------------------------------- 292 293define void @zext_postinc_constant_start_offset_constant_one(ptr %A) { 294; CHECK-LABEL: @zext_postinc_constant_start_offset_constant_one( 295; CHECK-NEXT: entry: 296; CHECK-NEXT: br label [[FOR_BODY:%.*]] 297; CHECK: for.body: 298; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 299; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1 300; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP0]] 301; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 302; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 303; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6 304; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 305; CHECK: exit: 306; CHECK-NEXT: ret void 307; 308entry: 309 br label %for.body 310 311for.body: 312 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 313 %add.us = add i32 %j.016.us, 1 314 %idxprom.us = zext i32 %add.us to i64 315 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 316 tail call void @use_ptr(ptr %arrayidx.us) 317 %inc.us = add nsw i32 %j.016.us, -1 318 %cmp2.us = icmp ugt i32 %inc.us, 6 319 br i1 %cmp2.us, label %for.body, label %exit 320 321exit: 322 ret void 323} 324 325 326define void @zext_preinc_constant_start_offset_constant_one(ptr %A) { 327; CHECK-LABEL: @zext_preinc_constant_start_offset_constant_one( 328; CHECK-NEXT: entry: 329; CHECK-NEXT: br label [[FOR_BODY:%.*]] 330; CHECK: for.body: 331; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 332; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1 333; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP0]] 334; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 335; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 336; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6 337; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 338; CHECK: exit: 339; CHECK-NEXT: ret void 340; 341entry: 342 br label %for.body 343 344for.body: 345 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 346 %add.us = add i32 %j.016.us, 1 347 %idxprom.us = zext i32 %add.us to i64 348 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 349 tail call void @use_ptr(ptr %arrayidx.us) 350 %inc.us = add nsw i32 %j.016.us, -1 351 %cmp2.us = icmp ugt i32 %j.016.us, 6 352 br i1 %cmp2.us, label %for.body, label %exit 353 354exit: 355 ret void 356} 357 358define void @zext_postinc_offset_constant_one(ptr %A, i32 %start) { 359; CHECK-LABEL: @zext_postinc_offset_constant_one( 360; CHECK-NEXT: entry: 361; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 362; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 363; CHECK: for.body.preheader: 364; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START]] to i64 365; CHECK-NEXT: br label [[FOR_BODY:%.*]] 366; CHECK: for.body: 367; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 368; CHECK-NEXT: [[J_016_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[FOR_BODY]] ], [ [[START]], [[FOR_BODY_PREHEADER]] ] 369; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw i64 [[INDVARS_IV]] to i32 370; CHECK-NEXT: [[ADD_US:%.*]] = add i32 [[TMP1]], 1 371; CHECK-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64 372; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 373; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 374; CHECK-NEXT: [[INC_US]] = add nsw i32 [[J_016_US]], -1 375; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[INC_US]], 6 376; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 377; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 378; CHECK: exit.loopexit: 379; CHECK-NEXT: br label [[EXIT]] 380; CHECK: exit: 381; CHECK-NEXT: ret void 382; 383entry: 384 %nonpos = icmp slt i32 %start, 2 385 br i1 %nonpos, label %exit, label %for.body 386 387for.body: 388 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 389 %add.us = add i32 %j.016.us, 1 390 %idxprom.us = zext i32 %add.us to i64 391 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 392 tail call void @use_ptr(ptr %arrayidx.us) 393 %inc.us = add nsw i32 %j.016.us, -1 394 %cmp2.us = icmp ugt i32 %inc.us, 6 395 br i1 %cmp2.us, label %for.body, label %exit 396 397exit: 398 ret void 399} 400 401 402define void @zext_preinc_offset_constant_one(ptr %A, i32 %start) { 403; CHECK-LABEL: @zext_preinc_offset_constant_one( 404; CHECK-NEXT: entry: 405; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 406; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 407; CHECK: for.body.preheader: 408; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START]] to i64 409; CHECK-NEXT: br label [[FOR_BODY:%.*]] 410; CHECK: for.body: 411; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 412; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1 413; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]] 414; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 415; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6 416; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 417; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 418; CHECK: exit.loopexit: 419; CHECK-NEXT: br label [[EXIT]] 420; CHECK: exit: 421; CHECK-NEXT: ret void 422; 423entry: 424 %nonpos = icmp slt i32 %start, 2 425 br i1 %nonpos, label %exit, label %for.body 426 427for.body: 428 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 429 %add.us = add i32 %j.016.us, 1 430 %idxprom.us = zext i32 %add.us to i64 431 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 432 tail call void @use_ptr(ptr %arrayidx.us) 433 %inc.us = add nsw i32 %j.016.us, -1 434 %cmp2.us = icmp ugt i32 %j.016.us, 6 435 br i1 %cmp2.us, label %for.body, label %exit 436 437exit: 438 ret void 439} 440 441define void @sext_postinc_constant_start_offset_constant_one(ptr %A) { 442; CHECK-LABEL: @sext_postinc_constant_start_offset_constant_one( 443; CHECK-NEXT: entry: 444; CHECK-NEXT: br label [[FOR_BODY:%.*]] 445; CHECK: for.body: 446; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 447; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1 448; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP0]] 449; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 450; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 451; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6 452; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 453; CHECK: exit: 454; CHECK-NEXT: ret void 455; 456entry: 457 br label %for.body 458 459for.body: 460 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 461 %add.us = add i32 %j.016.us, 1 462 %idxprom.us = sext i32 %add.us to i64 463 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 464 tail call void @use_ptr(ptr %arrayidx.us) 465 %inc.us = add nsw i32 %j.016.us, -1 466 %cmp2.us = icmp ugt i32 %inc.us, 6 467 br i1 %cmp2.us, label %for.body, label %exit 468 469exit: 470 ret void 471} 472 473 474define void @sext_preinc_constant_start_offset_constant_one(ptr %A) { 475; CHECK-LABEL: @sext_preinc_constant_start_offset_constant_one( 476; CHECK-NEXT: entry: 477; CHECK-NEXT: br label [[FOR_BODY:%.*]] 478; CHECK: for.body: 479; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 480; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1 481; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP0]] 482; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 483; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 484; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6 485; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 486; CHECK: exit: 487; CHECK-NEXT: ret void 488; 489entry: 490 br label %for.body 491 492for.body: 493 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 494 %add.us = add i32 %j.016.us, 1 495 %idxprom.us = sext i32 %add.us to i64 496 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 497 tail call void @use_ptr(ptr %arrayidx.us) 498 %inc.us = add nsw i32 %j.016.us, -1 499 %cmp2.us = icmp ugt i32 %j.016.us, 6 500 br i1 %cmp2.us, label %for.body, label %exit 501 502exit: 503 ret void 504} 505 506define void @sext_postinc_offset_constant_one(ptr %A, i32 %start) { 507; CHECK-LABEL: @sext_postinc_offset_constant_one( 508; CHECK-NEXT: entry: 509; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 510; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 511; CHECK: for.body.preheader: 512; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[START]] to i64 513; CHECK-NEXT: br label [[FOR_BODY:%.*]] 514; CHECK: for.body: 515; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 516; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32 517; CHECK-NEXT: [[ADD_US:%.*]] = add i32 [[TMP1]], 1 518; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64 519; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 520; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 521; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 522; CHECK-NEXT: [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV_NEXT]] to i32 523; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[TMP2]], 6 524; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 525; CHECK: exit.loopexit: 526; CHECK-NEXT: br label [[EXIT]] 527; CHECK: exit: 528; CHECK-NEXT: ret void 529; 530entry: 531 %nonpos = icmp slt i32 %start, 2 532 br i1 %nonpos, label %exit, label %for.body 533 534for.body: 535 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 536 %add.us = add i32 %j.016.us, 1 537 %idxprom.us = sext i32 %add.us to i64 538 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 539 tail call void @use_ptr(ptr %arrayidx.us) 540 %inc.us = add nsw i32 %j.016.us, -1 541 %cmp2.us = icmp ugt i32 %inc.us, 6 542 br i1 %cmp2.us, label %for.body, label %exit 543 544exit: 545 ret void 546} 547 548 549define void @sext_preinc_offset_constant_one(ptr %A, i32 %start) { 550; CHECK-LABEL: @sext_preinc_offset_constant_one( 551; CHECK-NEXT: entry: 552; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 553; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 554; CHECK: for.body.preheader: 555; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[START]] to i64 556; CHECK-NEXT: br label [[FOR_BODY:%.*]] 557; CHECK: for.body: 558; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 559; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32 560; CHECK-NEXT: [[ADD_US:%.*]] = add nuw i32 [[TMP1]], 1 561; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64 562; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 563; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 564; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 565; CHECK-NEXT: [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32 566; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[TMP2]], 6 567; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 568; CHECK: exit.loopexit: 569; CHECK-NEXT: br label [[EXIT]] 570; CHECK: exit: 571; CHECK-NEXT: ret void 572; 573entry: 574 %nonpos = icmp slt i32 %start, 2 575 br i1 %nonpos, label %exit, label %for.body 576 577for.body: 578 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 579 %add.us = add i32 %j.016.us, 1 580 %idxprom.us = sext i32 %add.us to i64 581 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 582 tail call void @use_ptr(ptr %arrayidx.us) 583 %inc.us = add nsw i32 %j.016.us, -1 584 %cmp2.us = icmp ugt i32 %j.016.us, 6 585 br i1 %cmp2.us, label %for.body, label %exit 586 587exit: 588 ret void 589} 590 591; use(a[i - 1]) loops 592; ------------------------------------------------------------------- 593 594define void @zext_postinc_constant_start_offset_constant_minus_one(ptr %A) { 595; CHECK-LABEL: @zext_postinc_constant_start_offset_constant_minus_one( 596; CHECK-NEXT: entry: 597; CHECK-NEXT: br label [[FOR_BODY:%.*]] 598; CHECK: for.body: 599; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 600; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 601; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV_NEXT]] 602; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 603; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6 604; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 605; CHECK: exit: 606; CHECK-NEXT: ret void 607; 608entry: 609 br label %for.body 610 611for.body: 612 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 613 %add.us = add i32 %j.016.us, -1 614 %idxprom.us = zext i32 %add.us to i64 615 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 616 tail call void @use_ptr(ptr %arrayidx.us) 617 %inc.us = add nsw i32 %j.016.us, -1 618 %cmp2.us = icmp ugt i32 %inc.us, 6 619 br i1 %cmp2.us, label %for.body, label %exit 620 621exit: 622 ret void 623} 624 625 626define void @zext_preinc_constant_start_offset_constant_minus_one(ptr %A) { 627; CHECK-LABEL: @zext_preinc_constant_start_offset_constant_minus_one( 628; CHECK-NEXT: entry: 629; CHECK-NEXT: br label [[FOR_BODY:%.*]] 630; CHECK: for.body: 631; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 632; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 633; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV_NEXT]] 634; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 635; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6 636; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 637; CHECK: exit: 638; CHECK-NEXT: ret void 639; 640entry: 641 br label %for.body 642 643for.body: 644 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 645 %add.us = add i32 %j.016.us, -1 646 %idxprom.us = zext i32 %add.us to i64 647 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 648 tail call void @use_ptr(ptr %arrayidx.us) 649 %inc.us = add nsw i32 %j.016.us, -1 650 %cmp2.us = icmp ugt i32 %j.016.us, 6 651 br i1 %cmp2.us, label %for.body, label %exit 652 653exit: 654 ret void 655} 656 657define void @zext_postinc_offset_constant_minus_one(ptr %A, i32 %start) { 658; CHECK-LABEL: @zext_postinc_offset_constant_minus_one( 659; CHECK-NEXT: entry: 660; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 661; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 662; CHECK: for.body.preheader: 663; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START]] to i64 664; CHECK-NEXT: br label [[FOR_BODY:%.*]] 665; CHECK: for.body: 666; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 667; CHECK-NEXT: [[J_016_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[FOR_BODY]] ], [ [[START]], [[FOR_BODY_PREHEADER]] ] 668; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1 669; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]] 670; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 671; CHECK-NEXT: [[INC_US]] = add nsw i32 [[J_016_US]], -1 672; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[INC_US]], 6 673; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 674; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 675; CHECK: exit.loopexit: 676; CHECK-NEXT: br label [[EXIT]] 677; CHECK: exit: 678; CHECK-NEXT: ret void 679; 680entry: 681 %nonpos = icmp slt i32 %start, 2 682 br i1 %nonpos, label %exit, label %for.body 683 684for.body: 685 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 686 %add.us = add i32 %j.016.us, -1 687 %idxprom.us = zext i32 %add.us to i64 688 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 689 tail call void @use_ptr(ptr %arrayidx.us) 690 %inc.us = add nsw i32 %j.016.us, -1 691 %cmp2.us = icmp ugt i32 %inc.us, 6 692 br i1 %cmp2.us, label %for.body, label %exit 693 694exit: 695 ret void 696} 697 698 699define void @zext_preinc_offset_constant_minus_one(ptr %A, i32 %start) { 700; CHECK-LABEL: @zext_preinc_offset_constant_minus_one( 701; CHECK-NEXT: entry: 702; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 703; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 704; CHECK: for.body.preheader: 705; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START]] to i64 706; CHECK-NEXT: br label [[FOR_BODY:%.*]] 707; CHECK: for.body: 708; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 709; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1 710; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]] 711; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 712; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6 713; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 714; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 715; CHECK: exit.loopexit: 716; CHECK-NEXT: br label [[EXIT]] 717; CHECK: exit: 718; CHECK-NEXT: ret void 719; 720entry: 721 %nonpos = icmp slt i32 %start, 2 722 br i1 %nonpos, label %exit, label %for.body 723 724for.body: 725 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 726 %add.us = add i32 %j.016.us, -1 727 %idxprom.us = zext i32 %add.us to i64 728 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 729 tail call void @use_ptr(ptr %arrayidx.us) 730 %inc.us = add nsw i32 %j.016.us, -1 731 %cmp2.us = icmp ugt i32 %j.016.us, 6 732 br i1 %cmp2.us, label %for.body, label %exit 733 734exit: 735 ret void 736} 737 738define void @sext_postinc_constant_start_offset_constant_minus_one(ptr %A) { 739; CHECK-LABEL: @sext_postinc_constant_start_offset_constant_minus_one( 740; CHECK-NEXT: entry: 741; CHECK-NEXT: br label [[FOR_BODY:%.*]] 742; CHECK: for.body: 743; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 744; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 745; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV_NEXT]] 746; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 747; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6 748; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 749; CHECK: exit: 750; CHECK-NEXT: ret void 751; 752entry: 753 br label %for.body 754 755for.body: 756 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 757 %add.us = add i32 %j.016.us, -1 758 %idxprom.us = sext i32 %add.us to i64 759 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 760 tail call void @use_ptr(ptr %arrayidx.us) 761 %inc.us = add nsw i32 %j.016.us, -1 762 %cmp2.us = icmp ugt i32 %inc.us, 6 763 br i1 %cmp2.us, label %for.body, label %exit 764 765exit: 766 ret void 767} 768 769 770define void @sext_preinc_constant_start_offset_constant_minus_one(ptr %A) { 771; CHECK-LABEL: @sext_preinc_constant_start_offset_constant_minus_one( 772; CHECK-NEXT: entry: 773; CHECK-NEXT: br label [[FOR_BODY:%.*]] 774; CHECK: for.body: 775; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ] 776; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 777; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV_NEXT]] 778; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 779; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6 780; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]] 781; CHECK: exit: 782; CHECK-NEXT: ret void 783; 784entry: 785 br label %for.body 786 787for.body: 788 %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ] 789 %add.us = add i32 %j.016.us, -1 790 %idxprom.us = sext i32 %add.us to i64 791 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 792 tail call void @use_ptr(ptr %arrayidx.us) 793 %inc.us = add nsw i32 %j.016.us, -1 794 %cmp2.us = icmp ugt i32 %j.016.us, 6 795 br i1 %cmp2.us, label %for.body, label %exit 796 797exit: 798 ret void 799} 800 801define void @sext_postinc_offset_constant_minus_one(ptr %A, i32 %start) { 802; CHECK-LABEL: @sext_postinc_offset_constant_minus_one( 803; CHECK-NEXT: entry: 804; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 805; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 806; CHECK: for.body.preheader: 807; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[START]] to i64 808; CHECK-NEXT: br label [[FOR_BODY:%.*]] 809; CHECK: for.body: 810; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 811; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32 812; CHECK-NEXT: [[ADD_US:%.*]] = add i32 [[TMP1]], -1 813; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64 814; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 815; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 816; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 817; CHECK-NEXT: [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV_NEXT]] to i32 818; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[TMP2]], 6 819; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 820; CHECK: exit.loopexit: 821; CHECK-NEXT: br label [[EXIT]] 822; CHECK: exit: 823; CHECK-NEXT: ret void 824; 825entry: 826 %nonpos = icmp slt i32 %start, 2 827 br i1 %nonpos, label %exit, label %for.body 828 829for.body: 830 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 831 %add.us = add i32 %j.016.us, -1 832 %idxprom.us = sext i32 %add.us to i64 833 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 834 tail call void @use_ptr(ptr %arrayidx.us) 835 %inc.us = add nsw i32 %j.016.us, -1 836 %cmp2.us = icmp ugt i32 %inc.us, 6 837 br i1 %cmp2.us, label %for.body, label %exit 838 839exit: 840 ret void 841} 842 843 844define void @sext_preinc_offset_constant_minus_one(ptr %A, i32 %start) { 845; CHECK-LABEL: @sext_preinc_offset_constant_minus_one( 846; CHECK-NEXT: entry: 847; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2 848; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]] 849; CHECK: for.body.preheader: 850; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[START]] to i64 851; CHECK-NEXT: br label [[FOR_BODY:%.*]] 852; CHECK: for.body: 853; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 854; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32 855; CHECK-NEXT: [[ADD_US:%.*]] = add i32 [[TMP1]], -1 856; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64 857; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 858; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 859; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 860; CHECK-NEXT: [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32 861; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[TMP2]], 6 862; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]] 863; CHECK: exit.loopexit: 864; CHECK-NEXT: br label [[EXIT]] 865; CHECK: exit: 866; CHECK-NEXT: ret void 867; 868entry: 869 %nonpos = icmp slt i32 %start, 2 870 br i1 %nonpos, label %exit, label %for.body 871 872for.body: 873 %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ] 874 %add.us = add i32 %j.016.us, -1 875 %idxprom.us = sext i32 %add.us to i64 876 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 877 tail call void @use_ptr(ptr %arrayidx.us) 878 %inc.us = add nsw i32 %j.016.us, -1 879 %cmp2.us = icmp ugt i32 %j.016.us, 6 880 br i1 %cmp2.us, label %for.body, label %exit 881 882exit: 883 ret void 884} 885 886declare dso_local void @use_ptr(ptr %0) 887 888 889