[llvm] r181842 - ARM ISel: Don't create illegal types during LowerMUL

Bill Wendling wendling at apple.com
Wed May 15 17:07:14 PDT 2013


Got it. Thanks! :)

-bw

On May 15, 2013, at 1:21 AM, Renato Golin <renato.golin at linaro.org> wrote:

> Hi Bill, this is the last patch to fix all 3.3 rc1 problems, which should give us a clean rc2 on ARM.
> 
> Cheers, 
> Renato
> 
> On 15 May 2013 01:31, "Arnold Schwaighofer" <aschwaighofer at apple.com> wrote:
> Author: arnolds
> Date: Tue May 14 17:33:24 2013
> New Revision: 181842
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=181842&view=rev
> Log:
> ARM ISel: Don't create illegal types during LowerMUL
> 
> The transformation happening here is that we want to turn a
> "mul(ext(X), ext(X))" into a "vmull(X, X)", stripping off the extension. We have
> to make sure that X still has a valid vector type - possibly recreate an
> extension to a smaller type. In case of a extload of a memory type smaller than
> 64 bit we used create a ext(load()). The problem with doing this - instead of
> recreating an extload - is that an illegal type is exposed.
> 
> This patch fixes this by creating extloads instead of ext(load()) sequences.
> 
> Fixes PR15970.
> 
> radar://13871383
> 
> Modified:
>     llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
>     llvm/trunk/test/CodeGen/ARM/vmul.ll
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=181842&r1=181841&r2=181842&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue May 14 17:33:24 2013
> @@ -5257,6 +5257,23 @@ static bool isZeroExtended(SDNode *N, Se
>    return false;
>  }
> 
> +static EVT getExtensionTo64Bits(const EVT &OrigVT) {
> +  if (OrigVT.getSizeInBits() >= 64)
> +    return OrigVT;
> +
> +  assert(OrigVT.isSimple() && "Expecting a simple value type");
> +
> +  MVT::SimpleValueType OrigSimpleTy = OrigVT.getSimpleVT().SimpleTy;
> +  switch (OrigSimpleTy) {
> +  default: llvm_unreachable("Unexpected Vector Type");
> +  case MVT::v2i8:
> +  case MVT::v2i16:
> +     return MVT::v2i32;
> +  case MVT::v4i8:
> +    return  MVT::v4i16;
> +  }
> +}
> +
>  /// AddRequiredExtensionForVMULL - Add a sign/zero extension to extend the total
>  /// value size to 64 bits. We need a 64-bit D register as an operand to VMULL.
>  /// We insert the required extension here to get the vector to fill a D register.
> @@ -5272,18 +5289,8 @@ static SDValue AddRequiredExtensionForVM
>      return N;
> 
>    // Must extend size to at least 64 bits to be used as an operand for VMULL.
> -  MVT::SimpleValueType OrigSimpleTy = OrigTy.getSimpleVT().SimpleTy;
> -  EVT NewVT;
> -  switch (OrigSimpleTy) {
> -  default: llvm_unreachable("Unexpected Orig Vector Type");
> -  case MVT::v2i8:
> -  case MVT::v2i16:
> -    NewVT = MVT::v2i32;
> -    break;
> -  case MVT::v4i8:
> -    NewVT = MVT::v4i16;
> -    break;
> -  }
> +  EVT NewVT = getExtensionTo64Bits(OrigTy);
> +
>    return DAG.getNode(ExtOpcode, N->getDebugLoc(), NewVT, N);
>  }
> 
> @@ -5293,22 +5300,22 @@ static SDValue AddRequiredExtensionForVM
>  /// reach a total size of 64 bits. We have to add the extension separately
>  /// because ARM does not have a sign/zero extending load for vectors.
>  static SDValue SkipLoadExtensionForVMULL(LoadSDNode *LD, SelectionDAG& DAG) {
> -  SDValue NonExtendingLoad =
> -    DAG.getLoad(LD->getMemoryVT(), LD->getDebugLoc(), LD->getChain(),
> +  EVT ExtendedTy = getExtensionTo64Bits(LD->getMemoryVT());
> +
> +  // The load already has the right type.
> +  if (ExtendedTy == LD->getMemoryVT())
> +    return DAG.getLoad(LD->getMemoryVT(), LD->getDebugLoc(), LD->getChain(),
>                  LD->getBasePtr(), LD->getPointerInfo(), LD->isVolatile(),
>                  LD->isNonTemporal(), LD->isInvariant(),
>                  LD->getAlignment());
> -  unsigned ExtOp = 0;
> -  switch (LD->getExtensionType()) {
> -  default: llvm_unreachable("Unexpected LoadExtType");
> -  case ISD::EXTLOAD:
> -  case ISD::SEXTLOAD: ExtOp = ISD::SIGN_EXTEND; break;
> -  case ISD::ZEXTLOAD: ExtOp = ISD::ZERO_EXTEND; break;
> -  }
> -  MVT::SimpleValueType MemType = LD->getMemoryVT().getSimpleVT().SimpleTy;
> -  MVT::SimpleValueType ExtType = LD->getValueType(0).getSimpleVT().SimpleTy;
> -  return AddRequiredExtensionForVMULL(NonExtendingLoad, DAG,
> -                                      MemType, ExtType, ExtOp);
> +
> +  // We need to create a zextload/sextload. We cannot just create a load
> +  // followed by a zext/zext node because LowerMUL is also run during normal
> +  // operation legalization where we can't create illegal types.
> +  return DAG.getExtLoad(LD->getExtensionType(), LD->getDebugLoc(), ExtendedTy,
> +                        LD->getChain(), LD->getBasePtr(), LD->getPointerInfo(),
> +                        LD->getMemoryVT(), LD->isVolatile(),
> +                        LD->isNonTemporal(), LD->getAlignment());
>  }
> 
>  /// SkipExtensionForVMULL - For a node that is a SIGN_EXTEND, ZERO_EXTEND,
> 
> Modified: llvm/trunk/test/CodeGen/ARM/vmul.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vmul.ll?rev=181842&r1=181841&r2=181842&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/vmul.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/vmul.ll Tue May 14 17:33:24 2013
> @@ -599,3 +599,27 @@ for.end179:
>  declare <8 x i16> @llvm.arm.neon.vrshiftu.v8i16(<8 x i16>, <8 x i16>) nounwind readnone
>  declare <8 x i16> @llvm.arm.neon.vqsubu.v8i16(<8 x i16>, <8 x i16>) nounwind readnone
>  declare <8 x i8> @llvm.arm.neon.vqmovnu.v8i8(<8 x i16>) nounwind readnone
> +
> +; vmull lowering would create a zext(v4i8 load()) instead of a zextload(v4i8),
> +; creating an illegal type during legalization and causing an assert.
> +; PR15970
> +define void @no_illegal_types_vmull_sext(<4 x i32> %a) {
> +entry:
> +  %wide.load283.i = load <4 x i8>* undef, align 1
> +  %0 = sext <4 x i8> %wide.load283.i to <4 x i32>
> +  %1 = sub nsw <4 x i32> %0, %a
> +  %2 = mul nsw <4 x i32> %1, %1
> +  %predphi290.v.i = select <4 x i1> undef, <4 x i32> undef, <4 x i32> %2
> +  store <4 x i32> %predphi290.v.i, <4 x i32>* undef, align 4
> +  ret void
> +}
> +define void @no_illegal_types_vmull_zext(<4 x i32> %a) {
> +entry:
> +  %wide.load283.i = load <4 x i8>* undef, align 1
> +  %0 = zext <4 x i8> %wide.load283.i to <4 x i32>
> +  %1 = sub nsw <4 x i32> %0, %a
> +  %2 = mul nsw <4 x i32> %1, %1
> +  %predphi290.v.i = select <4 x i1> undef, <4 x i32> undef, <4 x i32> %2
> +  store <4 x i32> %predphi290.v.i, <4 x i32>* undef, align 4
> +  ret void
> +}
> 
> 
> _______________________________________________
> 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