forked from OSchip/llvm-project
[Hexagon] Custom-widen SETCC's operands
The result cannot be widened, unfortunately, because widening vNi1 would depend on the context in which it appears (i.e. the type alone is not sufficient to tell if it needs to be widened).
This commit is contained in:
parent
35c9baa11e
commit
a90214760d
|
@ -486,6 +486,7 @@ private:
|
|||
SDValue SplitHvxMemOp(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue WidenHvxLoad(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue WidenHvxStore(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue WidenHvxSetCC(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue WidenHvxExtend(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue WidenHvxTruncate(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
|
|
|
@ -51,6 +51,13 @@ HexagonTargetLowering::initializeHVXLowering() {
|
|||
addRegisterClass(MVT::v256i8, &Hexagon::HvxWRRegClass);
|
||||
addRegisterClass(MVT::v128i16, &Hexagon::HvxWRRegClass);
|
||||
addRegisterClass(MVT::v64i32, &Hexagon::HvxWRRegClass);
|
||||
// Treat v16i1 as a legal type, since there is no way to widen vNi1:
|
||||
// the validity of vNi1 may depend on how the result was obtained.
|
||||
// For example v32i1 is ok when it's a result of comparing v32i32,
|
||||
// but would need to be widened if it came from comparing v32i16.
|
||||
// This precludes using getTypeToTransformTo, since it doesn't have
|
||||
// the necessary context to decide what to do.
|
||||
addRegisterClass(MVT::v16i1, &Hexagon::HvxQRRegClass);
|
||||
addRegisterClass(MVT::v32i1, &Hexagon::HvxQRRegClass);
|
||||
addRegisterClass(MVT::v64i1, &Hexagon::HvxQRRegClass);
|
||||
addRegisterClass(MVT::v128i1, &Hexagon::HvxQRRegClass);
|
||||
|
@ -241,7 +248,6 @@ HexagonTargetLowering::initializeHVXLowering() {
|
|||
}
|
||||
|
||||
// Handle store widening for short vectors.
|
||||
std::vector<MVT> ShortTys;
|
||||
unsigned HwLen = Subtarget.getVectorLength();
|
||||
for (MVT ElemTy : Subtarget.getHVXElementTypes()) {
|
||||
if (ElemTy == MVT::i1)
|
||||
|
@ -254,6 +260,7 @@ HexagonTargetLowering::initializeHVXLowering() {
|
|||
if (Action == TargetLoweringBase::TypeWidenVector) {
|
||||
setOperationAction(ISD::LOAD, VecTy, Custom);
|
||||
setOperationAction(ISD::STORE, VecTy, Custom);
|
||||
setOperationAction(ISD::SETCC, VecTy, Custom);
|
||||
setOperationAction(ISD::TRUNCATE, VecTy, Custom);
|
||||
setOperationAction(ISD::ANY_EXTEND, VecTy, Custom);
|
||||
setOperationAction(ISD::SIGN_EXTEND, VecTy, Custom);
|
||||
|
@ -1932,6 +1939,27 @@ HexagonTargetLowering::WidenHvxStore(SDValue Op, SelectionDAG &DAG) const {
|
|||
MemOp, ISD::UNINDEXED, false, false);
|
||||
}
|
||||
|
||||
SDValue
|
||||
HexagonTargetLowering::WidenHvxSetCC(SDValue Op, SelectionDAG &DAG) const {
|
||||
const SDLoc &dl(Op);
|
||||
SDValue Op0 = Op.getOperand(0), Op1 = Op.getOperand(1);
|
||||
MVT ElemTy = ty(Op0).getVectorElementType();
|
||||
unsigned HwLen = Subtarget.getVectorLength();
|
||||
|
||||
unsigned WideOpLen = (8 * HwLen) / ElemTy.getSizeInBits();
|
||||
assert(WideOpLen * ElemTy.getSizeInBits() == 8 * HwLen);
|
||||
MVT WideOpTy = MVT::getVectorVT(ElemTy, WideOpLen);
|
||||
|
||||
SDValue WideOp0 = appendUndef(Op0, WideOpTy, DAG);
|
||||
SDValue WideOp1 = appendUndef(Op1, WideOpTy, DAG);
|
||||
EVT ResTy =
|
||||
getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), WideOpTy);
|
||||
SDValue SetCC = DAG.getNode(ISD::SETCC, dl, ResTy,
|
||||
{WideOp0, WideOp1, Op.getOperand(2)});
|
||||
return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, ty(Op),
|
||||
{SetCC, getZero(dl, MVT::i32, DAG)});
|
||||
}
|
||||
|
||||
SDValue
|
||||
HexagonTargetLowering::WidenHvxExtend(SDValue Op, SelectionDAG &DAG) const {
|
||||
const SDLoc &dl(Op);
|
||||
|
@ -2102,20 +2130,28 @@ HexagonTargetLowering::LowerHvxOperationWrapper(SDNode *N,
|
|||
case ISD::ANY_EXTEND:
|
||||
case ISD::SIGN_EXTEND:
|
||||
case ISD::ZERO_EXTEND:
|
||||
assert(shouldWidenToHvx(ty(Op.getOperand(0)), DAG) && "Not widening?");
|
||||
if (SDValue T = WidenHvxExtend(Op, DAG))
|
||||
Results.push_back(T);
|
||||
if (shouldWidenToHvx(ty(Op.getOperand(0)), DAG)) {
|
||||
if (SDValue T = WidenHvxExtend(Op, DAG))
|
||||
Results.push_back(T);
|
||||
}
|
||||
break;
|
||||
case ISD::SETCC:
|
||||
if (shouldWidenToHvx(ty(Op.getOperand(0)), DAG)) {
|
||||
if (SDValue T = WidenHvxSetCC(Op, DAG))
|
||||
Results.push_back(T);
|
||||
}
|
||||
break;
|
||||
case ISD::TRUNCATE:
|
||||
assert(shouldWidenToHvx(ty(Op.getOperand(0)), DAG) && "Not widening?");
|
||||
if (SDValue T = WidenHvxTruncate(Op, DAG))
|
||||
Results.push_back(T);
|
||||
if (shouldWidenToHvx(ty(Op.getOperand(0)), DAG)) {
|
||||
if (SDValue T = WidenHvxTruncate(Op, DAG))
|
||||
Results.push_back(T);
|
||||
}
|
||||
break;
|
||||
case ISD::STORE: {
|
||||
assert(shouldWidenToHvx(ty(cast<StoreSDNode>(N)->getValue()), DAG) &&
|
||||
"Not widening?");
|
||||
SDValue Store = WidenHvxStore(SDValue(N, 0), DAG);
|
||||
Results.push_back(Store);
|
||||
if (shouldWidenToHvx(ty(cast<StoreSDNode>(N)->getValue()), DAG)) {
|
||||
SDValue Store = WidenHvxStore(Op, DAG);
|
||||
Results.push_back(Store);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISD::MLOAD:
|
||||
|
@ -2132,6 +2168,8 @@ HexagonTargetLowering::LowerHvxOperationWrapper(SDNode *N,
|
|||
Results.push_back(S);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2144,21 +2182,24 @@ HexagonTargetLowering::ReplaceHvxNodeResults(SDNode *N,
|
|||
case ISD::ANY_EXTEND:
|
||||
case ISD::SIGN_EXTEND:
|
||||
case ISD::ZERO_EXTEND:
|
||||
assert(shouldWidenToHvx(ty(Op), DAG) && "Not widening?");
|
||||
if (SDValue T = WidenHvxExtend(Op, DAG))
|
||||
Results.push_back(T);
|
||||
if (shouldWidenToHvx(ty(Op), DAG)) {
|
||||
if (SDValue T = WidenHvxExtend(Op, DAG))
|
||||
Results.push_back(T);
|
||||
}
|
||||
break;
|
||||
case ISD::TRUNCATE:
|
||||
assert(shouldWidenToHvx(ty(Op), DAG) && "Not widening?");
|
||||
if (SDValue T = WidenHvxTruncate(Op, DAG))
|
||||
Results.push_back(T);
|
||||
if (shouldWidenToHvx(ty(Op), DAG)) {
|
||||
if (SDValue T = WidenHvxTruncate(Op, DAG))
|
||||
Results.push_back(T);
|
||||
}
|
||||
break;
|
||||
case ISD::LOAD: {
|
||||
assert(shouldWidenToHvx(ty(Op), DAG) && "Not widening?");
|
||||
SDValue Load = WidenHvxLoad(Op, DAG);
|
||||
assert(Load->getOpcode() == ISD::MERGE_VALUES);
|
||||
Results.push_back(Load.getOperand(0));
|
||||
Results.push_back(Load.getOperand(1));
|
||||
if (shouldWidenToHvx(ty(Op), DAG)) {
|
||||
SDValue Load = WidenHvxLoad(Op, DAG);
|
||||
assert(Load->getOpcode() == ISD::MERGE_VALUES);
|
||||
Results.push_back(Load.getOperand(0));
|
||||
Results.push_back(Load.getOperand(1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISD::BITCAST:
|
||||
|
@ -2180,7 +2221,6 @@ HexagonTargetLowering::PerformHvxDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
|
|||
SelectionDAG &DAG = DCI.DAG;
|
||||
SDValue Op(N, 0);
|
||||
unsigned Opc = Op.getOpcode();
|
||||
|
||||
if (DCI.isBeforeLegalizeOps())
|
||||
return SDValue();
|
||||
|
||||
|
@ -2231,7 +2271,6 @@ HexagonTargetLowering::PerformHvxDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
|
|||
|
||||
bool
|
||||
HexagonTargetLowering::shouldWidenToHvx(MVT Ty, SelectionDAG &DAG) const {
|
||||
assert(!Subtarget.isHVXVectorType(Ty, true));
|
||||
auto Action = getPreferredHvxVectorAction(Ty);
|
||||
if (Action == TargetLoweringBase::TypeWidenVector) {
|
||||
EVT WideTy = getTypeToTransformTo(*DAG.getContext(), Ty);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
; RUN: llc -march=hexagon -hexagon-hvx-widen=32 < %s | FileCheck %s
|
||||
|
||||
; Make sure that this doesn't crash.
|
||||
; CHECK-LABEL: f0:
|
||||
; CHECK: vmem
|
||||
|
||||
target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
|
||||
target triple = "hexagon"
|
||||
|
||||
define dllexport void @f0(i16* %a0, <16 x i16> %a1) local_unnamed_addr #0 {
|
||||
b0:
|
||||
%v0 = getelementptr i16, i16* %a0, i32 undef
|
||||
%v1 = bitcast i16* %v0 to <16 x i16>*
|
||||
%v2 = load <16 x i16>, <16 x i16>* undef, align 2
|
||||
%v3 = icmp sgt <16 x i16> zeroinitializer, %v2
|
||||
%v4 = select <16 x i1> %v3, <16 x i16> %a1, <16 x i16> %v2
|
||||
store <16 x i16> %v4, <16 x i16>* %v1, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { "target-features"="+hvxv66,+hvx-length128b" }
|
Loading…
Reference in New Issue