@@ -1405,7 +1405,7 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
1405
1405
case PPCISD::EXTRACT_SPE: return "PPCISD::EXTRACT_SPE";
1406
1406
case PPCISD::EXTSWSLI: return "PPCISD::EXTSWSLI";
1407
1407
case PPCISD::LD_VSX_LH: return "PPCISD::LD_VSX_LH";
1408
- case PPCISD::FP_EXTEND_LH : return "PPCISD::FP_EXTEND_LH ";
1408
+ case PPCISD::FP_EXTEND_HALF : return "PPCISD::FP_EXTEND_HALF ";
1409
1409
}
1410
1410
return nullptr;
1411
1411
}
@@ -9913,6 +9913,30 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
9913
9913
switch (Op0.getOpcode()) {
9914
9914
default:
9915
9915
return SDValue();
9916
+ case ISD::EXTRACT_SUBVECTOR: {
9917
+ assert(Op0.getNumOperands() == 2 &&
9918
+ isa<ConstantSDNode>(Op0->getOperand(1)) &&
9919
+ "Node should have 2 operands with second one being a constant!");
9920
+
9921
+ if (Op0.getOperand(0).getValueType() != MVT::v4f32)
9922
+ return SDValue();
9923
+
9924
+ // Custom lower is only done for high or low doubleword.
9925
+ int Idx = cast<ConstantSDNode>(Op0.getOperand(1))->getZExtValue();
9926
+ if (Idx % 2 != 0)
9927
+ return SDValue();
9928
+
9929
+ // Since input is v4f32, at this point Idx is either 0 or 2.
9930
+ // Shift to get the doubleword position we want.
9931
+ int DWord = Idx >> 1;
9932
+
9933
+ // High and low word positions are different on little endian.
9934
+ if (Subtarget.isLittleEndian())
9935
+ DWord ^= 0x1;
9936
+
9937
+ return DAG.getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
9938
+ Op0.getOperand(0), DAG.getConstant(DWord, dl, MVT::i32));
9939
+ }
9916
9940
case ISD::FADD:
9917
9941
case ISD::FMUL:
9918
9942
case ISD::FSUB: {
@@ -9924,26 +9948,25 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
9924
9948
return SDValue();
9925
9949
// Generate new load node.
9926
9950
LoadSDNode *LD = cast<LoadSDNode>(LdOp);
9927
- SDValue LoadOps[] = { LD->getChain(), LD->getBasePtr() };
9928
- NewLoad[i] =
9929
- DAG.getMemIntrinsicNode(PPCISD::LD_VSX_LH, dl,
9930
- DAG.getVTList(MVT::v4f32, MVT::Other),
9931
- LoadOps, LD->getMemoryVT(),
9932
- LD->getMemOperand());
9933
- }
9934
- SDValue NewOp = DAG.getNode(Op0.getOpcode(), SDLoc(Op0), MVT::v4f32,
9935
- NewLoad[0], NewLoad[1],
9936
- Op0.getNode()->getFlags());
9937
- return DAG.getNode(PPCISD::FP_EXTEND_LH, dl, MVT::v2f64, NewOp);
9951
+ SDValue LoadOps[] = {LD->getChain(), LD->getBasePtr()};
9952
+ NewLoad[i] = DAG.getMemIntrinsicNode(
9953
+ PPCISD::LD_VSX_LH, dl, DAG.getVTList(MVT::v4f32, MVT::Other), LoadOps,
9954
+ LD->getMemoryVT(), LD->getMemOperand());
9955
+ }
9956
+ SDValue NewOp =
9957
+ DAG.getNode(Op0.getOpcode(), SDLoc(Op0), MVT::v4f32, NewLoad[0],
9958
+ NewLoad[1], Op0.getNode()->getFlags());
9959
+ return DAG.getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
9960
+ DAG.getConstant(0, dl, MVT::i32));
9938
9961
}
9939
9962
case ISD::LOAD: {
9940
9963
LoadSDNode *LD = cast<LoadSDNode>(Op0);
9941
- SDValue LoadOps[] = { LD->getChain(), LD->getBasePtr() };
9942
- SDValue NewLd =
9943
- DAG.getMemIntrinsicNode( PPCISD::LD_VSX_LH, dl,
9944
- DAG.getVTList(MVT::v4f32, MVT::Other),
9945
- LoadOps, LD->getMemoryVT(), LD->getMemOperand());
9946
- return DAG.getNode(PPCISD::FP_EXTEND_LH , dl, MVT::v2f64, NewLd );
9964
+ SDValue LoadOps[] = {LD->getChain(), LD->getBasePtr()};
9965
+ SDValue NewLd = DAG.getMemIntrinsicNode(
9966
+ PPCISD::LD_VSX_LH, dl, DAG.getVTList(MVT::v4f32, MVT::Other), LoadOps ,
9967
+ LD->getMemoryVT(), LD->getMemOperand());
9968
+ return DAG.getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
9969
+ DAG.getConstant(0 , dl, MVT::i32) );
9947
9970
}
9948
9971
}
9949
9972
llvm_unreachable("ERROR:Should return for all cases within swtich.");
0 commit comments