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