summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp61
1 files changed, 38 insertions, 23 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
index a963638be98..6c30057e5e2 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -304,6 +304,9 @@ class SystemZDAGToDAGISel : public SelectionDAGISel {
void splitLargeImmediate(unsigned Opcode, SDNode *Node, SDValue Op0,
uint64_t UpperVal, uint64_t LowerVal);
+ void loadVectorConstant(const SystemZVectorConstantInfo &VCI,
+ SDNode *Node);
+
// Try to use gather instruction Opcode to implement vector insertion N.
bool tryGather(SDNode *N, unsigned Opcode);
@@ -1132,6 +1135,35 @@ void SystemZDAGToDAGISel::splitLargeImmediate(unsigned Opcode, SDNode *Node,
SelectCode(Or.getNode());
}
+void SystemZDAGToDAGISel::loadVectorConstant(
+ const SystemZVectorConstantInfo &VCI, SDNode *Node) {
+ assert((VCI.Opcode == SystemZISD::BYTE_MASK ||
+ VCI.Opcode == SystemZISD::REPLICATE ||
+ VCI.Opcode == SystemZISD::ROTATE_MASK) &&
+ "Bad opcode!");
+ assert(VCI.VecVT.getSizeInBits() == 128 && "Expected a vector type");
+ EVT VT = Node->getValueType(0);
+ SDLoc DL(Node);
+ SmallVector<SDValue, 2> Ops;
+ for (unsigned OpVal : VCI.OpVals)
+ Ops.push_back(CurDAG->getConstant(OpVal, DL, MVT::i32));
+ SDValue Op = CurDAG->getNode(VCI.Opcode, DL, VCI.VecVT, Ops);
+
+ if (VCI.VecVT == VT.getSimpleVT())
+ ReplaceNode(Node, Op.getNode());
+ else if (VT.getSizeInBits() == 128) {
+ SDValue BitCast = CurDAG->getNode(ISD::BITCAST, DL, VT, Op);
+ ReplaceNode(Node, BitCast.getNode());
+ SelectCode(BitCast.getNode());
+ } else { // float or double
+ unsigned SubRegIdx =
+ (VT.getSizeInBits() == 32 ? SystemZ::subreg_h32 : SystemZ::subreg_h64);
+ ReplaceNode(
+ Node, CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, Op).getNode());
+ }
+ SelectCode(Op.getNode());
+}
+
bool SystemZDAGToDAGISel::tryGather(SDNode *N, unsigned Opcode) {
SDValue ElemV = N->getOperand(2);
auto *ElemN = dyn_cast<ConstantSDNode>(ElemV);
@@ -1529,13 +1561,9 @@ void SystemZDAGToDAGISel::Select(SDNode *Node) {
case ISD::BUILD_VECTOR: {
auto *BVN = cast<BuildVectorSDNode>(Node);
- SDLoc DL(Node);
- EVT VT = Node->getValueType(0);
- uint64_t Mask = 0;
- if (SystemZTargetLowering::tryBuildVectorByteMask(BVN, Mask)) {
- SDNode *Res = CurDAG->getMachineNode(SystemZ::VGBM, DL, VT,
- CurDAG->getTargetConstant(Mask, DL, MVT::i32));
- ReplaceNode(Node, Res);
+ SystemZVectorConstantInfo VCI(BVN);
+ if (VCI.isVectorConstantLegal(*Subtarget)) {
+ loadVectorConstant(VCI, Node);
return;
}
break;
@@ -1545,23 +1573,10 @@ void SystemZDAGToDAGISel::Select(SDNode *Node) {
APFloat Imm = cast<ConstantFPSDNode>(Node)->getValueAPF();
if (Imm.isZero() || Imm.isNegZero())
break;
- const SystemZInstrInfo *TII = getInstrInfo();
- EVT VT = Node->getValueType(0);
- unsigned Start, End;
- unsigned BitWidth = VT.getSizeInBits();
- bool Success = SystemZTargetLowering::analyzeFPImm(Imm, BitWidth, Start,
- End, static_cast<const SystemZInstrInfo *>(TII)); (void)Success;
+ SystemZVectorConstantInfo VCI(Imm);
+ bool Success = VCI.isVectorConstantLegal(*Subtarget); (void)Success;
assert(Success && "Expected legal FP immediate");
- SDLoc DL(Node);
- unsigned Opcode = (BitWidth == 32 ? SystemZ::VGMF : SystemZ::VGMG);
- SDNode *Res = CurDAG->getMachineNode(Opcode, DL, VT,
- CurDAG->getTargetConstant(Start, DL, MVT::i32),
- CurDAG->getTargetConstant(End, DL, MVT::i32));
- unsigned SubRegIdx = (BitWidth == 32 ? SystemZ::subreg_h32
- : SystemZ::subreg_h64);
- Res = CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, SDValue(Res, 0))
- .getNode();
- ReplaceNode(Node, Res);
+ loadVectorConstant(VCI, Node);
return;
}
OpenPOWER on IntegriCloud