1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -indvars -indvars-post-increment-ranges -S | FileCheck %s 3 4target datalayout = "p:64:64:64-n32:64" 5 6; When the IV in this loop is widened we want to widen this use as well: 7; icmp slt i32 %i.inc, %limit 8; In order to do this indvars need to prove that the narrow IV def (%i.inc) 9; is not-negative from the range check inside of the loop. 10define void @test(i32* %base, i32 %limit, i32 %start) { 11; CHECK-LABEL: @test( 12; CHECK-NEXT: for.body.lr.ph: 13; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[START:%.*]], i32 64) 14; CHECK-NEXT: [[TMP0:%.*]] = sub i32 [[UMAX]], [[START]] 15; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[START]], 1 16; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[LIMIT:%.*]], i32 [[TMP1]]) 17; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[SMAX]], -1 18; CHECK-NEXT: [[TMP3:%.*]] = sub i32 [[TMP2]], [[START]] 19; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP3]], i32 [[TMP0]]) 20; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP0]], [[UMIN]] 21; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i32 [[TMP3]], [[UMIN]] 22; CHECK-NEXT: br label [[FOR_BODY:%.*]] 23; CHECK: for.body: 24; CHECK-NEXT: br i1 [[TMP4]], label [[CONTINUE:%.*]], label [[FOR_END:%.*]] 25; CHECK: continue: 26; CHECK-NEXT: br label [[FOR_INC:%.*]] 27; CHECK: for.inc: 28; CHECK-NEXT: br i1 [[TMP5]], label [[FOR_BODY]], label [[FOR_END]] 29; CHECK: for.end: 30; CHECK-NEXT: br label [[EXIT:%.*]] 31; CHECK: exit: 32; CHECK-NEXT: ret void 33; 34 35for.body.lr.ph: 36 br label %for.body 37 38for.body: 39 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ] 40 %within_limits = icmp ult i32 %i, 64 41 br i1 %within_limits, label %continue, label %for.end 42 43continue: 44 %i.i64 = zext i32 %i to i64 45 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64 46 %val = load i32, i32* %arrayidx, align 4 47 br label %for.inc 48 49for.inc: 50 %i.inc = add nsw nuw i32 %i, 1 51 %cmp = icmp slt i32 %i.inc, %limit 52 br i1 %cmp, label %for.body, label %for.end 53 54for.end: 55 br label %exit 56 57exit: 58 ret void 59} 60 61define void @test_false_edge(i32* %base, i32 %limit, i32 %start) { 62; CHECK-LABEL: @test_false_edge( 63; CHECK-NEXT: for.body.lr.ph: 64; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[START:%.*]], i32 65) 65; CHECK-NEXT: [[TMP0:%.*]] = sub i32 [[UMAX]], [[START]] 66; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[START]], 1 67; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[LIMIT:%.*]], i32 [[TMP1]]) 68; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[SMAX]], -1 69; CHECK-NEXT: [[TMP3:%.*]] = sub i32 [[TMP2]], [[START]] 70; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP3]], i32 [[TMP0]]) 71; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], [[UMIN]] 72; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i32 [[TMP3]], [[UMIN]] 73; CHECK-NEXT: br label [[FOR_BODY:%.*]] 74; CHECK: for.body: 75; CHECK-NEXT: br i1 [[TMP4]], label [[FOR_END:%.*]], label [[CONTINUE:%.*]] 76; CHECK: continue: 77; CHECK-NEXT: br label [[FOR_INC:%.*]] 78; CHECK: for.inc: 79; CHECK-NEXT: br i1 [[TMP5]], label [[FOR_BODY]], label [[FOR_END]] 80; CHECK: for.end: 81; CHECK-NEXT: br label [[EXIT:%.*]] 82; CHECK: exit: 83; CHECK-NEXT: ret void 84; 85 86for.body.lr.ph: 87 br label %for.body 88 89for.body: 90 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ] 91 %out_of_bounds = icmp ugt i32 %i, 64 92 br i1 %out_of_bounds, label %for.end, label %continue 93 94continue: 95 %i.i64 = zext i32 %i to i64 96 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64 97 %val = load i32, i32* %arrayidx, align 4 98 br label %for.inc 99 100for.inc: 101 %i.inc = add nsw nuw i32 %i, 1 102 %cmp = icmp slt i32 %i.inc, %limit 103 br i1 %cmp, label %for.body, label %for.end 104 105for.end: 106 br label %exit 107 108exit: 109 ret void 110} 111 112define void @test_range_metadata(i32* %array_length_ptr, i32* %base, 113; CHECK-LABEL: @test_range_metadata( 114; CHECK-NEXT: for.body.lr.ph: 115; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 116; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 117; CHECK-NEXT: br label [[FOR_BODY:%.*]] 118; CHECK: for.body: 119; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] 120; CHECK-NEXT: [[ARRAY_LENGTH:%.*]] = load i32, i32* [[ARRAY_LENGTH_PTR:%.*]], align 4, !range [[RNG0:![0-9]+]] 121; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[ARRAY_LENGTH]] to i64 122; CHECK-NEXT: [[WITHIN_LIMITS:%.*]] = icmp ult i64 [[INDVARS_IV]], [[TMP2]] 123; CHECK-NEXT: br i1 [[WITHIN_LIMITS]], label [[CONTINUE:%.*]], label [[FOR_END:%.*]] 124; CHECK: continue: 125; CHECK-NEXT: br label [[FOR_INC]] 126; CHECK: for.inc: 127; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 128; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP1]] 129; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] 130; CHECK: for.end: 131; CHECK-NEXT: br label [[EXIT:%.*]] 132; CHECK: exit: 133; CHECK-NEXT: ret void 134; 135 i32 %limit, i32 %start) { 136 137for.body.lr.ph: 138 br label %for.body 139 140for.body: 141 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ] 142 %array_length = load i32, i32* %array_length_ptr, !range !{i32 0, i32 64 } 143 %within_limits = icmp ult i32 %i, %array_length 144 br i1 %within_limits, label %continue, label %for.end 145 146continue: 147 %i.i64 = zext i32 %i to i64 148 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64 149 %val = load i32, i32* %arrayidx, align 4 150 br label %for.inc 151 152for.inc: 153 %i.inc = add nsw nuw i32 %i, 1 154 %cmp = icmp slt i32 %i.inc, %limit 155 br i1 %cmp, label %for.body, label %for.end 156 157for.end: 158 br label %exit 159 160exit: 161 ret void 162} 163 164; Negative version of the test above, we don't know anything about 165; array_length_ptr range. 166define void @test_neg(i32* %array_length_ptr, i32* %base, 167; CHECK-LABEL: @test_neg( 168; CHECK-NEXT: for.body.lr.ph: 169; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 170; CHECK-NEXT: br label [[FOR_BODY:%.*]] 171; CHECK: for.body: 172; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] 173; CHECK-NEXT: [[ARRAY_LENGTH:%.*]] = load i32, i32* [[ARRAY_LENGTH_PTR:%.*]], align 4 174; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[ARRAY_LENGTH]] to i64 175; CHECK-NEXT: [[WITHIN_LIMITS:%.*]] = icmp ult i64 [[INDVARS_IV]], [[TMP1]] 176; CHECK-NEXT: br i1 [[WITHIN_LIMITS]], label [[CONTINUE:%.*]], label [[FOR_END:%.*]] 177; CHECK: continue: 178; CHECK-NEXT: br label [[FOR_INC]] 179; CHECK: for.inc: 180; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 181; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 182; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP2]], [[LIMIT:%.*]] 183; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] 184; CHECK: for.end: 185; CHECK-NEXT: br label [[EXIT:%.*]] 186; CHECK: exit: 187; CHECK-NEXT: ret void 188; 189 i32 %limit, i32 %start) { 190 191for.body.lr.ph: 192 br label %for.body 193 194for.body: 195 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ] 196 %array_length = load i32, i32* %array_length_ptr 197 %within_limits = icmp ult i32 %i, %array_length 198 br i1 %within_limits, label %continue, label %for.end 199 200continue: 201 %i.i64 = zext i32 %i to i64 202 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64 203 %val = load i32, i32* %arrayidx, align 4 204 br label %for.inc 205 206for.inc: 207 %i.inc = add nsw nuw i32 %i, 1 208 %cmp = icmp slt i32 %i.inc, %limit 209 br i1 %cmp, label %for.body, label %for.end 210 211for.end: 212 br label %exit 213 214exit: 215 ret void 216} 217 218define void @test_transitive_use(i32* %base, i32 %limit, i32 %start) { 219; CHECK-LABEL: @test_transitive_use( 220; CHECK-NEXT: for.body.lr.ph: 221; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 222; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 223; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[LIMIT]] to i64 224; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[START]], i32 64) 225; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[UMAX]] to i64 226; CHECK-NEXT: br label [[FOR_BODY:%.*]] 227; CHECK: for.body: 228; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] 229; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]] 230; CHECK-NEXT: br i1 [[EXITCOND]], label [[CONTINUE:%.*]], label [[FOR_END:%.*]] 231; CHECK: continue: 232; CHECK-NEXT: [[TMP3:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 3 233; CHECK-NEXT: [[MUL_WITHIN:%.*]] = icmp ult i64 [[TMP3]], 64 234; CHECK-NEXT: br i1 [[MUL_WITHIN]], label [[GUARDED:%.*]], label [[CONTINUE_2:%.*]] 235; CHECK: guarded: 236; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i64 [[TMP3]], 1 237; CHECK-NEXT: [[RESULT:%.*]] = icmp slt i64 [[TMP4]], [[TMP1]] 238; CHECK-NEXT: br i1 [[RESULT]], label [[CONTINUE_2]], label [[FOR_END]] 239; CHECK: continue.2: 240; CHECK-NEXT: br label [[FOR_INC]] 241; CHECK: for.inc: 242; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 243; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP2]] 244; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] 245; CHECK: for.end: 246; CHECK-NEXT: br label [[EXIT:%.*]] 247; CHECK: exit: 248; CHECK-NEXT: ret void 249; 250 251for.body.lr.ph: 252 br label %for.body 253 254for.body: 255 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ] 256 %within_limits = icmp ult i32 %i, 64 257 br i1 %within_limits, label %continue, label %for.end 258 259continue: 260 %i.mul.3 = mul nsw nuw i32 %i, 3 261 %mul_within = icmp ult i32 %i.mul.3, 64 262 br i1 %mul_within, label %guarded, label %continue.2 263 264guarded: 265 %i.mul.3.inc = add nsw nuw i32 %i.mul.3, 1 266 %result = icmp slt i32 %i.mul.3.inc, %limit 267 br i1 %result, label %continue.2, label %for.end 268 269continue.2: 270 %i.i64 = zext i32 %i to i64 271 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64 272 %val = load i32, i32* %arrayidx, align 4 273 br label %for.inc 274 275for.inc: 276 %i.inc = add nsw nuw i32 %i, 1 277 %cmp = icmp slt i32 %i.inc, %limit 278 br i1 %cmp, label %for.body, label %for.end 279 280 281for.end: 282 br label %exit 283 284exit: 285 ret void 286} 287 288declare void @llvm.experimental.guard(i1, ...) 289 290define void @test_guard_one_bb(i32* %base, i32 %limit, i32 %start) { 291; CHECK-LABEL: @test_guard_one_bb( 292; CHECK-NEXT: for.body.lr.ph: 293; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 294; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 295; CHECK-NEXT: br label [[FOR_BODY:%.*]] 296; CHECK: for.body: 297; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] 298; CHECK-NEXT: [[WITHIN_LIMITS:%.*]] = icmp ult i64 [[INDVARS_IV]], 64 299; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_LIMITS]]) [ "deopt"() ] 300; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 301; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP1]] 302; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 303; CHECK: for.end: 304; CHECK-NEXT: br label [[EXIT:%.*]] 305; CHECK: exit: 306; CHECK-NEXT: ret void 307; 308 309for.body.lr.ph: 310 br label %for.body 311 312for.body: 313 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.body ] 314 %within_limits = icmp ult i32 %i, 64 315 %i.i64 = zext i32 %i to i64 316 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64 317 %val = load i32, i32* %arrayidx, align 4 318 call void(i1, ...) @llvm.experimental.guard(i1 %within_limits) [ "deopt"() ] 319 %i.inc = add nsw nuw i32 %i, 1 320 %cmp = icmp slt i32 %i.inc, %limit 321 br i1 %cmp, label %for.body, label %for.end 322 323for.end: 324 br label %exit 325 326exit: 327 ret void 328} 329 330define void @test_guard_in_the_same_bb(i32* %base, i32 %limit, i32 %start) { 331; CHECK-LABEL: @test_guard_in_the_same_bb( 332; CHECK-NEXT: for.body.lr.ph: 333; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 334; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 335; CHECK-NEXT: br label [[FOR_BODY:%.*]] 336; CHECK: for.body: 337; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] 338; CHECK-NEXT: [[WITHIN_LIMITS:%.*]] = icmp ult i64 [[INDVARS_IV]], 64 339; CHECK-NEXT: br label [[FOR_INC]] 340; CHECK: for.inc: 341; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_LIMITS]]) [ "deopt"() ] 342; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 343; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP1]] 344; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 345; CHECK: for.end: 346; CHECK-NEXT: br label [[EXIT:%.*]] 347; CHECK: exit: 348; CHECK-NEXT: ret void 349; 350 351for.body.lr.ph: 352 br label %for.body 353 354for.body: 355 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ] 356 %within_limits = icmp ult i32 %i, 64 357 %i.i64 = zext i32 %i to i64 358 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64 359 %val = load i32, i32* %arrayidx, align 4 360 br label %for.inc 361 362for.inc: 363 call void(i1, ...) @llvm.experimental.guard(i1 %within_limits) [ "deopt"() ] 364 %i.inc = add nsw nuw i32 %i, 1 365 %cmp = icmp slt i32 %i.inc, %limit 366 br i1 %cmp, label %for.body, label %for.end 367 368for.end: 369 br label %exit 370 371exit: 372 ret void 373} 374 375define void @test_guard_in_idom(i32* %base, i32 %limit, i32 %start) { 376; CHECK-LABEL: @test_guard_in_idom( 377; CHECK-NEXT: for.body.lr.ph: 378; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 379; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 380; CHECK-NEXT: br label [[FOR_BODY:%.*]] 381; CHECK: for.body: 382; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] 383; CHECK-NEXT: [[WITHIN_LIMITS:%.*]] = icmp ult i64 [[INDVARS_IV]], 64 384; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_LIMITS]]) [ "deopt"() ] 385; CHECK-NEXT: br label [[FOR_INC]] 386; CHECK: for.inc: 387; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 388; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP1]] 389; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 390; CHECK: for.end: 391; CHECK-NEXT: br label [[EXIT:%.*]] 392; CHECK: exit: 393; CHECK-NEXT: ret void 394; 395 396for.body.lr.ph: 397 br label %for.body 398 399for.body: 400 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ] 401 %within_limits = icmp ult i32 %i, 64 402 call void(i1, ...) @llvm.experimental.guard(i1 %within_limits) [ "deopt"() ] 403 %i.i64 = zext i32 %i to i64 404 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64 405 %val = load i32, i32* %arrayidx, align 4 406 br label %for.inc 407 408for.inc: 409 %i.inc = add nsw nuw i32 %i, 1 410 %cmp = icmp slt i32 %i.inc, %limit 411 br i1 %cmp, label %for.body, label %for.end 412 413for.end: 414 br label %exit 415 416exit: 417 ret void 418} 419 420define void @test_guard_merge_ranges(i32* %base, i32 %limit, i32 %start) { 421; CHECK-LABEL: @test_guard_merge_ranges( 422; CHECK-NEXT: for.body.lr.ph: 423; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 424; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 425; CHECK-NEXT: br label [[FOR_BODY:%.*]] 426; CHECK: for.body: 427; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] 428; CHECK-NEXT: [[WITHIN_LIMITS_1:%.*]] = icmp ult i64 [[INDVARS_IV]], 64 429; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_LIMITS_1]]) [ "deopt"() ] 430; CHECK-NEXT: [[WITHIN_LIMITS_2:%.*]] = icmp ult i64 [[INDVARS_IV]], 2147483647 431; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_LIMITS_2]]) [ "deopt"() ] 432; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 433; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP1]] 434; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 435; CHECK: for.end: 436; CHECK-NEXT: br label [[EXIT:%.*]] 437; CHECK: exit: 438; CHECK-NEXT: ret void 439; 440 441for.body.lr.ph: 442 br label %for.body 443 444for.body: 445 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.body ] 446 %within_limits.1 = icmp ult i32 %i, 64 447 call void(i1, ...) @llvm.experimental.guard(i1 %within_limits.1) [ "deopt"() ] 448 %within_limits.2 = icmp ult i32 %i, 2147483647 449 call void(i1, ...) @llvm.experimental.guard(i1 %within_limits.2) [ "deopt"() ] 450 %i.i64 = zext i32 %i to i64 451 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64 452 %val = load i32, i32* %arrayidx, align 4 453 %i.inc = add nsw nuw i32 %i, 1 454 %cmp = icmp slt i32 %i.inc, %limit 455 br i1 %cmp, label %for.body, label %for.end 456 457for.end: 458 br label %exit 459 460exit: 461 ret void 462} 463