@@ -710,6 +710,12 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
710710 setOperationAction (ISD::VACOPY, MVT::Other, Custom);
711711 setOperationAction (ISD::VAEND, MVT::Other, Expand);
712712
713+ if (Subtarget.isTargetzOS ()) {
714+ // Handle address space casts between mixed sized pointers.
715+ setOperationAction (ISD::ADDRSPACECAST, MVT::i32 , Custom);
716+ setOperationAction (ISD::ADDRSPACECAST, MVT::i64 , Custom);
717+ }
718+
713719 setOperationAction (ISD::GET_ROUNDING, MVT::i32 , Custom);
714720
715721 // Codes for which we want to perform some z-specific combinations.
@@ -6059,6 +6065,34 @@ SDValue SystemZTargetLowering::lowerShift(SDValue Op, SelectionDAG &DAG,
60596065 return Op;
60606066}
60616067
6068+ static SDValue lowerAddrSpaceCast (SDValue Op, SelectionDAG &DAG) {
6069+ SDLoc dl (Op);
6070+ SDValue Src = Op.getOperand (0 );
6071+ MVT DstVT = Op.getSimpleValueType ();
6072+
6073+ AddrSpaceCastSDNode *N = cast<AddrSpaceCastSDNode>(Op.getNode ());
6074+ unsigned SrcAS = N->getSrcAddressSpace ();
6075+
6076+ assert (SrcAS != N->getDestAddressSpace () &&
6077+ " addrspacecast must be between different address spaces" );
6078+
6079+ // addrspacecast [0 <- 1] : Assinging a ptr32 value to a 64-bit pointer.
6080+ // addrspacecast [1 <- 0] : Assigining a 64-bit pointer to a ptr32 value.
6081+ if (SrcAS == SYSTEMZAS::PTR32 && DstVT == MVT::i64 ) {
6082+ Op = DAG.getNode (ISD::AND, dl, MVT::i32 , Src,
6083+ DAG.getConstant (0x7fffffff , dl, MVT::i32 ));
6084+ Op = DAG.getNode (ISD::ZERO_EXTEND, dl, DstVT, Op);
6085+ } else if (DstVT == MVT::i32 ) {
6086+ Op = DAG.getNode (ISD::TRUNCATE, dl, DstVT, Src);
6087+ Op = DAG.getNode (ISD::AND, dl, MVT::i32 , Op,
6088+ DAG.getConstant (0x7fffffff , dl, MVT::i32 ));
6089+ Op = DAG.getNode (ISD::ZERO_EXTEND, dl, DstVT, Op);
6090+ } else {
6091+ report_fatal_error (" Bad address space in addrspacecast" );
6092+ }
6093+ return Op;
6094+ }
6095+
60626096SDValue SystemZTargetLowering::lowerIS_FPCLASS (SDValue Op,
60636097 SelectionDAG &DAG) const {
60646098 SDLoc DL (Op);
@@ -6232,6 +6266,8 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
62326266 return lowerShift (Op, DAG, SystemZISD::VSRL_BY_SCALAR);
62336267 case ISD::SRA:
62346268 return lowerShift (Op, DAG, SystemZISD::VSRA_BY_SCALAR);
6269+ case ISD::ADDRSPACECAST:
6270+ return lowerAddrSpaceCast (Op, DAG);
62356271 case ISD::ROTL:
62366272 return lowerShift (Op, DAG, SystemZISD::VROTL_BY_SCALAR);
62376273 case ISD::IS_FPCLASS:
@@ -6875,6 +6911,20 @@ SDValue SystemZTargetLowering::combineLOAD(
68756911 SDNode *N, DAGCombinerInfo &DCI) const {
68766912 SelectionDAG &DAG = DCI.DAG ;
68776913 EVT LdVT = N->getValueType (0 );
6914+ if (auto *LN = dyn_cast<LoadSDNode>(N)) {
6915+ if (LN->getAddressSpace () == SYSTEMZAS::PTR32) {
6916+ MVT PtrVT = getPointerTy (DAG.getDataLayout ());
6917+ MVT LoadNodeVT = LN->getBasePtr ().getSimpleValueType ();
6918+ if (PtrVT != LoadNodeVT) {
6919+ SDLoc DL (LN);
6920+ SDValue AddrSpaceCast = DAG.getAddrSpaceCast (
6921+ DL, PtrVT, LN->getBasePtr (), SYSTEMZAS::PTR32, 0 );
6922+ return DAG.getExtLoad (LN->getExtensionType (), DL, LN->getValueType (0 ),
6923+ LN->getChain (), AddrSpaceCast, LN->getMemoryVT (),
6924+ LN->getMemOperand ());
6925+ }
6926+ }
6927+ }
68786928 SDLoc DL (N);
68796929
68806930 // Replace a 128-bit load that is used solely to move its value into GPRs
@@ -7042,6 +7092,20 @@ SDValue SystemZTargetLowering::combineSTORE(
70427092 auto *SN = cast<StoreSDNode>(N);
70437093 auto &Op1 = N->getOperand (1 );
70447094 EVT MemVT = SN->getMemoryVT ();
7095+
7096+ if (SN->getAddressSpace () == SYSTEMZAS::PTR32) {
7097+ MVT PtrVT = getPointerTy (DAG.getDataLayout ());
7098+ MVT StoreNodeVT = SN->getBasePtr ().getSimpleValueType ();
7099+ if (PtrVT != StoreNodeVT) {
7100+ SDLoc DL (SN);
7101+ SDValue AddrSpaceCast = DAG.getAddrSpaceCast (DL, PtrVT, SN->getBasePtr (),
7102+ SYSTEMZAS::PTR32, 0 );
7103+ return DAG.getStore (SN->getChain (), DL, SN->getValue (), AddrSpaceCast,
7104+ SN->getPointerInfo (), SN->getOriginalAlign (),
7105+ SN->getMemOperand ()->getFlags (), SN->getAAInfo ());
7106+ }
7107+ }
7108+
70457109 // If we have (truncstoreiN (extract_vector_elt X, Y), Z) then it is better
70467110 // for the extraction to be done on a vMiN value, so that we can use VSTE.
70477111 // If X has wider elements then convert it to:
0 commit comments