Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -8278,6 +8278,30 @@ const APInt &L = LC->getAPInt(); const APInt &M = MC->getAPInt(); const APInt &N = NC->getAPInt(); + + // If the bit width is 1, then the arithmetic is a bit different. + if (BitWidth == 1) { + // Normally, the increments are M+N, M+2N, ... + // Here they are M+N, M, M+N, etc., so the accumulated values are + // L+M+N, L+N, L+M, L, and these four values will repeat. + bool BL = !L.isNullValue(), BM = !M.isNullValue(), BN = !N.isNullValue(); + int Iter; + + if (!(BL ^ BM ^ BN)) + Iter = 0; // e.g. L=N, M=0 + else if (!(BL ^ BN)) + Iter = 1; // e.g. L=N, M=1 + else if (!(BL ^ BM)) + Iter = 2; // e.g. L=0, M=0, N=1 + else if (!BL) + Iter = 3; // e.g. L=0, M=1, N=1 + else + return None; + + const auto *Root = cast(SE.getConstant(APInt(32, Iter))); + return std::make_pair(Root, Root); + } + APInt Two(BitWidth, 2); // Convert from chrec coefficients to polynomial coefficients AX^2+BX+C Index: test/Analysis/ScalarEvolution/solve-quadratic-i1.ll =================================================================== --- /dev/null +++ test/Analysis/ScalarEvolution/solve-quadratic-i1.ll @@ -0,0 +1,39 @@ +; RUN: opt -analyze -scalar-evolution -S < %s | FileCheck %s + +; CHECK: Printing analysis 'Scalar Evolution Analysis' for function 'f1': +; CHECK-NEXT: Classifying expressions for: @f1 +; CHECK-NEXT: %a.0 = phi i16 [ 2, %entry ], [ %inc, %lbl1 ] +; CHECK-NEXT: --> {2,+,1}<%lbl1> U: [2,-32768) S: [2,-32768) Exits: 3 LoopDispositions: { %lbl1: Computable } +; CHECK-NEXT: %b.0 = phi i16 [ 1, %entry ], [ %add, %lbl1 ] +; CHECK-NEXT: --> {1,+,2,+,1}<%lbl1> U: full-set S: full-set Exits: 3 LoopDispositions: { %lbl1: Computable } +; CHECK-NEXT: %inc = add nsw i16 %a.0, 1 +; CHECK-NEXT: --> {3,+,1}<%lbl1> U: [3,0) S: [3,0) Exits: 4 LoopDispositions: { %lbl1: Computable } +; CHECK-NEXT: %add = add nsw i16 %b.0, %a.0 +; CHECK-NEXT: --> {3,+,3,+,1}<%lbl1> U: full-set S: full-set Exits: 6 LoopDispositions: { %lbl1: Computable } +; CHECK-NEXT: %and = and i16 %add, 1 +; CHECK-NEXT: --> (zext i1 {true,+,true,+,true}<%lbl1> to i16) U: [0,2) S: [0,2) Exits: 0 LoopDispositions: { %lbl1: Computable } +; CHECK-NEXT: Determining loop execution counts for: @f1 +; CHECK-NEXT: Loop %lbl1: backedge-taken count is 1 +; CHECK-NEXT: Loop %lbl1: max backedge-taken count is 1 +; CHECK-NEXT: Loop %lbl1: Predicated backedge-taken count is 1 +; CHECK-NEXT: Predicates: +; CHECK: Loop %lbl1: Trip multiple is 2 + +target triple = "x86_64-unknown-linux-gnu" + +define void @f1() { +entry: + br label %lbl1 + +lbl1: ; preds = %lbl1, %entry + %a.0 = phi i16 [ 2, %entry ], [ %inc, %lbl1 ] + %b.0 = phi i16 [ 1, %entry ], [ %add, %lbl1 ] + %inc = add nsw i16 %a.0, 1 + %add = add nsw i16 %b.0, %a.0 + %and = and i16 %add, 1 + %tobool = icmp ne i16 %and, 0 + br i1 %tobool, label %lbl1, label %if.end + +if.end: ; preds = %lbl1 + ret void +}