1; RUN: opt < %s -indvars -S | FileCheck %s 2target triple = "aarch64--linux-gnu" 3 4; Check the loop exit i32 compare instruction and operand are widened to i64 5; instead of truncating IV before its use in the i32 compare instruction. 6 7@idx = common global i32 0, align 4 8@e = common global i32 0, align 4 9@ptr = common global i32* null, align 8 10 11; CHECK-LABEL: @test1 12; CHECK: for.body.lr.ph: 13; CHECK: sext i32 14; CHECK: for.cond: 15; CHECK: icmp slt i64 16; CHECK: for.body: 17; CHECK: phi i64 18 19define i32 @test1() { 20entry: 21 store i32 -1, i32* @idx, align 4 22 %0 = load i32* @e, align 4 23 %cmp4 = icmp slt i32 %0, 0 24 br i1 %cmp4, label %for.end.loopexit, label %for.body.lr.ph 25 26for.body.lr.ph: 27 %1 = load i32** @ptr, align 8 28 %2 = load i32* @e, align 4 29 br label %for.body 30 31for.cond: 32 %inc = add nsw i32 %i.05, 1 33 %cmp = icmp slt i32 %i.05, %2 34 br i1 %cmp, label %for.body, label %for.cond.for.end.loopexit_crit_edge 35 36for.body: 37 %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.cond ] 38 %idxprom = sext i32 %i.05 to i64 39 %arrayidx = getelementptr inbounds i32* %1, i64 %idxprom 40 %3 = load i32* %arrayidx, align 4 41 %tobool = icmp eq i32 %3, 0 42 br i1 %tobool, label %if.then, label %for.cond 43 44if.then: 45 %i.05.lcssa = phi i32 [ %i.05, %for.body ] 46 store i32 %i.05.lcssa, i32* @idx, align 4 47 br label %for.end 48 49for.cond.for.end.loopexit_crit_edge: 50 br label %for.end.loopexit 51 52for.end.loopexit: 53 br label %for.end 54 55for.end: 56 %4 = load i32* @idx, align 4 57 ret i32 %4 58} 59 60; CHECK-LABEL: @test2 61; CHECK: for.body4.us 62; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 63; CHECK: %cmp2.us = icmp slt i64 64; CHECK-NOT: %2 = trunc i64 %indvars.iv.next to i32 65; CHECK-NOT: %cmp2.us = icmp slt i32 66 67define void @test2([8 x i8]* %a, i8* %b, i8 %limit) { 68entry: 69 %conv = zext i8 %limit to i32 70 br i1 undef, label %for.cond1.preheader, label %for.cond1.preheader.us 71 72for.cond1.preheader.us: 73 %storemerge5.us = phi i32 [ 0, %entry ], [ %inc14.us, %for.inc13.us ] 74 br i1 true, label %for.body4.lr.ph.us, label %for.inc13.us 75 76for.inc13.us: 77 %inc14.us = add nsw i32 %storemerge5.us, 1 78 %cmp.us = icmp slt i32 %inc14.us, 4 79 br i1 %cmp.us, label %for.cond1.preheader.us, label %for.end 80 81for.body4.us: 82 %storemerge14.us = phi i32 [ 0, %for.body4.lr.ph.us ], [ %inc.us, %for.body4.us ] 83 %idxprom.us = sext i32 %storemerge14.us to i64 84 %arrayidx6.us = getelementptr inbounds [8 x i8]* %a, i64 %idxprom5.us, i64 %idxprom.us 85 %0 = load i8* %arrayidx6.us, align 1 86 %idxprom7.us = zext i8 %0 to i64 87 %arrayidx8.us = getelementptr inbounds i8* %b, i64 %idxprom7.us 88 %1 = load i8* %arrayidx8.us, align 1 89 store i8 %1, i8* %arrayidx6.us, align 1 90 %inc.us = add nsw i32 %storemerge14.us, 1 91 %cmp2.us = icmp slt i32 %inc.us, %conv 92 br i1 %cmp2.us, label %for.body4.us, label %for.inc13.us 93 94for.body4.lr.ph.us: 95 %idxprom5.us = sext i32 %storemerge5.us to i64 96 br label %for.body4.us 97 98for.cond1.preheader: 99 %storemerge5 = phi i32 [ 0, %entry ], [ %inc14, %for.inc13 ] 100 br i1 false, label %for.inc13, label %for.inc13 101 102for.inc13: 103 %inc14 = add nsw i32 %storemerge5, 1 104 %cmp = icmp slt i32 %inc14, 4 105 br i1 %cmp, label %for.cond1.preheader, label %for.end 106 107for.end: 108 ret void 109} 110 111; CHECK-LABEL: @test3 112; CHECK: sext i32 %b 113; CHECK: for.cond: 114; CHECK: phi i64 115; CHECK: icmp slt i64 116 117define i32 @test3(i32* %a, i32 %b) { 118entry: 119 br label %for.cond 120 121for.cond: 122 %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ] 123 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 124 %cmp = icmp slt i32 %i.0, %b 125 br i1 %cmp, label %for.body, label %for.end 126 127for.body: 128 %idxprom = sext i32 %i.0 to i64 129 %arrayidx = getelementptr inbounds i32* %a, i64 %idxprom 130 %0 = load i32* %arrayidx, align 4 131 %add = add nsw i32 %sum.0, %0 132 %inc = add nsw i32 %i.0, 1 133 br label %for.cond 134 135for.end: 136 ret i32 %sum.0 137} 138 139declare i32 @fn1(i8 signext) 140 141; PR21030 142; CHECK-LABEL: @test4 143; CHECK: for.body: 144; CHECK: phi i32 145; CHECK: icmp sgt i8 146 147define i32 @test4(i32 %a) { 148entry: 149 br label %for.body 150 151for.body: 152 %c.07 = phi i8 [ -3, %entry ], [ %dec, %for.body ] 153 %conv6 = zext i8 %c.07 to i32 154 %or = or i32 %a, %conv6 155 %conv3 = trunc i32 %or to i8 156 %call = call i32 @fn1(i8 signext %conv3) 157 %dec = add i8 %c.07, -1 158 %cmp = icmp sgt i8 %dec, -14 159 br i1 %cmp, label %for.body, label %for.end 160 161for.end: 162 ret i32 0 163} 164 165; CHECK-LABEL: @test5 166; CHECK: zext i32 %b 167; CHECK: for.cond: 168; CHECK: phi i64 169; CHECK: icmp ule i64 170 171define i32 @test5(i32* %a, i32 %b) { 172entry: 173 br label %for.cond 174 175for.cond: 176 %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ] 177 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 178 %cmp = icmp ule i32 %i.0, %b 179 br i1 %cmp, label %for.body, label %for.end 180 181for.body: 182 %idxprom = zext i32 %i.0 to i64 183 %arrayidx = getelementptr inbounds i32* %a, i64 %idxprom 184 %0 = load i32* %arrayidx, align 4 185 %add = add nsw i32 %sum.0, %0 186 %inc = add nsw i32 %i.0, 1 187 br label %for.cond 188 189for.end: 190 ret i32 %sum.0 191} 192