summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonISelLowering.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelLowering.cpp246
1 files changed, 16 insertions, 230 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index b70e01b59ec..ef387379bd0 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -129,11 +129,6 @@ namespace {
// Implement calling convention for Hexagon.
-static const MVT LegalV64[] = { MVT::v64i8, MVT::v32i16, MVT::v16i32 };
-static const MVT LegalW64[] = { MVT::v128i8, MVT::v64i16, MVT::v32i32 };
-static const MVT LegalV128[] = { MVT::v128i8, MVT::v64i16, MVT::v32i32 };
-static const MVT LegalW128[] = { MVT::v256i8, MVT::v128i16, MVT::v64i32 };
-
static bool
CC_Hexagon(unsigned ValNo, MVT ValVT,
MVT LocVT, CCValAssign::LocInfo LocInfo,
@@ -1732,40 +1727,6 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
addRegisterClass(MVT::f64, &Hexagon::DoubleRegsRegClass);
}
- if (Subtarget.hasV60TOps()) {
- if (Subtarget.useHVX64BOps()) {
- addRegisterClass(MVT::v64i8, &Hexagon::HvxVRRegClass);
- addRegisterClass(MVT::v32i16, &Hexagon::HvxVRRegClass);
- addRegisterClass(MVT::v16i32, &Hexagon::HvxVRRegClass);
- addRegisterClass(MVT::v128i8, &Hexagon::HvxWRRegClass);
- addRegisterClass(MVT::v64i16, &Hexagon::HvxWRRegClass);
- addRegisterClass(MVT::v32i32, &Hexagon::HvxWRRegClass);
- // These "short" boolean vector types should be legal because
- // they will appear as results of vector compares. If they were
- // not legal, type legalization would try to make them legal
- // and that would require using operations that do not use or
- // produce such types. That, in turn, would imply using custom
- // nodes, which would be unoptimizable by the DAG combiner.
- // The idea is to rely on target-independent operations as much
- // as possible.
- addRegisterClass(MVT::v16i1, &Hexagon::HvxQRRegClass);
- addRegisterClass(MVT::v32i1, &Hexagon::HvxQRRegClass);
- addRegisterClass(MVT::v64i1, &Hexagon::HvxQRRegClass);
- addRegisterClass(MVT::v512i1, &Hexagon::HvxQRRegClass);
- } else if (Subtarget.useHVX128BOps()) {
- addRegisterClass(MVT::v128i8, &Hexagon::HvxVRRegClass);
- addRegisterClass(MVT::v64i16, &Hexagon::HvxVRRegClass);
- addRegisterClass(MVT::v32i32, &Hexagon::HvxVRRegClass);
- addRegisterClass(MVT::v256i8, &Hexagon::HvxWRRegClass);
- addRegisterClass(MVT::v128i16, &Hexagon::HvxWRRegClass);
- addRegisterClass(MVT::v64i32, &Hexagon::HvxWRRegClass);
- addRegisterClass(MVT::v32i1, &Hexagon::HvxQRRegClass);
- addRegisterClass(MVT::v64i1, &Hexagon::HvxQRRegClass);
- addRegisterClass(MVT::v128i1, &Hexagon::HvxQRRegClass);
- addRegisterClass(MVT::v1024i1, &Hexagon::HvxQRRegClass);
- }
- }
-
//
// Handling of scalar operations.
//
@@ -2002,11 +1963,6 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v4i16, Custom);
setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v8i8, Custom);
- auto setPromoteTo = [this] (unsigned Opc, MVT FromTy, MVT ToTy) {
- setOperationAction(Opc, FromTy, Promote);
- AddPromotedToType(Opc, FromTy, ToTy);
- };
-
// Subtarget-specific operation actions.
//
if (Subtarget.hasV5TOps()) {
@@ -2068,121 +2024,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
setIndexedStoreAction(ISD::POST_INC, VT, Legal);
}
- if (Subtarget.useHVXOps()) {
- bool Use64b = Subtarget.useHVX64BOps();
- ArrayRef<MVT> LegalV = Use64b ? LegalV64 : LegalV128;
- ArrayRef<MVT> LegalW = Use64b ? LegalW64 : LegalW128;
- MVT ByteV = Use64b ? MVT::v64i8 : MVT::v128i8;
- MVT ByteW = Use64b ? MVT::v128i8 : MVT::v256i8;
-
- setOperationAction(ISD::VECTOR_SHUFFLE, ByteV, Legal);
- setOperationAction(ISD::VECTOR_SHUFFLE, ByteW, Legal);
- setOperationAction(ISD::AND, ByteV, Legal);
- setOperationAction(ISD::OR, ByteV, Legal);
- setOperationAction(ISD::XOR, ByteV, Legal);
-
- for (MVT T : LegalV) {
- setIndexedLoadAction(ISD::POST_INC, T, Legal);
- setIndexedStoreAction(ISD::POST_INC, T, Legal);
-
- setOperationAction(ISD::ADD, T, Legal);
- setOperationAction(ISD::SUB, T, Legal);
- if (T != ByteV) {
- setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, T, Legal);
- setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, T, Legal);
- }
-
- setOperationAction(ISD::MUL, T, Custom);
- setOperationAction(ISD::MULHS, T, Custom);
- setOperationAction(ISD::MULHU, T, Custom);
- setOperationAction(ISD::BUILD_VECTOR, T, Custom);
- // Make concat-vectors custom to handle concats of more than 2 vectors.
- setOperationAction(ISD::CONCAT_VECTORS, T, Custom);
- setOperationAction(ISD::INSERT_SUBVECTOR, T, Custom);
- setOperationAction(ISD::INSERT_VECTOR_ELT, T, Custom);
- setOperationAction(ISD::EXTRACT_SUBVECTOR, T, Custom);
- setOperationAction(ISD::EXTRACT_VECTOR_ELT, T, Custom);
- setOperationAction(ISD::ANY_EXTEND, T, Custom);
- setOperationAction(ISD::SIGN_EXTEND, T, Custom);
- setOperationAction(ISD::ZERO_EXTEND, T, Custom);
- if (T != ByteV) {
- setOperationAction(ISD::ANY_EXTEND_VECTOR_INREG, T, Custom);
- // HVX only has shifts of words and halfwords.
- setOperationAction(ISD::SRA, T, Custom);
- setOperationAction(ISD::SHL, T, Custom);
- setOperationAction(ISD::SRL, T, Custom);
- }
-
- setCondCodeAction(ISD::SETNE, T, Expand);
- setCondCodeAction(ISD::SETLE, T, Expand);
- setCondCodeAction(ISD::SETGE, T, Expand);
- setCondCodeAction(ISD::SETLT, T, Expand);
- setCondCodeAction(ISD::SETULE, T, Expand);
- setCondCodeAction(ISD::SETUGE, T, Expand);
- setCondCodeAction(ISD::SETULT, T, Expand);
- }
-
- for (MVT T : LegalV) {
- MVT BoolV = MVT::getVectorVT(MVT::i1, T.getVectorNumElements());
- setOperationAction(ISD::BUILD_VECTOR, BoolV, Custom);
- setOperationAction(ISD::CONCAT_VECTORS, BoolV, Custom);
- setOperationAction(ISD::INSERT_SUBVECTOR, BoolV, Custom);
- setOperationAction(ISD::INSERT_VECTOR_ELT, BoolV, Custom);
- setOperationAction(ISD::EXTRACT_SUBVECTOR, BoolV, Custom);
- setOperationAction(ISD::EXTRACT_VECTOR_ELT, BoolV, Custom);
- }
-
- for (MVT T : LegalV) {
- if (T == ByteV)
- continue;
- // Promote all shuffles to operate on vectors of bytes.
- setPromoteTo(ISD::VECTOR_SHUFFLE, T, ByteV);
- setPromoteTo(ISD::AND, T, ByteV);
- setPromoteTo(ISD::OR, T, ByteV);
- setPromoteTo(ISD::XOR, T, ByteV);
- }
-
- for (MVT T : LegalW) {
- // Custom-lower BUILD_VECTOR for vector pairs. The standard (target-
- // independent) handling of it would convert it to a load, which is
- // not always the optimal choice.
- setOperationAction(ISD::BUILD_VECTOR, T, Custom);
- // Make concat-vectors custom to handle concats of more than 2 vectors.
- setOperationAction(ISD::CONCAT_VECTORS, T, Custom);
-
- // Custom-lower these operations for pairs. Expand them into a concat
- // of the corresponding operations on individual vectors.
- setOperationAction(ISD::ANY_EXTEND, T, Custom);
- setOperationAction(ISD::SIGN_EXTEND, T, Custom);
- setOperationAction(ISD::ZERO_EXTEND, T, Custom);
- setOperationAction(ISD::SIGN_EXTEND_INREG, T, Custom);
- setOperationAction(ISD::ANY_EXTEND_VECTOR_INREG, T, Custom);
- setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, T, Legal);
- setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, T, Legal);
-
- setOperationAction(ISD::ADD, T, Legal);
- setOperationAction(ISD::SUB, T, Legal);
- setOperationAction(ISD::MUL, T, Custom);
- setOperationAction(ISD::MULHS, T, Custom);
- setOperationAction(ISD::MULHU, T, Custom);
- setOperationAction(ISD::AND, T, Custom);
- setOperationAction(ISD::OR, T, Custom);
- setOperationAction(ISD::XOR, T, Custom);
- setOperationAction(ISD::SETCC, T, Custom);
- setOperationAction(ISD::VSELECT, T, Custom);
- if (T != ByteW) {
- setOperationAction(ISD::SRA, T, Custom);
- setOperationAction(ISD::SHL, T, Custom);
- setOperationAction(ISD::SRL, T, Custom);
-
- // Promote all shuffles to operate on vectors of bytes.
- setPromoteTo(ISD::VECTOR_SHUFFLE, T, ByteW);
- }
-
- MVT BoolV = MVT::getVectorVT(MVT::i1, T.getVectorNumElements());
- setOperationAction(ISD::SETCC, BoolV, Custom);
- }
- }
+ if (Subtarget.useHVXOps())
+ initializeHVXLowering();
computeRegisterProperties(&HRI);
@@ -2444,6 +2287,8 @@ HexagonTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG)
unsigned VecLen = AM.size();
MVT VecTy = ty(Op);
+ assert(!Subtarget.isHVXVectorType(VecTy, true) &&
+ "HVX shuffles should be legal");
assert(VecTy.getSizeInBits() <= 64 && "Unexpected vector length");
SDValue Op0 = Op.getOperand(0);
@@ -2559,13 +2404,10 @@ HexagonTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG)
return SDValue();
}
-// Lower a vector shift. Try to convert
-// <VT> = SHL/SRA/SRL <VT> by <VT> to Hexagon specific
-// <VT> = SHL/SRA/SRL <VT> by <IT/i32>.
+// Create a Hexagon-specific node for shifting a vector by an integer.
SDValue
-HexagonTargetLowering::LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const {
- const SDLoc dl(Op);
-
+HexagonTargetLowering::getVectorShiftByInt(SDValue Op, SelectionDAG &DAG)
+ const {
if (auto *BVN = dyn_cast<BuildVectorSDNode>(Op.getOperand(1).getNode())) {
if (SDValue S = BVN->getSplatValue()) {
unsigned NewOpc;
@@ -2582,17 +2424,19 @@ HexagonTargetLowering::LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const {
default:
llvm_unreachable("Unexpected shift opcode");
}
- return DAG.getNode(NewOpc, dl, ty(Op), Op.getOperand(0), S);
+ return DAG.getNode(NewOpc, SDLoc(Op), ty(Op), Op.getOperand(0), S);
}
}
- if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(ty(Op)))
- return LowerHvxShift(Op, DAG);
-
return SDValue();
}
SDValue
+HexagonTargetLowering::LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const {
+ return getVectorShiftByInt(Op, DAG);
+}
+
+SDValue
HexagonTargetLowering::LowerBITCAST(SDValue Op, SelectionDAG &DAG) const {
MVT ResTy = ty(Op);
SDValue InpV = Op.getOperand(0);
@@ -2610,43 +2454,6 @@ HexagonTargetLowering::LowerBITCAST(SDValue Op, SelectionDAG &DAG) const {
return SDValue();
}
-// Any-, sign-, and zero-extends of boolean vectors to integer types are
-// all the same.
-
-SDValue
-HexagonTargetLowering::LowerANY_EXTEND(SDValue Op, SelectionDAG &DAG) const {
- // Lower any-extends of boolean vectors to sign-extends, since they
- // translate directly to Q2V. Zero-extending could also be done equally
- // fast, but Q2V is used/recognized in more places.
- // For all other vectors, use zero-extend.
- MVT ResTy = ty(Op);
- SDValue InpV = Op.getOperand(0);
- MVT ElemTy = ty(InpV).getVectorElementType();
- if (ElemTy == MVT::i1 && Subtarget.isHVXVectorType(ResTy))
- return LowerSIGN_EXTEND(Op, DAG);
- return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(Op), ResTy, InpV);
-}
-
-SDValue
-HexagonTargetLowering::LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const {
- MVT ResTy = ty(Op);
- SDValue InpV = Op.getOperand(0);
- MVT ElemTy = ty(InpV).getVectorElementType();
- if (ElemTy == MVT::i1 && Subtarget.isHVXVectorType(ResTy))
- return extendHvxVectorPred(InpV, SDLoc(Op), ty(Op), false, DAG);
- return Op;
-}
-
-SDValue
-HexagonTargetLowering::LowerZERO_EXTEND(SDValue Op, SelectionDAG &DAG) const {
- MVT ResTy = ty(Op);
- SDValue InpV = Op.getOperand(0);
- MVT ElemTy = ty(InpV).getVectorElementType();
- if (ElemTy == MVT::i1 && Subtarget.isHVXVectorType(ResTy))
- return extendHvxVectorPred(InpV, SDLoc(Op), ty(Op), true, DAG);
- return Op;
-}
-
bool
HexagonTargetLowering::getBuildVectorConstInts(ArrayRef<SDValue> Values,
MVT VecTy, SelectionDAG &DAG,
@@ -3022,9 +2829,6 @@ HexagonTargetLowering::getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG)
SDValue
HexagonTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
MVT VecTy = ty(Op);
- if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(VecTy, true))
- return LowerHvxBuildVector(Op, DAG);
-
unsigned BW = VecTy.getSizeInBits();
const SDLoc &dl(Op);
SmallVector<SDValue,8> Ops;
@@ -3064,9 +2868,6 @@ HexagonTargetLowering::LowerCONCAT_VECTORS(SDValue Op,
SelectionDAG &DAG) const {
MVT VecTy = ty(Op);
const SDLoc &dl(Op);
- if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(VecTy, true))
- return LowerHvxConcatVectors(Op, DAG);
-
if (VecTy.getSizeInBits() == 64) {
assert(Op.getNumOperands() == 2);
return DAG.getNode(HexagonISD::COMBINE, dl, VecTy, Op.getOperand(1),
@@ -3131,10 +2932,6 @@ SDValue
HexagonTargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op,
SelectionDAG &DAG) const {
SDValue Vec = Op.getOperand(0);
- MVT VecTy = ty(Vec);
- if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(VecTy, true))
- return LowerHvxExtractElement(Op, DAG);
-
MVT ElemTy = ty(Vec).getVectorElementType();
return extractVector(Vec, Op.getOperand(1), SDLoc(Op), ElemTy, ty(Op), DAG);
}
@@ -3142,31 +2939,20 @@ HexagonTargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op,
SDValue
HexagonTargetLowering::LowerEXTRACT_SUBVECTOR(SDValue Op,
SelectionDAG &DAG) const {
- SDValue Vec = Op.getOperand(0);
- MVT VecTy = ty(Vec);
- if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(VecTy, true))
- return LowerHvxExtractSubvector(Op, DAG);
-
- return extractVector(Vec, Op.getOperand(1), SDLoc(Op), ty(Op), ty(Op), DAG);
+ return extractVector(Op.getOperand(0), Op.getOperand(1), SDLoc(Op),
+ ty(Op), ty(Op), DAG);
}
SDValue
HexagonTargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
SelectionDAG &DAG) const {
- MVT VecTy = ty(Op);
- if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(VecTy, true))
- return LowerHvxInsertElement(Op, DAG);
-
return insertVector(Op.getOperand(0), Op.getOperand(1), Op.getOperand(2),
- SDLoc(Op), VecTy.getVectorElementType(), DAG);
+ SDLoc(Op), ty(Op).getVectorElementType(), DAG);
}
SDValue
HexagonTargetLowering::LowerINSERT_SUBVECTOR(SDValue Op,
SelectionDAG &DAG) const {
- if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(ty(Op), true))
- return LowerHvxInsertSubvector(Op, DAG);
-
SDValue ValV = Op.getOperand(1);
return insertVector(Op.getOperand(0), ValV, Op.getOperand(2),
SDLoc(Op), ty(ValV), DAG);
OpenPOWER on IntegriCloud