@@ -530,6 +530,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
530530 setOperationAction(ISD::XOR, MVT::i32, Custom);
531531 setOperationAction(ISD::XOR, MVT::i64, Custom);
532532
533+ setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
534+ setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
535+
533536 // Virtually no operation on f128 is legal, but LLVM can't expand them when
534537 // there's a valid register class, so we need custom operations in most cases.
535538 setOperationAction(ISD::FABS, MVT::f128, Expand);
@@ -6746,6 +6749,37 @@ static SDValue LowerTruncateVectorStore(SDLoc DL, StoreSDNode *ST,
67466749 ST->getBasePtr(), ST->getMemOperand());
67476750}
67486751
6752+ static SDValue LowerADDRSPACECAST(SDValue Op, SelectionDAG &DAG) {
6753+ SDLoc dl(Op);
6754+ SDValue Src = Op.getOperand(0);
6755+ MVT DestVT = Op.getSimpleValueType();
6756+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6757+ AddrSpaceCastSDNode *N = cast<AddrSpaceCastSDNode>(Op.getNode());
6758+
6759+ unsigned SrcAS = N->getSrcAddressSpace();
6760+ unsigned DestAS = N->getDestAddressSpace();
6761+ assert(SrcAS != DestAS &&
6762+ "addrspacecast must be between different address spaces");
6763+ assert(TLI.getTargetMachine().getPointerSize(SrcAS) !=
6764+ TLI.getTargetMachine().getPointerSize(DestAS) &&
6765+ "addrspacecast must be between different ptr sizes");
6766+
6767+ if (SrcAS == ARM64AS::PTR32_SPTR) {
6768+ return DAG.getNode(ISD::SIGN_EXTEND, dl, DestVT, Src,
6769+ DAG.getTargetConstant(0, dl, DestVT));
6770+ } else if (SrcAS == ARM64AS::PTR32_UPTR) {
6771+ return DAG.getNode(ISD::ZERO_EXTEND, dl, DestVT, Src,
6772+ DAG.getTargetConstant(0, dl, DestVT));
6773+ } else if ((DestAS == ARM64AS::PTR32_SPTR) ||
6774+ (DestAS == ARM64AS::PTR32_UPTR)) {
6775+ SDValue Ext = DAG.getAnyExtOrTrunc(Src, dl, DestVT);
6776+ SDValue Trunc = DAG.getZeroExtendInReg(Ext, dl, DestVT);
6777+ return Trunc;
6778+ } else {
6779+ return Src;
6780+ }
6781+ }
6782+
67496783// Custom lowering for any store, vector or scalar and/or default or with
67506784// a truncate operations. Currently only custom lower truncate operation
67516785// from vector v4i16 to v4i8 or volatile stores of i128.
@@ -7399,6 +7433,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
73997433 case ISD::SIGN_EXTEND:
74007434 case ISD::ZERO_EXTEND:
74017435 return LowerFixedLengthVectorIntExtendToSVE(Op, DAG);
7436+ case ISD::ADDRSPACECAST:
7437+ return LowerADDRSPACECAST(Op, DAG);
74027438 case ISD::SIGN_EXTEND_INREG: {
74037439 // Only custom lower when ExtraVT has a legal byte based element type.
74047440 EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
@@ -23448,6 +23484,26 @@ static SDValue performLOADCombine(SDNode *N,
2344823484 performTBISimplification(N->getOperand(1), DCI, DAG);
2344923485
2345023486 LoadSDNode *LD = cast<LoadSDNode>(N);
23487+ EVT RegVT = LD->getValueType(0);
23488+ EVT MemVT = LD->getMemoryVT();
23489+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23490+ SDLoc DL(LD);
23491+
23492+ // Cast ptr32 and ptr64 pointers to the default address space before a load.
23493+ unsigned AddrSpace = LD->getAddressSpace();
23494+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
23495+ AddrSpace == ARM64AS::PTR32_UPTR) {
23496+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
23497+ if (PtrVT != LD->getBasePtr().getSimpleValueType()) {
23498+ SDValue Cast =
23499+ DAG.getAddrSpaceCast(DL, PtrVT, LD->getBasePtr(), AddrSpace, 0);
23500+ return DAG.getExtLoad(LD->getExtensionType(), DL, RegVT, LD->getChain(),
23501+ Cast, LD->getPointerInfo(), MemVT,
23502+ LD->getOriginalAlign(),
23503+ LD->getMemOperand()->getFlags());
23504+ }
23505+ }
23506+
2345123507 if (LD->isVolatile() || !Subtarget->isLittleEndian())
2345223508 return SDValue(N, 0);
2345323509
@@ -23457,13 +23513,11 @@ static SDValue performLOADCombine(SDNode *N,
2345723513 if (!LD->isNonTemporal())
2345823514 return SDValue(N, 0);
2345923515
23460- EVT MemVT = LD->getMemoryVT();
2346123516 if (MemVT.isScalableVector() || MemVT.getSizeInBits() <= 256 ||
2346223517 MemVT.getSizeInBits() % 256 == 0 ||
2346323518 256 % MemVT.getScalarSizeInBits() != 0)
2346423519 return SDValue(N, 0);
2346523520
23466- SDLoc DL(LD);
2346723521 SDValue Chain = LD->getChain();
2346823522 SDValue BasePtr = LD->getBasePtr();
2346923523 SDNodeFlags Flags = LD->getFlags();
@@ -23723,12 +23777,28 @@ static SDValue performSTORECombine(SDNode *N,
2372323777 SDValue Value = ST->getValue();
2372423778 SDValue Ptr = ST->getBasePtr();
2372523779 EVT ValueVT = Value.getValueType();
23780+ EVT MemVT = ST->getMemoryVT();
23781+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23782+ SDLoc DL(ST);
2372623783
2372723784 auto hasValidElementTypeForFPTruncStore = [](EVT VT) {
2372823785 EVT EltVT = VT.getVectorElementType();
2372923786 return EltVT == MVT::f32 || EltVT == MVT::f64;
2373023787 };
2373123788
23789+ // Cast ptr32 and ptr64 pointers to the default address space before a store.
23790+ unsigned AddrSpace = ST->getAddressSpace();
23791+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
23792+ AddrSpace == ARM64AS::PTR32_UPTR) {
23793+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
23794+ if (PtrVT != Ptr.getSimpleValueType()) {
23795+ SDValue Cast = DAG.getAddrSpaceCast(DL, PtrVT, Ptr, AddrSpace, 0);
23796+ return DAG.getStore(Chain, DL, Value, Cast, ST->getPointerInfo(),
23797+ ST->getOriginalAlign(),
23798+ ST->getMemOperand()->getFlags(), ST->getAAInfo());
23799+ }
23800+ }
23801+
2373223802 if (SDValue Res = combineI8TruncStore(ST, DAG, Subtarget))
2373323803 return Res;
2373423804
@@ -23742,8 +23812,8 @@ static SDValue performSTORECombine(SDNode *N,
2374223812 ValueVT.isFixedLengthVector() &&
2374323813 ValueVT.getFixedSizeInBits() >= Subtarget->getMinSVEVectorSizeInBits() &&
2374423814 hasValidElementTypeForFPTruncStore(Value.getOperand(0).getValueType()))
23745- return DAG.getTruncStore(Chain, SDLoc(N) , Value.getOperand(0), Ptr,
23746- ST->getMemoryVT(), ST-> getMemOperand());
23815+ return DAG.getTruncStore(Chain, DL , Value.getOperand(0), Ptr, MemVT ,
23816+ ST->getMemOperand());
2374723817
2374823818 if (SDValue Split = splitStores(N, DCI, DAG, Subtarget))
2374923819 return Split;
@@ -27070,6 +27140,11 @@ void AArch64TargetLowering::ReplaceNodeResults(
2707027140 ReplaceATOMIC_LOAD_128Results(N, Results, DAG, Subtarget);
2707127141 return;
2707227142 }
27143+ case ISD::ADDRSPACECAST: {
27144+ SDValue V = LowerADDRSPACECAST(SDValue(N, 0), DAG);
27145+ Results.push_back(V);
27146+ return;
27147+ }
2707327148 case ISD::ATOMIC_LOAD:
2707427149 case ISD::LOAD: {
2707527150 MemSDNode *LoadNode = cast<MemSDNode>(N);
0 commit comments