summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-12-14 21:28:48 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-12-14 21:28:48 +0000
commita9bb60c600bfec513cc00b7b126dfade550a3356 (patch)
tree0b74e6bede45da98327650d049972ab4a92c99c1 /lib
parente1acb56f11946214ba2903e25c7cce3d9e5f7791 (diff)
[Hexagon] Generate HVX code for comparisons and selects
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320744 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.cpp17
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.h1
-rw-r--r--lib/Target/Hexagon/HexagonISelLoweringHVX.cpp71
-rw-r--r--lib/Target/Hexagon/HexagonPatterns.td17
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.td12
5 files changed, 111 insertions, 7 deletions
diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp
index 0b7765c4391..be6d13a9fd0 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -1272,6 +1272,9 @@ SDValue HexagonTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
SDValue LHS = Op.getOperand(0);
SDValue RHS = Op.getOperand(1);
+ if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(ty(LHS)))
+ return LowerHvxSetCC(Op, DAG);
+
SDValue Cmp = Op.getOperand(2);
ISD::CondCode CC = cast<CondCodeSDNode>(Cmp)->get();
@@ -1732,6 +1735,9 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
addRegisterClass(MVT::v128i8, &Hexagon::HvxWRRegClass);
addRegisterClass(MVT::v64i16, &Hexagon::HvxWRRegClass);
addRegisterClass(MVT::v32i32, &Hexagon::HvxWRRegClass);
+ 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);
@@ -1740,6 +1746,9 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
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);
}
}
@@ -2001,10 +2010,12 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
setIndexedLoadAction(ISD::POST_INC, T, Legal);
setIndexedStoreAction(ISD::POST_INC, T, Legal);
- setOperationAction(ISD::ADD, T, Legal);
- setOperationAction(ISD::SUB, T, Legal);
- setOperationAction(ISD::MUL, T, Custom);
+ setOperationAction(ISD::ADD, T, Legal);
+ setOperationAction(ISD::SUB, T, Legal);
+ setOperationAction(ISD::VSELECT, T, Legal);
+ setOperationAction(ISD::MUL, T, Custom);
+ setOperationAction(ISD::SETCC, T, Custom);
setOperationAction(ISD::BUILD_VECTOR, T, Custom);
setOperationAction(ISD::INSERT_SUBVECTOR, T, Custom);
setOperationAction(ISD::INSERT_VECTOR_ELT, T, Custom);
diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h
index fca48d4cca6..0a5771ec883 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/lib/Target/Hexagon/HexagonISelLowering.h
@@ -347,6 +347,7 @@ namespace HexagonISD {
SDValue LowerHvxExtractSubvector(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerHvxInsertSubvector(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerHvxMul(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerHvxSetCC(SDValue Op, SelectionDAG &DAG) const;
std::pair<const TargetRegisterClass*, uint8_t>
findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
diff --git a/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
index cfa0c003e41..652dffce841 100644
--- a/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
+++ b/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
@@ -383,3 +383,74 @@ HexagonTargetLowering::LowerHvxMul(SDValue Op, SelectionDAG &DAG) const {
}
return SDValue();
}
+
+SDValue
+HexagonTargetLowering::LowerHvxSetCC(SDValue Op, SelectionDAG &DAG) const {
+ MVT VecTy = ty(Op.getOperand(0));
+ assert(VecTy == ty(Op.getOperand(1)));
+
+ SDValue Cmp = Op.getOperand(2);
+ ISD::CondCode CC = cast<CondCodeSDNode>(Cmp)->get();
+ bool Negate = false, Swap = false;
+
+ // HVX has instructions for SETEQ, SETGT, SETUGT. The other comparisons
+ // can be arranged as operand-swapped/negated versions of these. Since
+ // the generated code will have the original CC expressed as
+ // (negate (swap-op NewCmp)),
+ // the condition code for the NewCmp should be calculated from the original
+ // CC by applying these operations in the reverse order.
+
+ switch (CC) {
+ case ISD::SETNE: // !eq
+ case ISD::SETLE: // !gt
+ case ISD::SETGE: // !lt
+ case ISD::SETULE: // !ugt
+ case ISD::SETUGE: // !ult
+ CC = ISD::getSetCCInverse(CC, true);
+ Negate = true;
+ break;
+ default:
+ break;
+ }
+
+ switch (CC) {
+ case ISD::SETLT: // swap gt
+ case ISD::SETULT: // swap ugt
+ CC = ISD::getSetCCSwappedOperands(CC);
+ Swap = true;
+ break;
+ default:
+ break;
+ }
+
+ assert(CC == ISD::SETEQ || CC == ISD::SETGT || CC == ISD::SETUGT);
+
+ MVT ElemTy = VecTy.getVectorElementType();
+ unsigned ElemWidth = ElemTy.getSizeInBits();
+ assert(isPowerOf2_32(ElemWidth));
+
+ auto getIdx = [] (unsigned Code) {
+ static const unsigned Idx[] = { ISD::SETEQ, ISD::SETGT, ISD::SETUGT };
+ for (unsigned I = 0, E = array_lengthof(Idx); I != E; ++I)
+ if (Code == Idx[I])
+ return I;
+ llvm_unreachable("Unhandled CondCode");
+ };
+
+ static unsigned OpcTable[3][3] = {
+ // SETEQ SETGT, SETUGT
+ /* Byte */ { Hexagon::V6_veqb, Hexagon::V6_vgtb, Hexagon::V6_vgtub },
+ /* Half */ { Hexagon::V6_veqh, Hexagon::V6_vgth, Hexagon::V6_vgtuh },
+ /* Word */ { Hexagon::V6_veqw, Hexagon::V6_vgtw, Hexagon::V6_vgtuw }
+ };
+
+ unsigned CmpOpc = OpcTable[Log2_32(ElemWidth)-3][getIdx(CC)];
+
+ MVT ResTy = ty(Op);
+ const SDLoc &dl(Op);
+ SDValue OpL = Swap ? Op.getOperand(1) : Op.getOperand(0);
+ SDValue OpR = Swap ? Op.getOperand(0) : Op.getOperand(1);
+ SDValue CmpV = getNode(CmpOpc, dl, ResTy, {OpL, OpR}, DAG);
+ return Negate ? getNode(Hexagon::V6_pred_not, dl, ResTy, {CmpV}, DAG)
+ : CmpV;
+}
diff --git a/lib/Target/Hexagon/HexagonPatterns.td b/lib/Target/Hexagon/HexagonPatterns.td
index e6c8ad4deea..8ed9a8d01ce 100644
--- a/lib/Target/Hexagon/HexagonPatterns.td
+++ b/lib/Target/Hexagon/HexagonPatterns.td
@@ -88,6 +88,10 @@ def V8I8: PatLeaf<(v8i8 DoubleRegs:$R)>;
def V4I16: PatLeaf<(v4i16 DoubleRegs:$R)>;
def V2I32: PatLeaf<(v2i32 DoubleRegs:$R)>;
+def HQ8: PatLeaf<(VecQ8 HvxQR:$R)>;
+def HQ16: PatLeaf<(VecQ16 HvxQR:$R)>;
+def HQ32: PatLeaf<(VecQ32 HvxQR:$R)>;
+
def HVI8: PatLeaf<(VecI8 HvxVR:$R)>;
def HVI16: PatLeaf<(VecI16 HvxVR:$R)>;
def HVI32: PatLeaf<(VecI32 HvxVR:$R)>;
@@ -2932,7 +2936,14 @@ let Predicates = [UseHVX] in {
def: Pat<(sub HVI16:$Vs, HVI16:$Vt), (V6_vsubh HvxVR:$Vs, HvxVR:$Vt)>;
def: Pat<(sub HVI32:$Vs, HVI32:$Vt), (V6_vsubw HvxVR:$Vs, HvxVR:$Vt)>;
- def: Pat<(and HVI8:$Vs, HVI8:$Vt), (V6_vand HvxVR:$Vs, HvxVR:$Vt)>;
- def: Pat<(or HVI8:$Vs, HVI8:$Vt), (V6_vor HvxVR:$Vs, HvxVR:$Vt)>;
- def: Pat<(xor HVI8:$Vs, HVI8:$Vt), (V6_vxor HvxVR:$Vs, HvxVR:$Vt)>;
+ def: Pat<(and HVI8:$Vs, HVI8:$Vt), (V6_vand HvxVR:$Vs, HvxVR:$Vt)>;
+ def: Pat<(or HVI8:$Vs, HVI8:$Vt), (V6_vor HvxVR:$Vs, HvxVR:$Vt)>;
+ def: Pat<(xor HVI8:$Vs, HVI8:$Vt), (V6_vxor HvxVR:$Vs, HvxVR:$Vt)>;
+
+ def: Pat<(vselect HQ8:$Qu, HVI8:$Vs, HVI8:$Vt),
+ (V6_vmux HvxQR:$Qu, HvxVR:$Vs, HvxVR:$Vt)>;
+ def: Pat<(vselect HQ16:$Qu, HVI16:$Vs, HVI16:$Vt),
+ (V6_vmux HvxQR:$Qu, HvxVR:$Vs, HvxVR:$Vt)>;
+ def: Pat<(vselect HQ32:$Qu, HVI32:$Vs, HVI32:$Vt),
+ (V6_vmux HvxQR:$Qu, HvxVR:$Vs, HvxVR:$Vt)>;
}
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.td b/lib/Target/Hexagon/HexagonRegisterInfo.td
index aa8ecb8d314..2ceed70c249 100644
--- a/lib/Target/Hexagon/HexagonRegisterInfo.td
+++ b/lib/Target/Hexagon/HexagonRegisterInfo.td
@@ -225,6 +225,15 @@ def VecPI16
def VecPI32
: ValueTypeByHwMode<[Hvx64, Hvx64old, Hvx128, Hvx128old, DefaultMode],
[v32i32, v32i32, v64i32, v64i32, v32i32]>;
+def VecQ8
+ : ValueTypeByHwMode<[Hvx64, Hvx64old, Hvx128, Hvx128old, DefaultMode],
+ [v64i1, v64i1, v128i1, v128i1, v64i1]>;
+def VecQ16
+ : ValueTypeByHwMode<[Hvx64, Hvx64old, Hvx128, Hvx128old, DefaultMode],
+ [v32i1, v32i1, v64i1, v64i1, v32i1]>;
+def VecQ32
+ : ValueTypeByHwMode<[Hvx64, Hvx64old, Hvx128, Hvx128old, DefaultMode],
+ [v16i1, v16i1, v32i1, v32i1, v16i1]>;
// HVX register classes
@@ -263,7 +272,8 @@ def HvxWR : RegisterClass<"Hexagon", [VecPI8, VecPI16, VecPI32], 1024,
[RegInfo<1024,1024,1024>, RegInfo<2048,2048,2048>, RegInfo<1024,1024,1024>]>;
}
-def HvxQR : RegisterClass<"Hexagon", [VecI1], 512, (add Q0, Q1, Q2, Q3)> {
+def HvxQR : RegisterClass<"Hexagon", [VecI1, VecQ8, VecQ16, VecQ32], 512,
+ (add Q0, Q1, Q2, Q3)> {
let RegInfos = RegInfoByHwMode<[Hvx64, Hvx128, DefaultMode],
[RegInfo<512,512,512>, RegInfo<1024,1024,1024>, RegInfo<512,512,512>]>;
}