Skip to content

[SystemZ][z/OS] Continuation of __ptr32 support #103393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZ.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ void initializeSystemZPostRewritePass(PassRegistry &);
void initializeSystemZShortenInstPass(PassRegistry &);
void initializeSystemZTDCPassPass(PassRegistry &);

namespace SYSTEMZAS {
enum : unsigned { PTR32 = 1 };
} // namespace SYSTEMZAS

} // end namespace llvm

#endif
11 changes: 11 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZCallingConv.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,17 @@ inline bool CC_SystemZ_I128Indirect(unsigned &ValNo, MVT &ValVT,
return true;
}

// A pointer in 64bit mode is always passed as 64bit.
inline bool CC_XPLINK64_Pointer(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
CCValAssign::LocInfo &LocInfo,
ISD::ArgFlagsTy &ArgFlags, CCState &State) {
if (LocVT != MVT::i64) {
LocVT = MVT::i64;
LocInfo = CCValAssign::ZExt;
}
return false;
}

inline bool CC_XPLINK64_Shadow_Reg(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
CCValAssign::LocInfo &LocInfo,
ISD::ArgFlagsTy &ArgFlags, CCState &State) {
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZCallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ def CC_SystemZ_XPLINK64 : CallingConv<[
// Although we assign the f32 vararg to be bitcast, it will first be promoted
// to an f64 within convertValVTToLocVT().
CCIfType<[f32, f64], CCIfNotFixed<CCBitConvertToType<i64>>>,
// Pointers are always passed in full 64-bit registers.
CCIfPtr<CCCustom<"CC_XPLINK64_Pointer">>,
// long double, can only be passed in GPR2 and GPR3, if available,
// hence R2Q
CCIfType<[f128], CCIfNotFixed<CCCustom<"CC_XPLINK64_Allocate128BitVararg">>>,
Expand Down
64 changes: 64 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,12 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::VACOPY, MVT::Other, Custom);
setOperationAction(ISD::VAEND, MVT::Other, Expand);

if (Subtarget.isTargetzOS()) {
// Handle address space casts between mixed sized pointers.
setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
}

setOperationAction(ISD::GET_ROUNDING, MVT::i32, Custom);

// Codes for which we want to perform some z-specific combinations.
Expand Down Expand Up @@ -6059,6 +6065,34 @@ SDValue SystemZTargetLowering::lowerShift(SDValue Op, SelectionDAG &DAG,
return Op;
}

static SDValue lowerAddrSpaceCast(SDValue Op, SelectionDAG &DAG) {
SDLoc dl(Op);
SDValue Src = Op.getOperand(0);
MVT DstVT = Op.getSimpleValueType();

AddrSpaceCastSDNode *N = cast<AddrSpaceCastSDNode>(Op.getNode());
unsigned SrcAS = N->getSrcAddressSpace();

assert(SrcAS != N->getDestAddressSpace() &&
"addrspacecast must be between different address spaces");

// addrspacecast [0 <- 1] : Assinging a ptr32 value to a 64-bit pointer.
// addrspacecast [1 <- 0] : Assigining a 64-bit pointer to a ptr32 value.
if (SrcAS == SYSTEMZAS::PTR32 && DstVT == MVT::i64) {
Op = DAG.getNode(ISD::AND, dl, MVT::i32, Src,
DAG.getConstant(0x7fffffff, dl, MVT::i32));
Op = DAG.getNode(ISD::ZERO_EXTEND, dl, DstVT, Op);
} else if (DstVT == MVT::i32) {
Op = DAG.getNode(ISD::TRUNCATE, dl, DstVT, Src);
Op = DAG.getNode(ISD::AND, dl, MVT::i32, Op,
DAG.getConstant(0x7fffffff, dl, MVT::i32));
Op = DAG.getNode(ISD::ZERO_EXTEND, dl, DstVT, Op);
} else {
report_fatal_error("Bad address space in addrspacecast");
}
return Op;
}

SDValue SystemZTargetLowering::lowerIS_FPCLASS(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
Expand Down Expand Up @@ -6232,6 +6266,8 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
return lowerShift(Op, DAG, SystemZISD::VSRL_BY_SCALAR);
case ISD::SRA:
return lowerShift(Op, DAG, SystemZISD::VSRA_BY_SCALAR);
case ISD::ADDRSPACECAST:
return lowerAddrSpaceCast(Op, DAG);
case ISD::ROTL:
return lowerShift(Op, DAG, SystemZISD::VROTL_BY_SCALAR);
case ISD::IS_FPCLASS:
Expand Down Expand Up @@ -6875,6 +6911,20 @@ SDValue SystemZTargetLowering::combineLOAD(
SDNode *N, DAGCombinerInfo &DCI) const {
SelectionDAG &DAG = DCI.DAG;
EVT LdVT = N->getValueType(0);
if (auto *LN = dyn_cast<LoadSDNode>(N)) {
if (LN->getAddressSpace() == SYSTEMZAS::PTR32) {
MVT PtrVT = getPointerTy(DAG.getDataLayout());
MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
if (PtrVT != LoadNodeVT) {
SDLoc DL(LN);
SDValue AddrSpaceCast = DAG.getAddrSpaceCast(
DL, PtrVT, LN->getBasePtr(), SYSTEMZAS::PTR32, 0);
return DAG.getExtLoad(LN->getExtensionType(), DL, LN->getValueType(0),
LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
LN->getMemOperand());
}
}
}
SDLoc DL(N);

// Replace a 128-bit load that is used solely to move its value into GPRs
Expand Down Expand Up @@ -7042,6 +7092,20 @@ SDValue SystemZTargetLowering::combineSTORE(
auto *SN = cast<StoreSDNode>(N);
auto &Op1 = N->getOperand(1);
EVT MemVT = SN->getMemoryVT();

if (SN->getAddressSpace() == SYSTEMZAS::PTR32) {
MVT PtrVT = getPointerTy(DAG.getDataLayout());
MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
if (PtrVT != StoreNodeVT) {
SDLoc DL(SN);
SDValue AddrSpaceCast = DAG.getAddrSpaceCast(DL, PtrVT, SN->getBasePtr(),
SYSTEMZAS::PTR32, 0);
return DAG.getStore(SN->getChain(), DL, SN->getValue(), AddrSpaceCast,
SN->getPointerInfo(), SN->getOriginalAlign(),
SN->getMemOperand()->getFlags(), SN->getAAInfo());
}
}

// If we have (truncstoreiN (extract_vector_elt X, Y), Z) then it is better
// for the extraction to be done on a vMiN value, so that we can use VSTE.
// If X has wider elements then convert it to:
Expand Down
Loading
Loading