@@ -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);
@@ -6879,6 +6882,37 @@ static SDValue LowerTruncateVectorStore(SDLoc DL, StoreSDNode *ST,
68796882 ST->getBasePtr(), ST->getMemOperand());
68806883}
68816884
6885+ static SDValue LowerADDRSPACECAST(SDValue Op, SelectionDAG &DAG) {
6886+ SDLoc dl(Op);
6887+ SDValue Src = Op.getOperand(0);
6888+ MVT DestVT = Op.getSimpleValueType();
6889+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6890+ AddrSpaceCastSDNode *N = cast<AddrSpaceCastSDNode>(Op.getNode());
6891+
6892+ unsigned SrcAS = N->getSrcAddressSpace();
6893+ unsigned DestAS = N->getDestAddressSpace();
6894+ assert(SrcAS != DestAS &&
6895+ "addrspacecast must be between different address spaces");
6896+ assert(TLI.getTargetMachine().getPointerSize(SrcAS) !=
6897+ TLI.getTargetMachine().getPointerSize(DestAS) &&
6898+ "addrspacecast must be between different ptr sizes");
6899+
6900+ if (SrcAS == ARM64AS::PTR32_SPTR) {
6901+ return DAG.getNode(ISD::SIGN_EXTEND, dl, DestVT, Src,
6902+ DAG.getTargetConstant(0, dl, DestVT));
6903+ } else if (SrcAS == ARM64AS::PTR32_UPTR) {
6904+ return DAG.getNode(ISD::ZERO_EXTEND, dl, DestVT, Src,
6905+ DAG.getTargetConstant(0, dl, DestVT));
6906+ } else if ((DestAS == ARM64AS::PTR32_SPTR) ||
6907+ (DestAS == ARM64AS::PTR32_UPTR)) {
6908+ SDValue Ext = DAG.getAnyExtOrTrunc(Src, dl, DestVT);
6909+ SDValue Trunc = DAG.getZeroExtendInReg(Ext, dl, DestVT);
6910+ return Trunc;
6911+ } else {
6912+ return Src;
6913+ }
6914+ }
6915+
68826916// Custom lowering for any store, vector or scalar and/or default or with
68836917// a truncate operations. Currently only custom lower truncate operation
68846918// from vector v4i16 to v4i8 or volatile stores of i128.
@@ -7540,6 +7574,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
75407574 case ISD::SIGN_EXTEND:
75417575 case ISD::ZERO_EXTEND:
75427576 return LowerFixedLengthVectorIntExtendToSVE(Op, DAG);
7577+ case ISD::ADDRSPACECAST:
7578+ return LowerADDRSPACECAST(Op, DAG);
75437579 case ISD::SIGN_EXTEND_INREG: {
75447580 // Only custom lower when ExtraVT has a legal byte based element type.
75457581 EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
@@ -23740,6 +23776,26 @@ static SDValue performLOADCombine(SDNode *N,
2374023776 performTBISimplification(N->getOperand(1), DCI, DAG);
2374123777
2374223778 LoadSDNode *LD = cast<LoadSDNode>(N);
23779+ EVT RegVT = LD->getValueType(0);
23780+ EVT MemVT = LD->getMemoryVT();
23781+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23782+ SDLoc DL(LD);
23783+
23784+ // Cast ptr32 and ptr64 pointers to the default address space before a load.
23785+ unsigned AddrSpace = LD->getAddressSpace();
23786+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
23787+ AddrSpace == ARM64AS::PTR32_UPTR) {
23788+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
23789+ if (PtrVT != LD->getBasePtr().getSimpleValueType()) {
23790+ SDValue Cast =
23791+ DAG.getAddrSpaceCast(DL, PtrVT, LD->getBasePtr(), AddrSpace, 0);
23792+ return DAG.getExtLoad(LD->getExtensionType(), DL, RegVT, LD->getChain(),
23793+ Cast, LD->getPointerInfo(), MemVT,
23794+ LD->getOriginalAlign(),
23795+ LD->getMemOperand()->getFlags());
23796+ }
23797+ }
23798+
2374323799 if (LD->isVolatile() || !Subtarget->isLittleEndian())
2374423800 return SDValue(N, 0);
2374523801
@@ -23749,13 +23805,11 @@ static SDValue performLOADCombine(SDNode *N,
2374923805 if (!LD->isNonTemporal())
2375023806 return SDValue(N, 0);
2375123807
23752- EVT MemVT = LD->getMemoryVT();
2375323808 if (MemVT.isScalableVector() || MemVT.getSizeInBits() <= 256 ||
2375423809 MemVT.getSizeInBits() % 256 == 0 ||
2375523810 256 % MemVT.getScalarSizeInBits() != 0)
2375623811 return SDValue(N, 0);
2375723812
23758- SDLoc DL(LD);
2375923813 SDValue Chain = LD->getChain();
2376023814 SDValue BasePtr = LD->getBasePtr();
2376123815 SDNodeFlags Flags = LD->getFlags();
@@ -24015,12 +24069,28 @@ static SDValue performSTORECombine(SDNode *N,
2401524069 SDValue Value = ST->getValue();
2401624070 SDValue Ptr = ST->getBasePtr();
2401724071 EVT ValueVT = Value.getValueType();
24072+ EVT MemVT = ST->getMemoryVT();
24073+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
24074+ SDLoc DL(ST);
2401824075
2401924076 auto hasValidElementTypeForFPTruncStore = [](EVT VT) {
2402024077 EVT EltVT = VT.getVectorElementType();
2402124078 return EltVT == MVT::f32 || EltVT == MVT::f64;
2402224079 };
2402324080
24081+ // Cast ptr32 and ptr64 pointers to the default address space before a store.
24082+ unsigned AddrSpace = ST->getAddressSpace();
24083+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
24084+ AddrSpace == ARM64AS::PTR32_UPTR) {
24085+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
24086+ if (PtrVT != Ptr.getSimpleValueType()) {
24087+ SDValue Cast = DAG.getAddrSpaceCast(DL, PtrVT, Ptr, AddrSpace, 0);
24088+ return DAG.getStore(Chain, DL, Value, Cast, ST->getPointerInfo(),
24089+ ST->getOriginalAlign(),
24090+ ST->getMemOperand()->getFlags(), ST->getAAInfo());
24091+ }
24092+ }
24093+
2402424094 if (SDValue Res = combineI8TruncStore(ST, DAG, Subtarget))
2402524095 return Res;
2402624096
@@ -24034,8 +24104,8 @@ static SDValue performSTORECombine(SDNode *N,
2403424104 ValueVT.isFixedLengthVector() &&
2403524105 ValueVT.getFixedSizeInBits() >= Subtarget->getMinSVEVectorSizeInBits() &&
2403624106 hasValidElementTypeForFPTruncStore(Value.getOperand(0).getValueType()))
24037- return DAG.getTruncStore(Chain, SDLoc(N) , Value.getOperand(0), Ptr,
24038- ST->getMemoryVT(), ST-> getMemOperand());
24107+ return DAG.getTruncStore(Chain, DL , Value.getOperand(0), Ptr, MemVT ,
24108+ ST->getMemOperand());
2403924109
2404024110 if (SDValue Split = splitStores(N, DCI, DAG, Subtarget))
2404124111 return Split;
@@ -27519,6 +27589,11 @@ void AArch64TargetLowering::ReplaceNodeResults(
2751927589 ReplaceATOMIC_LOAD_128Results(N, Results, DAG, Subtarget);
2752027590 return;
2752127591 }
27592+ case ISD::ADDRSPACECAST: {
27593+ SDValue V = LowerADDRSPACECAST(SDValue(N, 0), DAG);
27594+ Results.push_back(V);
27595+ return;
27596+ }
2752227597 case ISD::ATOMIC_LOAD:
2752327598 case ISD::LOAD: {
2752427599 MemSDNode *LoadNode = cast<MemSDNode>(N);
0 commit comments