Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit a9bb60c

Browse files
author
Krzysztof Parzyszek
committed
[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
1 parent e1acb56 commit a9bb60c

File tree

7 files changed

+699
-7
lines changed

7 files changed

+699
-7
lines changed

lib/Target/Hexagon/HexagonISelLowering.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,9 @@ SDValue HexagonTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
12721272

12731273
SDValue LHS = Op.getOperand(0);
12741274
SDValue RHS = Op.getOperand(1);
1275+
if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(ty(LHS)))
1276+
return LowerHvxSetCC(Op, DAG);
1277+
12751278
SDValue Cmp = Op.getOperand(2);
12761279
ISD::CondCode CC = cast<CondCodeSDNode>(Cmp)->get();
12771280

@@ -1732,6 +1735,9 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
17321735
addRegisterClass(MVT::v128i8, &Hexagon::HvxWRRegClass);
17331736
addRegisterClass(MVT::v64i16, &Hexagon::HvxWRRegClass);
17341737
addRegisterClass(MVT::v32i32, &Hexagon::HvxWRRegClass);
1738+
addRegisterClass(MVT::v16i1, &Hexagon::HvxQRRegClass);
1739+
addRegisterClass(MVT::v32i1, &Hexagon::HvxQRRegClass);
1740+
addRegisterClass(MVT::v64i1, &Hexagon::HvxQRRegClass);
17351741
addRegisterClass(MVT::v512i1, &Hexagon::HvxQRRegClass);
17361742
} else if (Subtarget.useHVX128BOps()) {
17371743
addRegisterClass(MVT::v128i8, &Hexagon::HvxVRRegClass);
@@ -1740,6 +1746,9 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
17401746
addRegisterClass(MVT::v256i8, &Hexagon::HvxWRRegClass);
17411747
addRegisterClass(MVT::v128i16, &Hexagon::HvxWRRegClass);
17421748
addRegisterClass(MVT::v64i32, &Hexagon::HvxWRRegClass);
1749+
addRegisterClass(MVT::v32i1, &Hexagon::HvxQRRegClass);
1750+
addRegisterClass(MVT::v64i1, &Hexagon::HvxQRRegClass);
1751+
addRegisterClass(MVT::v128i1, &Hexagon::HvxQRRegClass);
17431752
addRegisterClass(MVT::v1024i1, &Hexagon::HvxQRRegClass);
17441753
}
17451754
}
@@ -2001,10 +2010,12 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
20012010
setIndexedLoadAction(ISD::POST_INC, T, Legal);
20022011
setIndexedStoreAction(ISD::POST_INC, T, Legal);
20032012

2004-
setOperationAction(ISD::ADD, T, Legal);
2005-
setOperationAction(ISD::SUB, T, Legal);
2006-
setOperationAction(ISD::MUL, T, Custom);
2013+
setOperationAction(ISD::ADD, T, Legal);
2014+
setOperationAction(ISD::SUB, T, Legal);
2015+
setOperationAction(ISD::VSELECT, T, Legal);
20072016

2017+
setOperationAction(ISD::MUL, T, Custom);
2018+
setOperationAction(ISD::SETCC, T, Custom);
20082019
setOperationAction(ISD::BUILD_VECTOR, T, Custom);
20092020
setOperationAction(ISD::INSERT_SUBVECTOR, T, Custom);
20102021
setOperationAction(ISD::INSERT_VECTOR_ELT, T, Custom);

lib/Target/Hexagon/HexagonISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ namespace HexagonISD {
347347
SDValue LowerHvxExtractSubvector(SDValue Op, SelectionDAG &DAG) const;
348348
SDValue LowerHvxInsertSubvector(SDValue Op, SelectionDAG &DAG) const;
349349
SDValue LowerHvxMul(SDValue Op, SelectionDAG &DAG) const;
350+
SDValue LowerHvxSetCC(SDValue Op, SelectionDAG &DAG) const;
350351

351352
std::pair<const TargetRegisterClass*, uint8_t>
352353
findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)

lib/Target/Hexagon/HexagonISelLoweringHVX.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,3 +383,74 @@ HexagonTargetLowering::LowerHvxMul(SDValue Op, SelectionDAG &DAG) const {
383383
}
384384
return SDValue();
385385
}
386+
387+
SDValue
388+
HexagonTargetLowering::LowerHvxSetCC(SDValue Op, SelectionDAG &DAG) const {
389+
MVT VecTy = ty(Op.getOperand(0));
390+
assert(VecTy == ty(Op.getOperand(1)));
391+
392+
SDValue Cmp = Op.getOperand(2);
393+
ISD::CondCode CC = cast<CondCodeSDNode>(Cmp)->get();
394+
bool Negate = false, Swap = false;
395+
396+
// HVX has instructions for SETEQ, SETGT, SETUGT. The other comparisons
397+
// can be arranged as operand-swapped/negated versions of these. Since
398+
// the generated code will have the original CC expressed as
399+
// (negate (swap-op NewCmp)),
400+
// the condition code for the NewCmp should be calculated from the original
401+
// CC by applying these operations in the reverse order.
402+
403+
switch (CC) {
404+
case ISD::SETNE: // !eq
405+
case ISD::SETLE: // !gt
406+
case ISD::SETGE: // !lt
407+
case ISD::SETULE: // !ugt
408+
case ISD::SETUGE: // !ult
409+
CC = ISD::getSetCCInverse(CC, true);
410+
Negate = true;
411+
break;
412+
default:
413+
break;
414+
}
415+
416+
switch (CC) {
417+
case ISD::SETLT: // swap gt
418+
case ISD::SETULT: // swap ugt
419+
CC = ISD::getSetCCSwappedOperands(CC);
420+
Swap = true;
421+
break;
422+
default:
423+
break;
424+
}
425+
426+
assert(CC == ISD::SETEQ || CC == ISD::SETGT || CC == ISD::SETUGT);
427+
428+
MVT ElemTy = VecTy.getVectorElementType();
429+
unsigned ElemWidth = ElemTy.getSizeInBits();
430+
assert(isPowerOf2_32(ElemWidth));
431+
432+
auto getIdx = [] (unsigned Code) {
433+
static const unsigned Idx[] = { ISD::SETEQ, ISD::SETGT, ISD::SETUGT };
434+
for (unsigned I = 0, E = array_lengthof(Idx); I != E; ++I)
435+
if (Code == Idx[I])
436+
return I;
437+
llvm_unreachable("Unhandled CondCode");
438+
};
439+
440+
static unsigned OpcTable[3][3] = {
441+
// SETEQ SETGT, SETUGT
442+
/* Byte */ { Hexagon::V6_veqb, Hexagon::V6_vgtb, Hexagon::V6_vgtub },
443+
/* Half */ { Hexagon::V6_veqh, Hexagon::V6_vgth, Hexagon::V6_vgtuh },
444+
/* Word */ { Hexagon::V6_veqw, Hexagon::V6_vgtw, Hexagon::V6_vgtuw }
445+
};
446+
447+
unsigned CmpOpc = OpcTable[Log2_32(ElemWidth)-3][getIdx(CC)];
448+
449+
MVT ResTy = ty(Op);
450+
const SDLoc &dl(Op);
451+
SDValue OpL = Swap ? Op.getOperand(1) : Op.getOperand(0);
452+
SDValue OpR = Swap ? Op.getOperand(0) : Op.getOperand(1);
453+
SDValue CmpV = getNode(CmpOpc, dl, ResTy, {OpL, OpR}, DAG);
454+
return Negate ? getNode(Hexagon::V6_pred_not, dl, ResTy, {CmpV}, DAG)
455+
: CmpV;
456+
}

lib/Target/Hexagon/HexagonPatterns.td

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ def V8I8: PatLeaf<(v8i8 DoubleRegs:$R)>;
8888
def V4I16: PatLeaf<(v4i16 DoubleRegs:$R)>;
8989
def V2I32: PatLeaf<(v2i32 DoubleRegs:$R)>;
9090

91+
def HQ8: PatLeaf<(VecQ8 HvxQR:$R)>;
92+
def HQ16: PatLeaf<(VecQ16 HvxQR:$R)>;
93+
def HQ32: PatLeaf<(VecQ32 HvxQR:$R)>;
94+
9195
def HVI8: PatLeaf<(VecI8 HvxVR:$R)>;
9296
def HVI16: PatLeaf<(VecI16 HvxVR:$R)>;
9397
def HVI32: PatLeaf<(VecI32 HvxVR:$R)>;
@@ -2932,7 +2936,14 @@ let Predicates = [UseHVX] in {
29322936
def: Pat<(sub HVI16:$Vs, HVI16:$Vt), (V6_vsubh HvxVR:$Vs, HvxVR:$Vt)>;
29332937
def: Pat<(sub HVI32:$Vs, HVI32:$Vt), (V6_vsubw HvxVR:$Vs, HvxVR:$Vt)>;
29342938

2935-
def: Pat<(and HVI8:$Vs, HVI8:$Vt), (V6_vand HvxVR:$Vs, HvxVR:$Vt)>;
2936-
def: Pat<(or HVI8:$Vs, HVI8:$Vt), (V6_vor HvxVR:$Vs, HvxVR:$Vt)>;
2937-
def: Pat<(xor HVI8:$Vs, HVI8:$Vt), (V6_vxor HvxVR:$Vs, HvxVR:$Vt)>;
2939+
def: Pat<(and HVI8:$Vs, HVI8:$Vt), (V6_vand HvxVR:$Vs, HvxVR:$Vt)>;
2940+
def: Pat<(or HVI8:$Vs, HVI8:$Vt), (V6_vor HvxVR:$Vs, HvxVR:$Vt)>;
2941+
def: Pat<(xor HVI8:$Vs, HVI8:$Vt), (V6_vxor HvxVR:$Vs, HvxVR:$Vt)>;
2942+
2943+
def: Pat<(vselect HQ8:$Qu, HVI8:$Vs, HVI8:$Vt),
2944+
(V6_vmux HvxQR:$Qu, HvxVR:$Vs, HvxVR:$Vt)>;
2945+
def: Pat<(vselect HQ16:$Qu, HVI16:$Vs, HVI16:$Vt),
2946+
(V6_vmux HvxQR:$Qu, HvxVR:$Vs, HvxVR:$Vt)>;
2947+
def: Pat<(vselect HQ32:$Qu, HVI32:$Vs, HVI32:$Vt),
2948+
(V6_vmux HvxQR:$Qu, HvxVR:$Vs, HvxVR:$Vt)>;
29382949
}

lib/Target/Hexagon/HexagonRegisterInfo.td

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,15 @@ def VecPI16
225225
def VecPI32
226226
: ValueTypeByHwMode<[Hvx64, Hvx64old, Hvx128, Hvx128old, DefaultMode],
227227
[v32i32, v32i32, v64i32, v64i32, v32i32]>;
228+
def VecQ8
229+
: ValueTypeByHwMode<[Hvx64, Hvx64old, Hvx128, Hvx128old, DefaultMode],
230+
[v64i1, v64i1, v128i1, v128i1, v64i1]>;
231+
def VecQ16
232+
: ValueTypeByHwMode<[Hvx64, Hvx64old, Hvx128, Hvx128old, DefaultMode],
233+
[v32i1, v32i1, v64i1, v64i1, v32i1]>;
234+
def VecQ32
235+
: ValueTypeByHwMode<[Hvx64, Hvx64old, Hvx128, Hvx128old, DefaultMode],
236+
[v16i1, v16i1, v32i1, v32i1, v16i1]>;
228237

229238
// HVX register classes
230239

@@ -263,7 +272,8 @@ def HvxWR : RegisterClass<"Hexagon", [VecPI8, VecPI16, VecPI32], 1024,
263272
[RegInfo<1024,1024,1024>, RegInfo<2048,2048,2048>, RegInfo<1024,1024,1024>]>;
264273
}
265274

266-
def HvxQR : RegisterClass<"Hexagon", [VecI1], 512, (add Q0, Q1, Q2, Q3)> {
275+
def HvxQR : RegisterClass<"Hexagon", [VecI1, VecQ8, VecQ16, VecQ32], 512,
276+
(add Q0, Q1, Q2, Q3)> {
267277
let RegInfos = RegInfoByHwMode<[Hvx64, Hvx128, DefaultMode],
268278
[RegInfo<512,512,512>, RegInfo<1024,1024,1024>, RegInfo<512,512,512>]>;
269279
}

0 commit comments

Comments
 (0)