[llvm] r340480 - [ValueTracking] Teach computeNumSignBits to understand min/max clamp patterns with constant/splat values

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 23 10:17:23 PDT 2018


Hopefully fixed after r340546. Sorry for the trouble.

~Craig


On Thu, Aug 23, 2018 at 9:05 AM Maxim Kuvyrkov via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Hi Craig,
>
> After this commit clang crashes when building linux kernel on aarch64.
> Grep for "ValueTracking.cpp" in
> https://ci.linaro.org/view/tcwg-ci/job/tcwg-rr-llvm-kernel-aarch64/1897/artifact/artifacts/linux.build/*view*/
> .
>
> This is from CI we are deploying at Linaro, and it had been working for
> just couple of days.
>
> Ping me on IRC (maximk) and I'll help you reproduce.
>
> For reference, bisection job:
> https://ci.linaro.org/view/tcwg-ci/job/tcwg-bisect-llvm-kernel-aarch64/4/console
> .
>
> --
> Maxim Kuvyrkov
> www.linaro.org
>
>
>
> > On Aug 23, 2018, at 2:27 AM, Craig Topper via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
> >
> > Author: ctopper
> > Date: Wed Aug 22 16:27:50 2018
> > New Revision: 340480
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=340480&view=rev
> > Log:
> > [ValueTracking] Teach computeNumSignBits to understand min/max clamp
> patterns with constant/splat values
> >
> > If we have a min/max pair we can do a better job of counting sign bits
> if we look at them together. This is similar to what is done in the
> SelectionDAG version of computeNumSignBits for ISD::SMAX/SMIN.
> >
> > Differential Revision: https://reviews.llvm.org/D51112
> >
> > Modified:
> >    llvm/trunk/lib/Analysis/ValueTracking.cpp
> >    llvm/trunk/test/Transforms/InstCombine/max_known_bits.ll
> >
> > Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=340480&r1=340479&r2=340480&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
> > +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Wed Aug 22 16:27:50 2018
> > @@ -2209,6 +2209,34 @@ bool MaskedValueIsZero(const Value *V, c
> >   return Mask.isSubsetOf(Known.Zero);
> > }
> >
> > +// Match a signed min+max clamp pattern like smax(smin(In, CHigh),
> CLow).
> > +// Returns the input and lower/upper bounds.
> > +static bool isSignedMinMaxClamp(const Value *Select, const Value *&In,
> > +                                const APInt *&CLow, const APInt
> *&CHigh) {
> > +  assert(isa<SelectInst>(Select) && "Input should be a SelectInst!");
> > +
> > +  const Value *LHS, *RHS, *LHS2, *RHS2;
> > +  SelectPatternFlavor SPF = matchSelectPattern(Select, LHS, RHS).Flavor;
> > +  if (SPF != SPF_SMAX && SPF != SPF_SMIN)
> > +    return false;
> > +
> > +  if (!match(RHS, m_APInt(CLow)))
> > +    return false;
> > +
> > +  SelectPatternFlavor SPF2 = matchSelectPattern(LHS, LHS2, RHS2).Flavor;
> > +  if (getInverseMinMaxFlavor(SPF) != SPF2)
> > +    return false;
> > +
> > +  if (!match(RHS2, m_APInt(CHigh)))
> > +    return false;
> > +
> > +  if (SPF == SPF_SMIN)
> > +    std::swap(CLow, CHigh);
> > +
> > +  In = LHS2;
> > +  return CLow->sle(*CHigh);
> > +}
> > +
> > /// For vector constants, loop over the elements and find the constant
> with the
> > /// minimum number of sign bits. Return 0 if the value is not a vector
> constant
> > /// or if any element was not analyzed; otherwise, return the count for
> the
> > @@ -2370,11 +2398,19 @@ static unsigned ComputeNumSignBitsImpl(c
> >     }
> >     break;
> >
> > -  case Instruction::Select:
> > +  case Instruction::Select: {
> > +    // If we have a clamp pattern, we know that the number of sign bits
> will be
> > +    // the minimum of the clamp min/max range.
> > +    const Value *X;
> > +    const APInt *CLow, *CHigh;
> > +    if (isSignedMinMaxClamp(U, X, CLow, CHigh))
> > +      return std::min(CLow->getNumSignBits(), CHigh->getNumSignBits());
> > +
> >     Tmp = ComputeNumSignBits(U->getOperand(1), Depth + 1, Q);
> >     if (Tmp == 1) break;
> >     Tmp2 = ComputeNumSignBits(U->getOperand(2), Depth + 1, Q);
> >     return std::min(Tmp, Tmp2);
> > +  }
> >
> >   case Instruction::Add:
> >     // Add can have at most one carry bit.  Thus we know that the output
> >
> > Modified: llvm/trunk/test/Transforms/InstCombine/max_known_bits.ll
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/max_known_bits.ll?rev=340480&r1=340479&r2=340480&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/test/Transforms/InstCombine/max_known_bits.ll (original)
> > +++ llvm/trunk/test/Transforms/InstCombine/max_known_bits.ll Wed Aug 22
> 16:27:50 2018
> > @@ -17,3 +17,81 @@ define i16 @foo(i16 %x)  {
> >   ret i16 %t6
> > }
> >
> > +; This contains a min/max pair to clamp a value to 12 bits.
> > +; By analyzing the clamp pattern, we can tell the add doesn't have
> signed overflow.
> > +define i16 @min_max_clamp(i16 %x) {
> > +; CHECK-LABEL: @min_max_clamp(
> > +; CHECK-NEXT:    [[A:%.*]] = icmp sgt i16 [[X:%.*]], -2048
> > +; CHECK-NEXT:    [[B:%.*]] = select i1 [[A]], i16 [[X]], i16 -2048
> > +; CHECK-NEXT:    [[C:%.*]] = icmp slt i16 [[B]], 2047
> > +; CHECK-NEXT:    [[D:%.*]] = select i1 [[C]], i16 [[B]], i16 2047
> > +; CHECK-NEXT:    [[E:%.*]] = add nsw i16 [[D]], 1
> > +; CHECK-NEXT:    ret i16 [[E]]
> > +;
> > +  %a = icmp sgt i16 %x, -2048
> > +  %b = select i1 %a, i16 %x, i16 -2048
> > +  %c = icmp slt i16 %b, 2047
> > +  %d = select i1 %c, i16 %b, i16 2047
> > +  %e = add i16 %d, 1
> > +  ret i16 %e
> > +}
> > +
> > +; Same as above with min/max reversed.
> > +define i16 @min_max_clamp_2(i16 %x) {
> > +; CHECK-LABEL: @min_max_clamp_2(
> > +; CHECK-NEXT:    [[A:%.*]] = icmp slt i16 [[X:%.*]], 2047
> > +; CHECK-NEXT:    [[B:%.*]] = select i1 [[A]], i16 [[X]], i16 2047
> > +; CHECK-NEXT:    [[C:%.*]] = icmp sgt i16 [[B]], -2048
> > +; CHECK-NEXT:    [[D:%.*]] = select i1 [[C]], i16 [[B]], i16 -2048
> > +; CHECK-NEXT:    [[E:%.*]] = add nsw i16 [[D]], 1
> > +; CHECK-NEXT:    ret i16 [[E]]
> > +;
> > +  %a = icmp slt i16 %x, 2047
> > +  %b = select i1 %a, i16 %x, i16 2047
> > +  %c = icmp sgt i16 %b, -2048
> > +  %d = select i1 %c, i16 %b, i16 -2048
> > +  %e = add i16 %d, 1
> > +  ret i16 %e
> > +}
> > +
> > +; This contains a min/max pair to clamp a value to 12 bits.
> > +; By analyzing the clamp pattern, we can tell that the second add
> doesn't
> > +; overflow the original type and can be moved before the extend.
> > +define i32 @min_max_clamp_3(i16 %x) {
> > +; CHECK-LABEL: @min_max_clamp_3(
> > +; CHECK-NEXT:    [[A:%.*]] = icmp sgt i16 [[X:%.*]], -2048
> > +; CHECK-NEXT:    [[B:%.*]] = select i1 [[A]], i16 [[X]], i16 -2048
> > +; CHECK-NEXT:    [[C:%.*]] = icmp slt i16 [[B]], 2047
> > +; CHECK-NEXT:    [[D:%.*]] = select i1 [[C]], i16 [[B]], i16 2047
> > +; CHECK-NEXT:    [[G:%.*]] = sext i16 [[D]] to i32
> > +; CHECK-NEXT:    ret i32 [[G]]
> > +;
> > +  %a = icmp sgt i16 %x, -2048
> > +  %b = select i1 %a, i16 %x, i16 -2048
> > +  %c = icmp slt i16 %b, 2047
> > +  %d = select i1 %c, i16 %b, i16 2047
> > +  %e = add i16 %d, 1
> > +  %f = sext i16 %e to i32
> > +  %g = add i32 %f, -1
> > +  ret i32 %g
> > +}
> > +
> > +; Same as above with min/max order reversed
> > +define i32 @min_max_clamp_4(i16 %x) {
> > +; CHECK-LABEL: @min_max_clamp_4(
> > +; CHECK-NEXT:    [[A:%.*]] = icmp slt i16 [[X:%.*]], 2047
> > +; CHECK-NEXT:    [[B:%.*]] = select i1 [[A]], i16 [[X]], i16 2047
> > +; CHECK-NEXT:    [[C:%.*]] = icmp sgt i16 [[B]], -2048
> > +; CHECK-NEXT:    [[D:%.*]] = select i1 [[C]], i16 [[B]], i16 -2048
> > +; CHECK-NEXT:    [[G:%.*]] = sext i16 [[D]] to i32
> > +; CHECK-NEXT:    ret i32 [[G]]
> > +;
> > +  %a = icmp slt i16 %x, 2047
> > +  %b = select i1 %a, i16 %x, i16 2047
> > +  %c = icmp sgt i16 %b, -2048
> > +  %d = select i1 %c, i16 %b, i16 -2048
> > +  %e = add i16 %d, 1
> > +  %f = sext i16 %e to i32
> > +  %g = add i32 %f, -1
> > +  ret i32 %g
> > +}
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180823/6dca5bc5/attachment.html>


More information about the llvm-commits mailing list