@@ -710,6 +710,12 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
710
710
setOperationAction (ISD::VACOPY, MVT::Other, Custom);
711
711
setOperationAction (ISD::VAEND, MVT::Other, Expand);
712
712
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
+
713
719
setOperationAction (ISD::GET_ROUNDING, MVT::i32 , Custom);
714
720
715
721
// Codes for which we want to perform some z-specific combinations.
@@ -6059,6 +6065,34 @@ SDValue SystemZTargetLowering::lowerShift(SDValue Op, SelectionDAG &DAG,
6059
6065
return Op;
6060
6066
}
6061
6067
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
+
6062
6096
SDValue SystemZTargetLowering::lowerIS_FPCLASS (SDValue Op,
6063
6097
SelectionDAG &DAG) const {
6064
6098
SDLoc DL (Op);
@@ -6232,6 +6266,8 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
6232
6266
return lowerShift (Op, DAG, SystemZISD::VSRL_BY_SCALAR);
6233
6267
case ISD::SRA:
6234
6268
return lowerShift (Op, DAG, SystemZISD::VSRA_BY_SCALAR);
6269
+ case ISD::ADDRSPACECAST:
6270
+ return lowerAddrSpaceCast (Op, DAG);
6235
6271
case ISD::ROTL:
6236
6272
return lowerShift (Op, DAG, SystemZISD::VROTL_BY_SCALAR);
6237
6273
case ISD::IS_FPCLASS:
@@ -6875,6 +6911,20 @@ SDValue SystemZTargetLowering::combineLOAD(
6875
6911
SDNode *N, DAGCombinerInfo &DCI) const {
6876
6912
SelectionDAG &DAG = DCI.DAG ;
6877
6913
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
+ }
6878
6928
SDLoc DL (N);
6879
6929
6880
6930
// Replace a 128-bit load that is used solely to move its value into GPRs
@@ -7042,6 +7092,20 @@ SDValue SystemZTargetLowering::combineSTORE(
7042
7092
auto *SN = cast<StoreSDNode>(N);
7043
7093
auto &Op1 = N->getOperand (1 );
7044
7094
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
+
7045
7109
// If we have (truncstoreiN (extract_vector_elt X, Y), Z) then it is better
7046
7110
// for the extraction to be done on a vMiN value, so that we can use VSTE.
7047
7111
// If X has wider elements then convert it to:
0 commit comments