[Hexagon] Generate vector min/max for HVX
llvm-svn: 369014
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index 7ddc33e..eaae3f2 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -2877,6 +2877,17 @@
}
}
+SDValue
+HexagonTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
+ const {
+ SDValue Op(N, 0);
+ if (isHvxOperation(Op)) {
+ if (SDValue V = PerformHvxDAGCombine(N, DCI))
+ return V;
+ }
+ return SDValue();
+}
+
/// Returns relocation base for the given PIC jumptable.
SDValue
HexagonTargetLowering::getPICJumpTableRelocBase(SDValue Table,
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
index e922240..4bc49dd 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
@@ -223,6 +223,8 @@
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const override;
+ SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
+
bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
unsigned getRegisterByName(const char* RegName, EVT VT,
@@ -301,7 +303,8 @@
const AttributeList &FuncAttributes) const override;
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
- unsigned Align, MachineMemOperand::Flags Flags, bool *Fast) const override;
+ unsigned Align, MachineMemOperand::Flags Flags, bool *Fast)
+ const override;
/// Returns relocation base for the given PIC jumptable.
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
@@ -458,6 +461,8 @@
bool isHvxOperation(SDValue Op) const;
SDValue LowerHvxOperation(SDValue Op, SelectionDAG &DAG) const;
+
+ SDValue PerformHvxDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
};
} // end namespace llvm
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
index 345c657..bc8a995 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
@@ -193,6 +193,8 @@
setOperationAction(ISD::OR, BoolV, Legal);
setOperationAction(ISD::XOR, BoolV, Legal);
}
+
+ setTargetDAGCombine(ISD::VSELECT);
}
SDValue
@@ -1580,6 +1582,28 @@
llvm_unreachable("Unhandled HVX operation");
}
+SDValue
+HexagonTargetLowering::PerformHvxDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
+ const {
+ const SDLoc &dl(N);
+ SDValue Op(N, 0);
+
+ unsigned Opc = Op.getOpcode();
+ if (Opc == ISD::VSELECT) {
+ // (vselect (xor x, qtrue), v0, v1) -> (vselect x, v1, v0)
+ SDValue Cond = Op.getOperand(0);
+ if (Cond->getOpcode() == ISD::XOR) {
+ SDValue C0 = Cond.getOperand(0), C1 = Cond.getOperand(1);
+ if (C1->getOpcode() == HexagonISD::QTRUE) {
+ SDValue VSel = DCI.DAG.getNode(ISD::VSELECT, dl, ty(Op), C0,
+ Op.getOperand(2), Op.getOperand(1));
+ return VSel;
+ }
+ }
+ }
+ return SDValue();
+}
+
bool
HexagonTargetLowering::isHvxOperation(SDValue Op) const {
// If the type of the result, or any operand type are HVX vector types,
diff --git a/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td b/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
index a4cfca9..4f3d872 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
@@ -259,6 +259,31 @@
class Vnot<ValueType VecTy>
: PatFrag<(ops node:$Vs), (xor $Vs, Vneg1<VecTy>)>;
+multiclass VMinMax_pat<InstHexagon MinInst, InstHexagon MaxInst, PatFrag CmpOp,
+ ValueType CmpType, PatFrag CmpPred> {
+ def: Pat<(vselect (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)),
+ CmpPred:$Vt, CmpPred:$Vs),
+ (MinInst CmpPred:$Vs, CmpPred:$Vt)>;
+ def: Pat<(vselect (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)),
+ CmpPred:$Vs, CmpPred:$Vt),
+ (MaxInst CmpPred:$Vs, CmpPred:$Vt)>;
+}
+
+let Predicates = [UseHVX] in {
+ let AddedComplexity = 220 in {
+ defm: VMinMax_pat<V6_vminb, V6_vmaxb, setgt, VecQ8, HVI8>;
+ defm: VMinMax_pat<V6_vminb, V6_vmaxb, setge, VecQ8, HVI8>;
+ defm: VMinMax_pat<V6_vminub, V6_vmaxub, setugt, VecQ8, HVI8>;
+ defm: VMinMax_pat<V6_vminub, V6_vmaxub, setuge, VecQ8, HVI8>;
+ defm: VMinMax_pat<V6_vminh, V6_vmaxh, setgt, VecQ16, HVI16>;
+ defm: VMinMax_pat<V6_vminh, V6_vmaxh, setge, VecQ16, HVI16>;
+ defm: VMinMax_pat<V6_vminuh, V6_vmaxuh, setugt, VecQ16, HVI16>;
+ defm: VMinMax_pat<V6_vminuh, V6_vmaxuh, setuge, VecQ16, HVI16>;
+ defm: VMinMax_pat<V6_vminw, V6_vmaxw, setgt, VecQ32, HVI32>;
+ defm: VMinMax_pat<V6_vminw, V6_vmaxw, setge, VecQ32, HVI32>;
+ }
+}
+
let Predicates = [UseHVX] in {
let AddedComplexity = 200 in {
def: Pat<(Vnot<VecI8> HVI8:$Vs), (V6_vnot HvxVR:$Vs)>;