[llvm-commits] [llvm] r123864 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp test/CodeGen/ARM/umulo-32.ll

Matt Beaumont-Gay matthewbg at google.com
Wed Jan 19 17:22:39 PST 2011


On Wed, Jan 19, 2011 at 16:29, Eric Christopher <echristo at apple.com> wrote:
> Author: echristo
> Date: Wed Jan 19 18:29:24 2011
> New Revision: 123864
>
> URL: http://llvm.org/viewvc/llvm-project?rev=123864&view=rev
> Log:
> If we can, lower the multiply part of a umulo/smulo call to a libcall
> with an invalid type then split the result and perform the overflow check
> normally.
>
> Fixes the 32-bit parts of rdar://8622122 and rdar://8774702.
>
> Added:
>    llvm/trunk/test/CodeGen/ARM/umulo-32.ll
> Modified:
>    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=123864&r1=123863&r2=123864&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Jan 19 18:29:24 2011
> @@ -3181,14 +3181,8 @@
>       BottomHalf = DAG.getNode(Ops[isSigned][1], dl, DAG.getVTList(VT, VT), LHS,
>                                RHS);
>       TopHalf = BottomHalf.getValue(1);
> -    } else {
> -      // FIXME: We should be able to fall back to a libcall with an illegal
> -      // type in some cases.
> -      // Also, we can fall back to a division in some cases, but that's a big
> -      // performance hit in the general case.
> -      assert(TLI.isTypeLegal(EVT::getIntegerVT(*DAG.getContext(),
> -                                               VT.getSizeInBits() * 2)) &&
> -             "Don't know how to expand this operation yet!");
> +    } else if (TLI.isTypeLegal(EVT::getIntegerVT(*DAG.getContext(),
> +                                                 VT.getSizeInBits() * 2))) {
>       EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits() * 2);
>       LHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, LHS);
>       RHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, RHS);
> @@ -3197,6 +3191,31 @@
>                                DAG.getIntPtrConstant(0));
>       TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Tmp1,
>                             DAG.getIntPtrConstant(1));
> +    } else {
> +      // We can fall back to a libcall with an illegal type for the MUL if we
> +      // have a libcall big enough.
> +      // Also, we can fall back to a division in some cases, but that's a big
> +      // performance hit in the general case.
> +      EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits() * 2);
> +      RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
> +      if (WideVT == MVT::i16)
> +        LC = RTLIB::MUL_I16;
> +      else if (WideVT == MVT::i32)
> +        LC = RTLIB::MUL_I32;
> +      else if (WideVT == MVT::i64)
> +        LC = RTLIB::MUL_I64;
> +      else if (WideVT == MVT::i128)
> +        LC = RTLIB::MUL_I128;
> +      assert(LC != RTLIB::UNKNOWN_LIBCALL && "Cannot expand this operation!");
> +      LHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, LHS);
> +      RHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, RHS);
> +
> +      SDValue Ops[2] = { LHS, RHS };
> +      SDValue Ret = ExpandLibCall(LC, Node, Ops);

I'm not sure what you were going for here -- ExpandLibCall takes a
bool as the third param, so gcc complains:
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp: 3214: error: the address of
'Ops' will always evaluate as 'true' [-Waddress]

(Also, apparently Clang's -Waddress doesn't catch this case; PR forthcoming.)

> +      BottomHalf = DAG.getNode(ISD::TRUNCATE, dl, VT, Ret);
> +      TopHalf = DAG.getNode(ISD::SRL, dl, Ret.getValueType(), Ret,
> +                       DAG.getConstant(VT.getSizeInBits(), TLI.getPointerTy()));
> +      TopHalf = DAG.getNode(ISD::TRUNCATE, dl, VT, TopHalf);
>     }
>     if (isSigned) {
>       Tmp1 = DAG.getConstant(VT.getSizeInBits() - 1, TLI.getShiftAmountTy());
>
> Added: llvm/trunk/test/CodeGen/ARM/umulo-32.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/umulo-32.ll?rev=123864&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/umulo-32.ll (added)
> +++ llvm/trunk/test/CodeGen/ARM/umulo-32.ll Wed Jan 19 18:29:24 2011
> @@ -0,0 +1,14 @@
> +; RUN: llc < %s -mtriple=thumbv6-apple-darwin | FileCheck %s
> +
> +%umul.ty = type { i32, i1 }
> +
> +define i32 @func(i32 %a) nounwind {
> +; CHECK: func
> +; CHECK: muldi3
> +  %tmp0 = tail call %umul.ty @llvm.umul.with.overflow.i32(i32 %a, i32 37)
> +  %tmp1 = extractvalue %umul.ty %tmp0, 0
> +  %tmp2 = select i1 undef, i32 -1, i32 %tmp1
> +  ret i32 %tmp2
> +}
> +
> +declare %umul.ty @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>




More information about the llvm-commits mailing list