mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-20 12:31:40 +00:00
Merging r181842:
------------------------------------------------------------------------ r181842 | arnolds | 2013-05-14 15:33:24 -0700 (Tue, 14 May 2013) | 14 lines 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 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_33@181946 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5b85a9b5ad
commit
a3d7a30740
@ -5257,6 +5257,23 @@ static bool isZeroExtended(SDNode *N, SelectionDAG &DAG) {
|
|||||||
return false;
|
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
|
/// 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.
|
/// 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.
|
/// We insert the required extension here to get the vector to fill a D register.
|
||||||
@ -5272,18 +5289,8 @@ static SDValue AddRequiredExtensionForVMULL(SDValue N, SelectionDAG &DAG,
|
|||||||
return N;
|
return N;
|
||||||
|
|
||||||
// Must extend size to at least 64 bits to be used as an operand for VMULL.
|
// Must extend size to at least 64 bits to be used as an operand for VMULL.
|
||||||
MVT::SimpleValueType OrigSimpleTy = OrigTy.getSimpleVT().SimpleTy;
|
EVT NewVT = getExtensionTo64Bits(OrigTy);
|
||||||
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;
|
|
||||||
}
|
|
||||||
return DAG.getNode(ExtOpcode, N->getDebugLoc(), NewVT, N);
|
return DAG.getNode(ExtOpcode, N->getDebugLoc(), NewVT, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5293,22 +5300,22 @@ static SDValue AddRequiredExtensionForVMULL(SDValue N, SelectionDAG &DAG,
|
|||||||
/// reach a total size of 64 bits. We have to add the extension separately
|
/// 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.
|
/// because ARM does not have a sign/zero extending load for vectors.
|
||||||
static SDValue SkipLoadExtensionForVMULL(LoadSDNode *LD, SelectionDAG& DAG) {
|
static SDValue SkipLoadExtensionForVMULL(LoadSDNode *LD, SelectionDAG& DAG) {
|
||||||
SDValue NonExtendingLoad =
|
EVT ExtendedTy = getExtensionTo64Bits(LD->getMemoryVT());
|
||||||
DAG.getLoad(LD->getMemoryVT(), LD->getDebugLoc(), LD->getChain(),
|
|
||||||
|
// 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->getBasePtr(), LD->getPointerInfo(), LD->isVolatile(),
|
||||||
LD->isNonTemporal(), LD->isInvariant(),
|
LD->isNonTemporal(), LD->isInvariant(),
|
||||||
LD->getAlignment());
|
LD->getAlignment());
|
||||||
unsigned ExtOp = 0;
|
|
||||||
switch (LD->getExtensionType()) {
|
// We need to create a zextload/sextload. We cannot just create a load
|
||||||
default: llvm_unreachable("Unexpected LoadExtType");
|
// followed by a zext/zext node because LowerMUL is also run during normal
|
||||||
case ISD::EXTLOAD:
|
// operation legalization where we can't create illegal types.
|
||||||
case ISD::SEXTLOAD: ExtOp = ISD::SIGN_EXTEND; break;
|
return DAG.getExtLoad(LD->getExtensionType(), LD->getDebugLoc(), ExtendedTy,
|
||||||
case ISD::ZEXTLOAD: ExtOp = ISD::ZERO_EXTEND; break;
|
LD->getChain(), LD->getBasePtr(), LD->getPointerInfo(),
|
||||||
}
|
LD->getMemoryVT(), LD->isVolatile(),
|
||||||
MVT::SimpleValueType MemType = LD->getMemoryVT().getSimpleVT().SimpleTy;
|
LD->isNonTemporal(), LD->getAlignment());
|
||||||
MVT::SimpleValueType ExtType = LD->getValueType(0).getSimpleVT().SimpleTy;
|
|
||||||
return AddRequiredExtensionForVMULL(NonExtendingLoad, DAG,
|
|
||||||
MemType, ExtType, ExtOp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SkipExtensionForVMULL - For a node that is a SIGN_EXTEND, ZERO_EXTEND,
|
/// SkipExtensionForVMULL - For a node that is a SIGN_EXTEND, ZERO_EXTEND,
|
||||||
|
@ -599,3 +599,27 @@ for.end179: ; preds = %for.cond.loopexit,
|
|||||||
declare <8 x i16> @llvm.arm.neon.vrshiftu.v8i16(<8 x i16>, <8 x i16>) nounwind readnone
|
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 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
|
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
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user