forked from OSchip/llvm-project
[PowerPC] Cust lower fpext v2f32 to v2f64 from extract_subvector v4f32
Add the missing piece of r372029. Somehow when the patch for review D61961 was committed, only the test case went in and the code didn't. This of course caused all kinds of build bot breaks. This patch just adds the code for that patch. Author: Lei Huang Differential revision: https://reviews.llvm.org/D61961 llvm-svn: 372043
This commit is contained in:
parent
77383d83eb
commit
e63c676825
|
@ -1405,7 +1405,7 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||||
case PPCISD::EXTRACT_SPE: return "PPCISD::EXTRACT_SPE";
|
case PPCISD::EXTRACT_SPE: return "PPCISD::EXTRACT_SPE";
|
||||||
case PPCISD::EXTSWSLI: return "PPCISD::EXTSWSLI";
|
case PPCISD::EXTSWSLI: return "PPCISD::EXTSWSLI";
|
||||||
case PPCISD::LD_VSX_LH: return "PPCISD::LD_VSX_LH";
|
case PPCISD::LD_VSX_LH: return "PPCISD::LD_VSX_LH";
|
||||||
case PPCISD::FP_EXTEND_LH: return "PPCISD::FP_EXTEND_LH";
|
case PPCISD::FP_EXTEND_HALF: return "PPCISD::FP_EXTEND_HALF";
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -9913,6 +9913,30 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
|
||||||
switch (Op0.getOpcode()) {
|
switch (Op0.getOpcode()) {
|
||||||
default:
|
default:
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
case ISD::EXTRACT_SUBVECTOR: {
|
||||||
|
assert(Op0.getNumOperands() == 2 &&
|
||||||
|
isa<ConstantSDNode>(Op0->getOperand(1)) &&
|
||||||
|
"Node should have 2 operands with second one being a constant!");
|
||||||
|
|
||||||
|
if (Op0.getOperand(0).getValueType() != MVT::v4f32)
|
||||||
|
return SDValue();
|
||||||
|
|
||||||
|
// Custom lower is only done for high or low doubleword.
|
||||||
|
int Idx = cast<ConstantSDNode>(Op0.getOperand(1))->getZExtValue();
|
||||||
|
if (Idx % 2 != 0)
|
||||||
|
return SDValue();
|
||||||
|
|
||||||
|
// Since input is v4f32, at this point Idx is either 0 or 2.
|
||||||
|
// Shift to get the doubleword position we want.
|
||||||
|
int DWord = Idx >> 1;
|
||||||
|
|
||||||
|
// High and low word positions are different on little endian.
|
||||||
|
if (Subtarget.isLittleEndian())
|
||||||
|
DWord ^= 0x1;
|
||||||
|
|
||||||
|
return DAG.getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
|
||||||
|
Op0.getOperand(0), DAG.getConstant(DWord, dl, MVT::i32));
|
||||||
|
}
|
||||||
case ISD::FADD:
|
case ISD::FADD:
|
||||||
case ISD::FMUL:
|
case ISD::FMUL:
|
||||||
case ISD::FSUB: {
|
case ISD::FSUB: {
|
||||||
|
@ -9925,25 +9949,24 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
|
||||||
// Generate new load node.
|
// Generate new load node.
|
||||||
LoadSDNode *LD = cast<LoadSDNode>(LdOp);
|
LoadSDNode *LD = cast<LoadSDNode>(LdOp);
|
||||||
SDValue LoadOps[] = {LD->getChain(), LD->getBasePtr()};
|
SDValue LoadOps[] = {LD->getChain(), LD->getBasePtr()};
|
||||||
NewLoad[i] =
|
NewLoad[i] = DAG.getMemIntrinsicNode(
|
||||||
DAG.getMemIntrinsicNode(PPCISD::LD_VSX_LH, dl,
|
PPCISD::LD_VSX_LH, dl, DAG.getVTList(MVT::v4f32, MVT::Other), LoadOps,
|
||||||
DAG.getVTList(MVT::v4f32, MVT::Other),
|
LD->getMemoryVT(), LD->getMemOperand());
|
||||||
LoadOps, LD->getMemoryVT(),
|
|
||||||
LD->getMemOperand());
|
|
||||||
}
|
}
|
||||||
SDValue NewOp = DAG.getNode(Op0.getOpcode(), SDLoc(Op0), MVT::v4f32,
|
SDValue NewOp =
|
||||||
NewLoad[0], NewLoad[1],
|
DAG.getNode(Op0.getOpcode(), SDLoc(Op0), MVT::v4f32, NewLoad[0],
|
||||||
Op0.getNode()->getFlags());
|
NewLoad[1], Op0.getNode()->getFlags());
|
||||||
return DAG.getNode(PPCISD::FP_EXTEND_LH, dl, MVT::v2f64, NewOp);
|
return DAG.getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
|
||||||
|
DAG.getConstant(0, dl, MVT::i32));
|
||||||
}
|
}
|
||||||
case ISD::LOAD: {
|
case ISD::LOAD: {
|
||||||
LoadSDNode *LD = cast<LoadSDNode>(Op0);
|
LoadSDNode *LD = cast<LoadSDNode>(Op0);
|
||||||
SDValue LoadOps[] = {LD->getChain(), LD->getBasePtr()};
|
SDValue LoadOps[] = {LD->getChain(), LD->getBasePtr()};
|
||||||
SDValue NewLd =
|
SDValue NewLd = DAG.getMemIntrinsicNode(
|
||||||
DAG.getMemIntrinsicNode(PPCISD::LD_VSX_LH, dl,
|
PPCISD::LD_VSX_LH, dl, DAG.getVTList(MVT::v4f32, MVT::Other), LoadOps,
|
||||||
DAG.getVTList(MVT::v4f32, MVT::Other),
|
LD->getMemoryVT(), LD->getMemOperand());
|
||||||
LoadOps, LD->getMemoryVT(), LD->getMemOperand());
|
return DAG.getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
|
||||||
return DAG.getNode(PPCISD::FP_EXTEND_LH, dl, MVT::v2f64, NewLd);
|
DAG.getConstant(0, dl, MVT::i32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
llvm_unreachable("ERROR:Should return for all cases within swtich.");
|
llvm_unreachable("ERROR:Should return for all cases within swtich.");
|
||||||
|
|
|
@ -412,8 +412,9 @@ namespace llvm {
|
||||||
/// representation.
|
/// representation.
|
||||||
QBFLT,
|
QBFLT,
|
||||||
|
|
||||||
/// Custom extend v4f32 to v2f64.
|
/// FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or
|
||||||
FP_EXTEND_LH,
|
/// lower (IDX=1) half of v4f32 to v2f64.
|
||||||
|
FP_EXTEND_HALF,
|
||||||
|
|
||||||
/// CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a
|
/// CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a
|
||||||
/// byte-swapping store instruction. It byte-swaps the low "Type" bits of
|
/// byte-swapping store instruction. It byte-swaps the low "Type" bits of
|
||||||
|
|
|
@ -58,8 +58,8 @@ def SDT_PPCldvsxlh : SDTypeProfile<1, 1, [
|
||||||
SDTCisVT<0, v4f32>, SDTCisPtrTy<1>
|
SDTCisVT<0, v4f32>, SDTCisPtrTy<1>
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
def SDT_PPCfpextlh : SDTypeProfile<1, 1, [
|
def SDT_PPCfpexth : SDTypeProfile<1, 2, [
|
||||||
SDTCisVT<0, v2f64>, SDTCisVT<1, v4f32>
|
SDTCisVT<0, v2f64>, SDTCisVT<1, v4f32>, SDTCisPtrTy<2>
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
// Little-endian-specific nodes.
|
// Little-endian-specific nodes.
|
||||||
|
@ -102,7 +102,7 @@ def PPCuvec2fp: SDNode<"PPCISD::UINT_VEC_TO_FP", SDTVecConv, []>;
|
||||||
def PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>;
|
def PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>;
|
||||||
def PPCvabsd : SDNode<"PPCISD::VABSD", SDTVabsd, []>;
|
def PPCvabsd : SDNode<"PPCISD::VABSD", SDTVabsd, []>;
|
||||||
|
|
||||||
def PPCfpextlh : SDNode<"PPCISD::FP_EXTEND_LH", SDT_PPCfpextlh, []>;
|
def PPCfpexth : SDNode<"PPCISD::FP_EXTEND_HALF", SDT_PPCfpexth, []>;
|
||||||
def PPCldvsxlh : SDNode<"PPCISD::LD_VSX_LH", SDT_PPCldvsxlh,
|
def PPCldvsxlh : SDNode<"PPCISD::LD_VSX_LH", SDT_PPCldvsxlh,
|
||||||
[SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
|
[SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
|
||||||
|
|
||||||
|
@ -1086,7 +1086,8 @@ def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
|
||||||
def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
|
def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
|
||||||
(v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
|
(v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
|
||||||
|
|
||||||
def : Pat<(v2f64 (PPCfpextlh v4f32:$C)), (XVCVSPDP (XXMRGHW $C, $C))>;
|
def : Pat<(v2f64 (PPCfpexth v4f32:$C, 0)), (XVCVSPDP (XXMRGHW $C, $C))>;
|
||||||
|
def : Pat<(v2f64 (PPCfpexth v4f32:$C, 1)), (XVCVSPDP (XXMRGLW $C, $C))>;
|
||||||
|
|
||||||
// Loads.
|
// Loads.
|
||||||
let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
|
let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
|
||||||
|
|
Loading…
Reference in New Issue