1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=indvars < %s | FileCheck %s --check-prefixes=WIDENING_ON 3; RUN: opt -S -passes=indvars -indvars-widen-indvars=false < %s | FileCheck %s --check-prefixes=WIDENING_OFF 4 5target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2" 6target triple = "x86_64-unknown-linux-gnu" 7 8define void @test_01(i32 %start, i32 %limit) { 9; WIDENING_ON-LABEL: @test_01( 10; WIDENING_ON-NEXT: bb: 11; WIDENING_ON-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 12; WIDENING_ON-NEXT: [[TMP1:%.*]] = add nsw i64 [[TMP0]], -1 13; WIDENING_ON-NEXT: [[TMP2:%.*]] = zext i32 [[LIMIT:%.*]] to i64 14; WIDENING_ON-NEXT: [[RANGE_CHECK_WIDE_FIRST_ITER:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]] 15; WIDENING_ON-NEXT: br label [[LOOP:%.*]] 16; WIDENING_ON: loop: 17; WIDENING_ON-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[BB:%.*]] ] 18; WIDENING_ON-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 19; WIDENING_ON-NEXT: [[NOT_ZERO:%.*]] = icmp ne i64 [[INDVARS_IV]], 0 20; WIDENING_ON-NEXT: [[AND:%.*]] = and i1 [[NOT_ZERO]], [[RANGE_CHECK_WIDE_FIRST_ITER]] 21; WIDENING_ON-NEXT: br i1 [[AND]], label [[BACKEDGE]], label [[EXIT:%.*]] 22; WIDENING_ON: backedge: 23; WIDENING_ON-NEXT: br label [[LOOP]] 24; WIDENING_ON: exit: 25; WIDENING_ON-NEXT: ret void 26; 27; WIDENING_OFF-LABEL: @test_01( 28; WIDENING_OFF-NEXT: bb: 29; WIDENING_OFF-NEXT: [[TMP0:%.*]] = add i32 [[START:%.*]], -1 30; WIDENING_OFF-NEXT: [[RANGE_CHECK_FIRST_ITER:%.*]] = icmp ult i32 [[TMP0]], [[LIMIT:%.*]] 31; WIDENING_OFF-NEXT: br label [[LOOP:%.*]] 32; WIDENING_OFF: loop: 33; WIDENING_OFF-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[START]], [[BB:%.*]] ] 34; WIDENING_OFF-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1 35; WIDENING_OFF-NEXT: [[NOT_ZERO:%.*]] = icmp ne i32 [[IV]], 0 36; WIDENING_OFF-NEXT: [[AND:%.*]] = and i1 [[NOT_ZERO]], [[RANGE_CHECK_FIRST_ITER]] 37; WIDENING_OFF-NEXT: br i1 [[AND]], label [[BACKEDGE]], label [[EXIT:%.*]] 38; WIDENING_OFF: backedge: 39; WIDENING_OFF-NEXT: [[ZEXT:%.*]] = zext i32 [[IV_NEXT]] to i64 40; WIDENING_OFF-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr addrspace(1) poison, i64 [[ZEXT]] 41; WIDENING_OFF-NEXT: br label [[LOOP]] 42; WIDENING_OFF: exit: 43; WIDENING_OFF-NEXT: ret void 44; 45bb: 46 br label %loop 47 48loop: ; preds = %backedge, %bb 49 %iv = phi i32 [ %iv.next, %backedge ], [ %start, %bb ] 50 %iv.next = add i32 %iv, -1 51 %not.zero = icmp ne i32 %iv, 0 52 %range.check = icmp ult i32 %iv.next, %limit 53 %and = and i1 %not.zero, %range.check 54 br i1 %and, label %backedge, label %exit 55 56backedge: ; preds = %loop 57 %zext = zext i32 %iv.next to i64 58 %gep = getelementptr inbounds i32, ptr addrspace(1) poison, i64 %zext 59 br label %loop 60 61exit: ; preds = %loop 62 ret void 63} 64 65define i32 @test_02(i32 %start, i32 %limit) { 66; WIDENING_ON-LABEL: @test_02( 67; WIDENING_ON-NEXT: bb: 68; WIDENING_ON-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 69; WIDENING_ON-NEXT: br label [[LOOP:%.*]] 70; WIDENING_ON: loop: 71; WIDENING_ON-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[BB:%.*]] ] 72; WIDENING_ON-NEXT: [[CANONICAL_IV:%.*]] = phi i32 [ [[CANONICAL_IV_NEXT:%.*]], [[BACKEDGE]] ], [ 0, [[BB]] ] 73; WIDENING_ON-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[CANONICAL_IV]], 65635 74; WIDENING_ON-NEXT: br i1 [[EXITCOND]], label [[CHECKED:%.*]], label [[FAILED:%.*]] 75; WIDENING_ON: checked: 76; WIDENING_ON-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1 77; WIDENING_ON-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 78; WIDENING_ON-NEXT: [[NOT_ZERO:%.*]] = icmp ne i64 [[INDVARS_IV]], 0 79; WIDENING_ON-NEXT: [[TMP2:%.*]] = zext i32 [[LIMIT:%.*]] to i64 80; WIDENING_ON-NEXT: [[RANGE_CHECK_WIDE:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]] 81; WIDENING_ON-NEXT: [[AND:%.*]] = and i1 [[NOT_ZERO]], [[RANGE_CHECK_WIDE]] 82; WIDENING_ON-NEXT: br i1 [[AND]], label [[BACKEDGE]], label [[EXIT:%.*]] 83; WIDENING_ON: backedge: 84; WIDENING_ON-NEXT: [[CANONICAL_IV_NEXT]] = add nuw nsw i32 [[CANONICAL_IV]], 1 85; WIDENING_ON-NEXT: br label [[LOOP]] 86; WIDENING_ON: exit: 87; WIDENING_ON-NEXT: ret i32 0 88; WIDENING_ON: failed: 89; WIDENING_ON-NEXT: ret i32 1 90; 91; WIDENING_OFF-LABEL: @test_02( 92; WIDENING_OFF-NEXT: bb: 93; WIDENING_OFF-NEXT: br label [[LOOP:%.*]] 94; WIDENING_OFF: loop: 95; WIDENING_OFF-NEXT: [[CANONICAL_IV:%.*]] = phi i32 [ [[CANONICAL_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[BB:%.*]] ] 96; WIDENING_OFF-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE]] ], [ [[START:%.*]], [[BB]] ] 97; WIDENING_OFF-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[CANONICAL_IV]], 65635 98; WIDENING_OFF-NEXT: br i1 [[EXITCOND]], label [[CHECKED:%.*]], label [[FAILED:%.*]] 99; WIDENING_OFF: checked: 100; WIDENING_OFF-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1 101; WIDENING_OFF-NEXT: [[NOT_ZERO:%.*]] = icmp ne i32 [[IV]], 0 102; WIDENING_OFF-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i32 [[IV_NEXT]], [[LIMIT:%.*]] 103; WIDENING_OFF-NEXT: [[AND:%.*]] = and i1 [[NOT_ZERO]], [[RANGE_CHECK]] 104; WIDENING_OFF-NEXT: br i1 [[AND]], label [[BACKEDGE]], label [[EXIT:%.*]] 105; WIDENING_OFF: backedge: 106; WIDENING_OFF-NEXT: [[ZEXT:%.*]] = zext i32 [[IV_NEXT]] to i64 107; WIDENING_OFF-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr addrspace(1) poison, i64 [[ZEXT]] 108; WIDENING_OFF-NEXT: [[CANONICAL_IV_NEXT]] = add nuw nsw i32 [[CANONICAL_IV]], 1 109; WIDENING_OFF-NEXT: br label [[LOOP]] 110; WIDENING_OFF: exit: 111; WIDENING_OFF-NEXT: ret i32 0 112; WIDENING_OFF: failed: 113; WIDENING_OFF-NEXT: ret i32 1 114; 115bb: 116 br label %loop 117 118loop: ; preds = %backedge, %bb 119 %canonical_iv = phi i32 [ %canonical_iv.next, %backedge ], [ 0, %bb ] 120 %iv = phi i32 [ %iv.next, %backedge ], [ %start, %bb ] 121 %canonical_iv_check = icmp ult i32 %canonical_iv, 65635 122 br i1 %canonical_iv_check, label %checked, label %failed 123 124checked: 125 %iv.next = add i32 %iv, -1 126 %not.zero = icmp ne i32 %iv, 0 127 %range.check = icmp ult i32 %iv.next, %limit 128 %and = and i1 %not.zero, %range.check 129 br i1 %and, label %backedge, label %exit 130 131backedge: ; preds = %loop 132 %zext = zext i32 %iv.next to i64 133 %gep = getelementptr inbounds i32, ptr addrspace(1) poison, i64 %zext 134 %canonical_iv.next = add i32 %canonical_iv, 1 135 br label %loop 136 137exit: ; preds = %loop 138 ret i32 0 139 140failed: 141 ret i32 1 142} 143