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. 5 target datalayout = "n8:16:32:64" 6 7 8 target triple = "x86_64-apple-darwin" 9 10 declare 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 22 define void @loop_0(i32* %a) { 23 Prologue: 24 br i1 undef, label %B18, label %B6 25 26 B18: ; 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 36 B24: ; preds = %B18 37 %t2 = icmp eq i32 %tmp33, 20 38 br i1 %t2, label %B6, label %B18 39 40 B6: ; preds = %Prologue 41 ret void 42 43 exit24: ; 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 53 define void @loop_0.dead(i32* %a) { 54 Prologue: 55 br i1 undef, label %B18, label %B6 56 57 B18: ; 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 66 B24: ; preds = %B18 67 %t2 = icmp eq i32 %tmp33, 20 68 br i1 %t2, label %B6, label %B18 69 70 B6: ; preds = %Prologue 71 ret void 72 73 exit24: ; preds = %B18 74 call void @dummy(i32 %.02) 75 unreachable 76 } 77 78 define 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 103 declare void @dummy(i32) 104 declare void @dummy.i64(i64) 105 106 107 define void @loop_2(i32 %size, i32 %nsteps, i32 %hsize, i32* %lined, i8 %tmp1) { 108 ; CHECK-LABEL: @loop_2( 109 entry: 110 %cmp215 = icmp sgt i32 %size, 1 111 %tmp0 = bitcast i32* %lined to i8* 112 br label %for.body 113 114 for.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]] 126 for.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]] 143 for.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 153 for.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 158 for.end.loopexit: 159 ret void 160 } 161