1; RUN: opt < %s -indvars -S | FileCheck %s 2; RUN: opt -lcssa -loop-simplify -S < %s | opt -S -passes='require<targetir>,require<scalar-evolution>,require<domtree>,loop(indvars)' 3 4; Provide legal integer types. 5target datalayout = "n8:16:32:64" 6 7 8target triple = "x86_64-apple-darwin" 9 10declare void @use(i64 %x) 11 12; CHECK-LABEL: @loop_0 13; CHECK-LABEL: B18: 14; Only one phi now. 15; CHECK: phi i64 16; CHECK-NOT: phi 17; One trunc for the gep. 18; CHECK: trunc i64 %indvars.iv to i32 19; One trunc for the dummy() call. 20; CHECK-LABEL: exit24: 21; CHECK: trunc i64 {{.*}}lcssa.wide to i32 22define void @loop_0(i32* %a) { 23Prologue: 24 br i1 undef, label %B18, label %B6 25 26B18: ; preds = %B24, %Prologue 27 %.02 = phi i32 [ 0, %Prologue ], [ %tmp33, %B24 ] 28 %tmp23 = zext i32 %.02 to i64 29 call void @use(i64 %tmp23) 30 %tmp33 = add i32 %.02, 1 31 %o = getelementptr i32, i32* %a, i32 %.02 32 %v = load i32, i32* %o 33 %t = icmp eq i32 %v, 0 34 br i1 %t, label %exit24, label %B24 35 36B24: ; preds = %B18 37 %t2 = icmp eq i32 %tmp33, 20 38 br i1 %t2, label %B6, label %B18 39 40B6: ; preds = %Prologue 41 ret void 42 43exit24: ; preds = %B18 44 call void @dummy(i32 %.02) 45 unreachable 46} 47 48; Make sure that dead zext is removed and no widening happens. 49; CHECK-LABEL: @loop_0.dead 50; CHECK: phi i32 51; CHECK-NOT: zext 52; CHECK-NOT: trunc 53define void @loop_0.dead(i32* %a) { 54Prologue: 55 br i1 undef, label %B18, label %B6 56 57B18: ; preds = %B24, %Prologue 58 %.02 = phi i32 [ 0, %Prologue ], [ %tmp33, %B24 ] 59 %tmp23 = zext i32 %.02 to i64 60 %tmp33 = add i32 %.02, 1 61 %o = getelementptr i32, i32* %a, i32 %.02 62 %v = load i32, i32* %o 63 %t = icmp eq i32 %v, 0 64 br i1 %t, label %exit24, label %B24 65 66B24: ; preds = %B18 67 %t2 = icmp eq i32 %tmp33, 20 68 br i1 %t2, label %B6, label %B18 69 70B6: ; preds = %Prologue 71 ret void 72 73exit24: ; preds = %B18 74 call void @dummy(i32 %.02) 75 unreachable 76} 77 78define void @loop_1(i32 %lim) { 79; CHECK-LABEL: @loop_1( 80 entry: 81 %entry.cond = icmp ne i32 %lim, 0 82 br i1 %entry.cond, label %loop, label %leave 83 84 loop: 85; CHECK: loop: 86; CHECK: %indvars.iv = phi i64 [ 1, %loop.preheader ], [ %indvars.iv.next, %loop ] 87; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 88; CHECK: [[IV_INC:%[^ ]+]] = add nsw i64 %indvars.iv, -1 89; CHECK: call void @dummy.i64(i64 [[IV_INC]]) 90 91 %iv = phi i32 [ 1, %entry ], [ %iv.inc, %loop ] 92 %iv.inc = add i32 %iv, 1 93 %iv.inc.sub = add i32 %iv, -1 94 %iv.inc.sub.zext = zext i32 %iv.inc.sub to i64 95 call void @dummy.i64(i64 %iv.inc.sub.zext) 96 %be.cond = icmp ult i32 %iv.inc, %lim 97 br i1 %be.cond, label %loop, label %leave 98 99 leave: 100 ret void 101} 102 103declare void @dummy(i32) 104declare void @dummy.i64(i64) 105 106 107define void @loop_2(i32 %size, i32 %nsteps, i32 %hsize, i32* %lined, i8 %tmp1) { 108; CHECK-LABEL: @loop_2( 109entry: 110 %cmp215 = icmp sgt i32 %size, 1 111 %tmp0 = bitcast i32* %lined to i8* 112 br label %for.body 113 114for.body: 115 %j = phi i32 [ 0, %entry ], [ %inc6, %for.inc ] 116 %mul = mul nsw i32 %j, %size 117 %add = add nsw i32 %mul, %hsize 118 br i1 %cmp215, label %for.body2, label %for.inc 119 120; check that the induction variable of the inner loop has been widened after indvars. 121; CHECK: [[INNERLOOPINV:%[^ ]+]] = add nsw i64 122; CHECK: for.body2: 123; CHECK-NEXT: %indvars.iv = phi i64 [ 1, %for.body2.preheader ], [ %indvars.iv.next, %for.body2 ] 124; CHECK-NEXT: [[WIDENED:%[^ ]+]] = add nsw i64 [[INNERLOOPINV]], %indvars.iv 125; CHECK-NEXT: %add.ptr = getelementptr inbounds i8, i8* %tmp0, i64 [[WIDENED]] 126for.body2: 127 %k = phi i32 [ %inc, %for.body2 ], [ 1, %for.body ] 128 %add4 = add nsw i32 %add, %k 129 %idx.ext = sext i32 %add4 to i64 130 %add.ptr = getelementptr inbounds i8, i8* %tmp0, i64 %idx.ext 131 store i8 %tmp1, i8* %add.ptr, align 1 132 %inc = add nsw i32 %k, 1 133 %cmp2 = icmp slt i32 %inc, %size 134 br i1 %cmp2, label %for.body2, label %for.body3 135 136; check that the induction variable of the inner loop has been widened after indvars. 137; CHECK: for.body3.preheader: 138; CHECK: [[INNERLOOPINV:%[^ ]+]] = zext i32 139; CHECK: for.body3: 140; CHECK-NEXT: %indvars.iv2 = phi i64 [ 1, %for.body3.preheader ], [ %indvars.iv.next3, %for.body3 ] 141; CHECK-NEXT: [[WIDENED:%[^ ]+]] = add nuw nsw i64 [[INNERLOOPINV]], %indvars.iv2 142; CHECK-NEXT: %add.ptr2 = getelementptr inbounds i8, i8* %tmp0, i64 [[WIDENED]] 143for.body3: 144 %l = phi i32 [ %inc2, %for.body3 ], [ 1, %for.body2 ] 145 %add5 = add nuw i32 %add, %l 146 %idx.ext2 = zext i32 %add5 to i64 147 %add.ptr2 = getelementptr inbounds i8, i8* %tmp0, i64 %idx.ext2 148 store i8 %tmp1, i8* %add.ptr2, align 1 149 %inc2 = add nsw i32 %l, 1 150 %cmp3 = icmp slt i32 %inc2, %size 151 br i1 %cmp3, label %for.body3, label %for.inc 152 153for.inc: 154 %inc6 = add nsw i32 %j, 1 155 %cmp = icmp slt i32 %inc6, %nsteps 156 br i1 %cmp, label %for.body, label %for.end.loopexit 157 158for.end.loopexit: 159 ret void 160} 161