Remove the hidden "neon-reg-sequence" option. The reg sequences are working

now, so there's no need to disable them.

llvm-svn: 106155
This commit is contained in:
Bob Wilson 2010-06-16 21:34:01 +00:00
parent 9c56c0a851
commit d81a716d59
4 changed files with 156 additions and 271 deletions

View File

@ -90,10 +90,6 @@ inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
}
}
/// ModelWithRegSequence - Return true if isel should use REG_SEQUENCE to model
/// operations involving sub-registers.
bool ModelWithRegSequence();
FunctionPass *createARMISelDag(ARMBaseTargetMachine &TM,
CodeGenOpt::Level OptLevel);

View File

@ -36,11 +36,6 @@
using namespace llvm;
static cl::opt<bool>
UseRegSeq("neon-reg-sequence", cl::Hidden,
cl::desc("Use reg_sequence to model ld / st of multiple neon regs"),
cl::init(true));
//===--------------------------------------------------------------------===//
/// ARMDAGToDAGISel - ARM specific code to select ARM machine
/// instructions for SelectionDAG operations.
@ -962,16 +957,8 @@ SDNode *ARMDAGToDAGISel::PairSRegs(EVT VT, SDValue V0, SDValue V1) {
DebugLoc dl = V0.getNode()->getDebugLoc();
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32);
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32);
if (llvm::ModelWithRegSequence()) {
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
}
SDValue Undef =
SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0);
SDNode *Pair = CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
VT, Undef, V0, SubReg0);
return CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
VT, SDValue(Pair, 0), V1, SubReg1);
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
}
/// PairDRegs - Form a quad register from a pair of D registers.
@ -980,16 +967,8 @@ SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) {
DebugLoc dl = V0.getNode()->getDebugLoc();
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32);
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32);
if (llvm::ModelWithRegSequence()) {
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
}
SDValue Undef =
SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0);
SDNode *Pair = CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
VT, Undef, V0, SubReg0);
return CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
VT, SDValue(Pair, 0), V1, SubReg1);
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
}
/// PairQRegs - Form 4 consecutive D registers from a pair of Q registers.
@ -1115,7 +1094,7 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs,
std::vector<EVT> ResTys(NumVecs, VT);
ResTys.push_back(MVT::Other);
SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5);
if (!llvm::ModelWithRegSequence() || NumVecs < 2)
if (NumVecs < 2)
return VLd;
SDValue RegSeq;
@ -1156,24 +1135,17 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs,
Chain = SDValue(VLd, 2 * NumVecs);
// Combine the even and odd subregs to produce the result.
if (llvm::ModelWithRegSequence()) {
if (NumVecs == 1) {
SDNode *Q = PairDRegs(VT, SDValue(VLd, 0), SDValue(VLd, 1));
ReplaceUses(SDValue(N, 0), SDValue(Q, 0));
} else {
SDValue QQ = SDValue(QuadDRegs(MVT::v4i64,
SDValue(VLd, 0), SDValue(VLd, 1),
SDValue(VLd, 2), SDValue(VLd, 3)), 0);
SDValue Q0 = CurDAG->getTargetExtractSubreg(ARM::qsub_0, dl, VT, QQ);
SDValue Q1 = CurDAG->getTargetExtractSubreg(ARM::qsub_1, dl, VT, QQ);
ReplaceUses(SDValue(N, 0), Q0);
ReplaceUses(SDValue(N, 1), Q1);
}
if (NumVecs == 1) {
SDNode *Q = PairDRegs(VT, SDValue(VLd, 0), SDValue(VLd, 1));
ReplaceUses(SDValue(N, 0), SDValue(Q, 0));
} else {
for (unsigned Vec = 0; Vec < NumVecs; ++Vec) {
SDNode *Q = PairDRegs(VT, SDValue(VLd, 2*Vec), SDValue(VLd, 2*Vec+1));
ReplaceUses(SDValue(N, Vec), SDValue(Q, 0));
}
SDValue QQ = SDValue(QuadDRegs(MVT::v4i64,
SDValue(VLd, 0), SDValue(VLd, 1),
SDValue(VLd, 2), SDValue(VLd, 3)), 0);
SDValue Q0 = CurDAG->getTargetExtractSubreg(ARM::qsub_0, dl, VT, QQ);
SDValue Q1 = CurDAG->getTargetExtractSubreg(ARM::qsub_1, dl, VT, QQ);
ReplaceUses(SDValue(N, 0), Q0);
ReplaceUses(SDValue(N, 1), Q1);
}
} else {
// Otherwise, quad registers are loaded with two separate instructions,
@ -1196,37 +1168,27 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs,
SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 6);
Chain = SDValue(VLdB, NumVecs+1);
if (llvm::ModelWithRegSequence()) {
SDValue V0 = SDValue(VLdA, 0);
SDValue V1 = SDValue(VLdB, 0);
SDValue V2 = SDValue(VLdA, 1);
SDValue V3 = SDValue(VLdB, 1);
SDValue V4 = SDValue(VLdA, 2);
SDValue V5 = SDValue(VLdB, 2);
SDValue V6 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,RegVT),
0)
: SDValue(VLdA, 3);
SDValue V7 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,RegVT),
0)
: SDValue(VLdB, 3);
SDValue RegSeq = SDValue(OctoDRegs(MVT::v8i64, V0, V1, V2, V3,
V4, V5, V6, V7), 0);
SDValue V0 = SDValue(VLdA, 0);
SDValue V1 = SDValue(VLdB, 0);
SDValue V2 = SDValue(VLdA, 1);
SDValue V3 = SDValue(VLdB, 1);
SDValue V4 = SDValue(VLdA, 2);
SDValue V5 = SDValue(VLdB, 2);
SDValue V6 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,RegVT), 0)
: SDValue(VLdA, 3);
SDValue V7 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,RegVT), 0)
: SDValue(VLdB, 3);
SDValue RegSeq = SDValue(OctoDRegs(MVT::v8i64, V0, V1, V2, V3,
V4, V5, V6, V7), 0);
// Extract out the 3 / 4 Q registers.
assert(ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering");
for (unsigned Vec = 0; Vec < NumVecs; ++Vec) {
SDValue Q = CurDAG->getTargetExtractSubreg(ARM::qsub_0+Vec,
dl, VT, RegSeq);
ReplaceUses(SDValue(N, Vec), Q);
}
} else {
// Combine the even and odd subregs to produce the result.
for (unsigned Vec = 0; Vec < NumVecs; ++Vec) {
SDNode *Q = PairDRegs(VT, SDValue(VLdA, Vec), SDValue(VLdB, Vec));
ReplaceUses(SDValue(N, Vec), SDValue(Q, 0));
}
// Extract out the 3 / 4 Q registers.
assert(ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering");
for (unsigned Vec = 0; Vec < NumVecs; ++Vec) {
SDValue Q = CurDAG->getTargetExtractSubreg(ARM::qsub_0+Vec,
dl, VT, RegSeq);
ReplaceUses(SDValue(N, Vec), Q);
}
}
ReplaceUses(SDValue(N, NumVecs), Chain);
@ -1274,7 +1236,7 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs,
Ops.push_back(Align);
if (is64BitVector) {
if (llvm::ModelWithRegSequence() && NumVecs >= 2) {
if (NumVecs >= 2) {
SDValue RegSeq;
SDValue V0 = N->getOperand(0+3);
SDValue V1 = N->getOperand(1+3);
@ -1319,7 +1281,7 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs,
// Quad registers are directly supported for VST1 and VST2,
// storing pairs of D regs.
unsigned Opc = QOpcodes0[OpcodeIndex];
if (llvm::ModelWithRegSequence() && NumVecs == 2) {
if (NumVecs == 2) {
// First extract the pair of Q registers.
SDValue Q0 = N->getOperand(3);
SDValue Q1 = N->getOperand(4);
@ -1357,76 +1319,48 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs,
// Otherwise, quad registers are stored with two separate instructions,
// where one stores the even registers and the other stores the odd registers.
if (llvm::ModelWithRegSequence()) {
// Form the QQQQ REG_SEQUENCE.
SDValue V[8];
for (unsigned Vec = 0, i = 0; Vec < NumVecs; ++Vec, i+=2) {
V[i] = CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, RegVT,
N->getOperand(Vec+3));
V[i+1] = CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, RegVT,
N->getOperand(Vec+3));
}
if (NumVecs == 3)
V[6] = V[7] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, RegVT), 0);
SDValue RegSeq = SDValue(OctoDRegs(MVT::v8i64, V[0], V[1], V[2], V[3],
V[4], V[5], V[6], V[7]), 0);
// Store the even D registers.
assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
Ops.push_back(Reg0); // post-access address offset
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0+Vec*2, dl,
RegVT, RegSeq));
Ops.push_back(Pred);
Ops.push_back(Reg0); // predicate register
Ops.push_back(Chain);
unsigned Opc = QOpcodes0[OpcodeIndex];
SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(),
MVT::Other, Ops.data(), NumVecs+6);
Chain = SDValue(VStA, 1);
// Store the odd D registers.
Ops[0] = SDValue(VStA, 0); // MemAddr
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::dsub_1+Vec*2, dl,
RegVT, RegSeq);
Ops[NumVecs+5] = Chain;
Opc = QOpcodes1[OpcodeIndex];
SDNode *VStB = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(),
MVT::Other, Ops.data(), NumVecs+6);
Chain = SDValue(VStB, 1);
ReplaceUses(SDValue(N, 0), Chain);
return NULL;
} else {
Ops.push_back(Reg0); // post-access address offset
// Store the even subregs.
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, RegVT,
N->getOperand(Vec+3)));
Ops.push_back(Pred);
Ops.push_back(Reg0); // predicate register
Ops.push_back(Chain);
unsigned Opc = QOpcodes0[OpcodeIndex];
SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(),
MVT::Other, Ops.data(), NumVecs+6);
Chain = SDValue(VStA, 1);
// Store the odd subregs.
Ops[0] = SDValue(VStA, 0); // MemAddr
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, RegVT,
N->getOperand(Vec+3));
Ops[NumVecs+5] = Chain;
Opc = QOpcodes1[OpcodeIndex];
SDNode *VStB = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(),
MVT::Other, Ops.data(), NumVecs+6);
Chain = SDValue(VStB, 1);
ReplaceUses(SDValue(N, 0), Chain);
return NULL;
// Form the QQQQ REG_SEQUENCE.
SDValue V[8];
for (unsigned Vec = 0, i = 0; Vec < NumVecs; ++Vec, i+=2) {
V[i] = CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, RegVT,
N->getOperand(Vec+3));
V[i+1] = CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, RegVT,
N->getOperand(Vec+3));
}
if (NumVecs == 3)
V[6] = V[7] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, RegVT), 0);
SDValue RegSeq = SDValue(OctoDRegs(MVT::v8i64, V[0], V[1], V[2], V[3],
V[4], V[5], V[6], V[7]), 0);
// Store the even D registers.
assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
Ops.push_back(Reg0); // post-access address offset
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0+Vec*2, dl,
RegVT, RegSeq));
Ops.push_back(Pred);
Ops.push_back(Reg0); // predicate register
Ops.push_back(Chain);
unsigned Opc = QOpcodes0[OpcodeIndex];
SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(),
MVT::Other, Ops.data(), NumVecs+6);
Chain = SDValue(VStA, 1);
// Store the odd D registers.
Ops[0] = SDValue(VStA, 0); // MemAddr
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::dsub_1+Vec*2, dl,
RegVT, RegSeq);
Ops[NumVecs+5] = Chain;
Opc = QOpcodes1[OpcodeIndex];
SDNode *VStB = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(),
MVT::Other, Ops.data(), NumVecs+6);
Chain = SDValue(VStB, 1);
ReplaceUses(SDValue(N, 0), Chain);
return NULL;
}
SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
@ -1482,35 +1416,26 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
unsigned Opc = 0;
if (is64BitVector) {
Opc = DOpcodes[OpcodeIndex];
if (llvm::ModelWithRegSequence()) {
SDValue RegSeq;
SDValue V0 = N->getOperand(0+3);
SDValue V1 = N->getOperand(1+3);
if (NumVecs == 2) {
RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0);
} else {
SDValue V2 = N->getOperand(2+3);
SDValue V3 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
: N->getOperand(3+3);
RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0);
}
// Now extract the D registers back out.
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, VT,
RegSeq));
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, VT,
RegSeq));
if (NumVecs > 2)
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_2, dl, VT,
RegSeq));
if (NumVecs > 3)
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_3, dl, VT,
RegSeq));
SDValue RegSeq;
SDValue V0 = N->getOperand(0+3);
SDValue V1 = N->getOperand(1+3);
if (NumVecs == 2) {
RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0);
} else {
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops.push_back(N->getOperand(Vec+3));
SDValue V2 = N->getOperand(2+3);
SDValue V3 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
: N->getOperand(3+3);
RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0);
}
// Now extract the D registers back out.
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, VT, RegSeq));
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, VT, RegSeq));
if (NumVecs > 2)
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_2, dl, VT,RegSeq));
if (NumVecs > 3)
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_3, dl, VT,RegSeq));
} else {
// Check if this is loading the even or odd subreg of a Q register.
if (Lane < NumElts) {
@ -1520,31 +1445,24 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
Opc = QOpcodes1[OpcodeIndex];
}
if (llvm::ModelWithRegSequence()) {
SDValue RegSeq;
SDValue V0 = N->getOperand(0+3);
SDValue V1 = N->getOperand(1+3);
if (NumVecs == 2) {
RegSeq = SDValue(PairQRegs(MVT::v4i64, V0, V1), 0);
} else {
SDValue V2 = N->getOperand(2+3);
SDValue V3 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
: N->getOperand(3+3);
RegSeq = SDValue(QuadQRegs(MVT::v8i64, V0, V1, V2, V3), 0);
}
// Extract the subregs of the input vector.
unsigned SubIdx = Even ? ARM::dsub_0 : ARM::dsub_1;
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops.push_back(CurDAG->getTargetExtractSubreg(SubIdx+Vec*2, dl, RegVT,
RegSeq));
SDValue RegSeq;
SDValue V0 = N->getOperand(0+3);
SDValue V1 = N->getOperand(1+3);
if (NumVecs == 2) {
RegSeq = SDValue(PairQRegs(MVT::v4i64, V0, V1), 0);
} else {
// Extract the subregs of the input vector.
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops.push_back(CurDAG->getTargetExtractSubreg(SubregIdx, dl, RegVT,
N->getOperand(Vec+3)));
SDValue V2 = N->getOperand(2+3);
SDValue V3 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
: N->getOperand(3+3);
RegSeq = SDValue(QuadQRegs(MVT::v8i64, V0, V1, V2, V3), 0);
}
// Extract the subregs of the input vector.
unsigned SubIdx = Even ? ARM::dsub_0 : ARM::dsub_1;
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops.push_back(CurDAG->getTargetExtractSubreg(SubIdx+Vec*2, dl, RegVT,
RegSeq));
}
Ops.push_back(getI32Imm(Lane));
Ops.push_back(Pred);
@ -1558,73 +1476,54 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
ResTys.push_back(MVT::Other);
SDNode *VLdLn = CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(),NumVecs+6);
if (llvm::ModelWithRegSequence()) {
// Form a REG_SEQUENCE to force register allocation.
SDValue RegSeq;
if (is64BitVector) {
SDValue V0 = SDValue(VLdLn, 0);
SDValue V1 = SDValue(VLdLn, 1);
if (NumVecs == 2) {
RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0);
} else {
SDValue V2 = SDValue(VLdLn, 2);
// If it's a vld3, form a quad D-register but discard the last part.
SDValue V3 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
: SDValue(VLdLn, 3);
RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0);
}
// Form a REG_SEQUENCE to force register allocation.
SDValue RegSeq;
if (is64BitVector) {
SDValue V0 = SDValue(VLdLn, 0);
SDValue V1 = SDValue(VLdLn, 1);
if (NumVecs == 2) {
RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0);
} else {
// For 128-bit vectors, take the 64-bit results of the load and insert
// them as subregs into the result.
SDValue V[8];
for (unsigned Vec = 0, i = 0; Vec < NumVecs; ++Vec, i+=2) {
if (Even) {
V[i] = SDValue(VLdLn, Vec);
V[i+1] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, RegVT), 0);
} else {
V[i] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, RegVT), 0);
V[i+1] = SDValue(VLdLn, Vec);
}
}
if (NumVecs == 3)
V[6] = V[7] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, RegVT), 0);
if (NumVecs == 2)
RegSeq = SDValue(QuadDRegs(MVT::v4i64, V[0], V[1], V[2], V[3]), 0);
else
RegSeq = SDValue(OctoDRegs(MVT::v8i64, V[0], V[1], V[2], V[3],
V[4], V[5], V[6], V[7]), 0);
SDValue V2 = SDValue(VLdLn, 2);
// If it's a vld3, form a quad D-register but discard the last part.
SDValue V3 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
: SDValue(VLdLn, 3);
RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0);
}
} else {
// For 128-bit vectors, take the 64-bit results of the load and insert
// them as subregs into the result.
SDValue V[8];
for (unsigned Vec = 0, i = 0; Vec < NumVecs; ++Vec, i+=2) {
if (Even) {
V[i] = SDValue(VLdLn, Vec);
V[i+1] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, RegVT), 0);
} else {
V[i] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, RegVT), 0);
V[i+1] = SDValue(VLdLn, Vec);
}
}
if (NumVecs == 3)
V[6] = V[7] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, RegVT), 0);
assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
assert(ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering");
unsigned SubIdx = is64BitVector ? ARM::dsub_0 : ARM::qsub_0;
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
ReplaceUses(SDValue(N, Vec),
CurDAG->getTargetExtractSubreg(SubIdx+Vec, dl, VT, RegSeq));
ReplaceUses(SDValue(N, NumVecs), SDValue(VLdLn, NumVecs));
return NULL;
if (NumVecs == 2)
RegSeq = SDValue(QuadDRegs(MVT::v4i64, V[0], V[1], V[2], V[3]), 0);
else
RegSeq = SDValue(OctoDRegs(MVT::v8i64, V[0], V[1], V[2], V[3],
V[4], V[5], V[6], V[7]), 0);
}
// For a 64-bit vector load to D registers, nothing more needs to be done.
if (is64BitVector)
return VLdLn;
// For 128-bit vectors, take the 64-bit results of the load and insert them
// as subregs into the result.
for (unsigned Vec = 0; Vec < NumVecs; ++Vec) {
SDValue QuadVec = CurDAG->getTargetInsertSubreg(SubregIdx, dl, VT,
N->getOperand(Vec+3),
SDValue(VLdLn, Vec));
ReplaceUses(SDValue(N, Vec), QuadVec);
}
Chain = SDValue(VLdLn, NumVecs);
ReplaceUses(SDValue(N, NumVecs), Chain);
assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
assert(ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering");
unsigned SubIdx = is64BitVector ? ARM::dsub_0 : ARM::qsub_0;
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
ReplaceUses(SDValue(N, Vec),
CurDAG->getTargetExtractSubreg(SubIdx+Vec, dl, VT, RegSeq));
ReplaceUses(SDValue(N, NumVecs), SDValue(VLdLn, NumVecs));
return NULL;
}
@ -2410,9 +2309,3 @@ FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM,
CodeGenOpt::Level OptLevel) {
return new ARMDAGToDAGISel(TM, OptLevel);
}
/// ModelWithRegSequence - Return true if isel should use REG_SEQUENCE to model
/// operations involving sub-registers.
bool llvm::ModelWithRegSequence() {
return UseRegSeq;
}

View File

@ -109,10 +109,7 @@ void ARMTargetLowering::addTypeForNEON(EVT VT, EVT PromotedLdStVT,
}
setOperationAction(ISD::BUILD_VECTOR, VT.getSimpleVT(), Custom);
setOperationAction(ISD::VECTOR_SHUFFLE, VT.getSimpleVT(), Custom);
if (llvm::ModelWithRegSequence())
setOperationAction(ISD::CONCAT_VECTORS, VT.getSimpleVT(), Legal);
else
setOperationAction(ISD::CONCAT_VECTORS, VT.getSimpleVT(), Custom);
setOperationAction(ISD::CONCAT_VECTORS, VT.getSimpleVT(), Legal);
setOperationAction(ISD::EXTRACT_SUBVECTOR, VT.getSimpleVT(), Expand);
setOperationAction(ISD::SELECT, VT.getSimpleVT(), Expand);
setOperationAction(ISD::SELECT_CC, VT.getSimpleVT(), Expand);

View File

@ -467,8 +467,7 @@ bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
unsigned FirstOpnd, NumRegs, Offset, Stride;
if (!isNEONMultiRegOp(MI->getOpcode(), FirstOpnd, NumRegs, Offset, Stride))
continue;
if (llvm::ModelWithRegSequence() &&
FormsRegSequence(MI, FirstOpnd, NumRegs, Offset, Stride))
if (FormsRegSequence(MI, FirstOpnd, NumRegs, Offset, Stride))
continue;
MachineBasicBlock::iterator NextI = llvm::next(MBBI);