Split up ARM LowerShift function.

This function was being called from two different places for completely
unrelated reasons.  During type legalization, it was called to expand 64-bit
shift operations.  During operation legalization, it was called to handle
Neon vector shifts.  The vector shift code was not written to check for
illegal types, since it was assumed to be only called after type legalization.
Fixed this by splitting off the 64-bit shift expansion into a separate
function.  I don't have a particular testcase for this; I just noticed it
by inspection.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119738 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bob Wilson 2010-11-18 21:16:28 +00:00
parent 612fb5b9a6
commit d5448bb6e8

View File

@ -2921,33 +2921,40 @@ static SDValue LowerShift(SDNode *N, SelectionDAG &DAG,
EVT VT = N->getValueType(0);
DebugLoc dl = N->getDebugLoc();
if (!VT.isVector())
return SDValue();
// Lower vector shifts on NEON to use VSHL.
if (VT.isVector()) {
assert(ST->hasNEON() && "unexpected vector shift");
assert(ST->hasNEON() && "unexpected vector shift");
// Left shifts translate directly to the vshiftu intrinsic.
if (N->getOpcode() == ISD::SHL)
return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
DAG.getConstant(Intrinsic::arm_neon_vshiftu, MVT::i32),
N->getOperand(0), N->getOperand(1));
assert((N->getOpcode() == ISD::SRA ||
N->getOpcode() == ISD::SRL) && "unexpected vector shift opcode");
// NEON uses the same intrinsics for both left and right shifts. For
// right shifts, the shift amounts are negative, so negate the vector of
// shift amounts.
EVT ShiftVT = N->getOperand(1).getValueType();
SDValue NegatedCount = DAG.getNode(ISD::SUB, dl, ShiftVT,
getZeroVector(ShiftVT, DAG, dl),
N->getOperand(1));
Intrinsic::ID vshiftInt = (N->getOpcode() == ISD::SRA ?
Intrinsic::arm_neon_vshifts :
Intrinsic::arm_neon_vshiftu);
// Left shifts translate directly to the vshiftu intrinsic.
if (N->getOpcode() == ISD::SHL)
return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
DAG.getConstant(vshiftInt, MVT::i32),
N->getOperand(0), NegatedCount);
}
DAG.getConstant(Intrinsic::arm_neon_vshiftu, MVT::i32),
N->getOperand(0), N->getOperand(1));
assert((N->getOpcode() == ISD::SRA ||
N->getOpcode() == ISD::SRL) && "unexpected vector shift opcode");
// NEON uses the same intrinsics for both left and right shifts. For
// right shifts, the shift amounts are negative, so negate the vector of
// shift amounts.
EVT ShiftVT = N->getOperand(1).getValueType();
SDValue NegatedCount = DAG.getNode(ISD::SUB, dl, ShiftVT,
getZeroVector(ShiftVT, DAG, dl),
N->getOperand(1));
Intrinsic::ID vshiftInt = (N->getOpcode() == ISD::SRA ?
Intrinsic::arm_neon_vshifts :
Intrinsic::arm_neon_vshiftu);
return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
DAG.getConstant(vshiftInt, MVT::i32),
N->getOperand(0), NegatedCount);
}
static SDValue Expand64BitShift(SDNode *N, SelectionDAG &DAG,
const ARMSubtarget *ST) {
EVT VT = N->getValueType(0);
DebugLoc dl = N->getDebugLoc();
// We can get here for a node like i32 = ISD::SHL i32, i64
if (VT != MVT::i64)
@ -3958,7 +3965,7 @@ void ARMTargetLowering::ReplaceNodeResults(SDNode *N,
break;
case ISD::SRL:
case ISD::SRA:
Res = LowerShift(N, DAG, Subtarget);
Res = Expand64BitShift(N, DAG, Subtarget);
break;
}
if (Res.getNode())