@@ -532,6 +532,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
532532 setOperationAction(ISD::XOR, MVT::i32, Custom);
533533 setOperationAction(ISD::XOR, MVT::i64, Custom);
534534
535+ setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
536+ setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
537+
535538 // Virtually no operation on f128 is legal, but LLVM can't expand them when
536539 // there's a valid register class, so we need custom operations in most cases.
537540 setOperationAction(ISD::FABS, MVT::f128, Expand);
@@ -6713,6 +6716,37 @@ static SDValue LowerTruncateVectorStore(SDLoc DL, StoreSDNode *ST,
67136716 ST->getBasePtr(), ST->getMemOperand());
67146717}
67156718
6719+ static SDValue LowerADDRSPACECAST(SDValue Op, SelectionDAG &DAG) {
6720+ SDLoc dl(Op);
6721+ SDValue Src = Op.getOperand(0);
6722+ MVT DestVT = Op.getSimpleValueType();
6723+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6724+ AddrSpaceCastSDNode *N = cast<AddrSpaceCastSDNode>(Op.getNode());
6725+
6726+ unsigned SrcAS = N->getSrcAddressSpace();
6727+ unsigned DestAS = N->getDestAddressSpace();
6728+ assert(SrcAS != DestAS &&
6729+ "addrspacecast must be between different address spaces");
6730+ assert(TLI.getTargetMachine().getPointerSize(SrcAS) !=
6731+ TLI.getTargetMachine().getPointerSize(DestAS) &&
6732+ "addrspacecast must be between different ptr sizes");
6733+
6734+ if (SrcAS == ARM64AS::PTR32_SPTR) {
6735+ return DAG.getNode(ISD::SIGN_EXTEND, dl, DestVT, Src,
6736+ DAG.getTargetConstant(0, dl, DestVT));
6737+ } else if (SrcAS == ARM64AS::PTR32_UPTR) {
6738+ return DAG.getNode(ISD::ZERO_EXTEND, dl, DestVT, Src,
6739+ DAG.getTargetConstant(0, dl, DestVT));
6740+ } else if ((DestAS == ARM64AS::PTR32_SPTR) ||
6741+ (DestAS == ARM64AS::PTR32_UPTR)) {
6742+ SDValue Ext = DAG.getAnyExtOrTrunc(Src, dl, DestVT);
6743+ SDValue Trunc = DAG.getZeroExtendInReg(Ext, dl, DestVT);
6744+ return Trunc;
6745+ } else {
6746+ return Src;
6747+ }
6748+ }
6749+
67166750// Custom lowering for any store, vector or scalar and/or default or with
67176751// a truncate operations. Currently only custom lower truncate operation
67186752// from vector v4i16 to v4i8 or volatile stores of i128.
@@ -7366,6 +7400,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
73667400 case ISD::SIGN_EXTEND:
73677401 case ISD::ZERO_EXTEND:
73687402 return LowerFixedLengthVectorIntExtendToSVE(Op, DAG);
7403+ case ISD::ADDRSPACECAST:
7404+ return LowerADDRSPACECAST(Op, DAG);
73697405 case ISD::SIGN_EXTEND_INREG: {
73707406 // Only custom lower when ExtraVT has a legal byte based element type.
73717407 EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
@@ -23327,6 +23363,26 @@ static SDValue performLOADCombine(SDNode *N,
2332723363 performTBISimplification(N->getOperand(1), DCI, DAG);
2332823364
2332923365 LoadSDNode *LD = cast<LoadSDNode>(N);
23366+ EVT RegVT = LD->getValueType(0);
23367+ EVT MemVT = LD->getMemoryVT();
23368+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23369+ SDLoc DL(LD);
23370+
23371+ // Cast ptr32 and ptr64 pointers to the default address space before a load.
23372+ unsigned AddrSpace = LD->getAddressSpace();
23373+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
23374+ AddrSpace == ARM64AS::PTR32_UPTR) {
23375+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
23376+ if (PtrVT != LD->getBasePtr().getSimpleValueType()) {
23377+ SDValue Cast =
23378+ DAG.getAddrSpaceCast(DL, PtrVT, LD->getBasePtr(), AddrSpace, 0);
23379+ return DAG.getExtLoad(LD->getExtensionType(), DL, RegVT, LD->getChain(),
23380+ Cast, LD->getPointerInfo(), MemVT,
23381+ LD->getOriginalAlign(),
23382+ LD->getMemOperand()->getFlags());
23383+ }
23384+ }
23385+
2333023386 if (LD->isVolatile() || !Subtarget->isLittleEndian())
2333123387 return SDValue(N, 0);
2333223388
@@ -23336,13 +23392,11 @@ static SDValue performLOADCombine(SDNode *N,
2333623392 if (!LD->isNonTemporal())
2333723393 return SDValue(N, 0);
2333823394
23339- EVT MemVT = LD->getMemoryVT();
2334023395 if (MemVT.isScalableVector() || MemVT.getSizeInBits() <= 256 ||
2334123396 MemVT.getSizeInBits() % 256 == 0 ||
2334223397 256 % MemVT.getScalarSizeInBits() != 0)
2334323398 return SDValue(N, 0);
2334423399
23345- SDLoc DL(LD);
2334623400 SDValue Chain = LD->getChain();
2334723401 SDValue BasePtr = LD->getBasePtr();
2334823402 SDNodeFlags Flags = LD->getFlags();
@@ -23602,12 +23656,28 @@ static SDValue performSTORECombine(SDNode *N,
2360223656 SDValue Value = ST->getValue();
2360323657 SDValue Ptr = ST->getBasePtr();
2360423658 EVT ValueVT = Value.getValueType();
23659+ EVT MemVT = ST->getMemoryVT();
23660+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23661+ SDLoc DL(ST);
2360523662
2360623663 auto hasValidElementTypeForFPTruncStore = [](EVT VT) {
2360723664 EVT EltVT = VT.getVectorElementType();
2360823665 return EltVT == MVT::f32 || EltVT == MVT::f64;
2360923666 };
2361023667
23668+ // Cast ptr32 and ptr64 pointers to the default address space before a store.
23669+ unsigned AddrSpace = ST->getAddressSpace();
23670+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
23671+ AddrSpace == ARM64AS::PTR32_UPTR) {
23672+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
23673+ if (PtrVT != Ptr.getSimpleValueType()) {
23674+ SDValue Cast = DAG.getAddrSpaceCast(DL, PtrVT, Ptr, AddrSpace, 0);
23675+ return DAG.getStore(Chain, DL, Value, Cast, ST->getPointerInfo(),
23676+ ST->getOriginalAlign(),
23677+ ST->getMemOperand()->getFlags(), ST->getAAInfo());
23678+ }
23679+ }
23680+
2361123681 if (SDValue Res = combineI8TruncStore(ST, DAG, Subtarget))
2361223682 return Res;
2361323683
@@ -23621,8 +23691,8 @@ static SDValue performSTORECombine(SDNode *N,
2362123691 ValueVT.isFixedLengthVector() &&
2362223692 ValueVT.getFixedSizeInBits() >= Subtarget->getMinSVEVectorSizeInBits() &&
2362323693 hasValidElementTypeForFPTruncStore(Value.getOperand(0).getValueType()))
23624- return DAG.getTruncStore(Chain, SDLoc(N) , Value.getOperand(0), Ptr,
23625- ST->getMemoryVT(), ST-> getMemOperand());
23694+ return DAG.getTruncStore(Chain, DL , Value.getOperand(0), Ptr, MemVT ,
23695+ ST->getMemOperand());
2362623696
2362723697 if (SDValue Split = splitStores(N, DCI, DAG, Subtarget))
2362823698 return Split;
@@ -26949,6 +27019,11 @@ void AArch64TargetLowering::ReplaceNodeResults(
2694927019 ReplaceATOMIC_LOAD_128Results(N, Results, DAG, Subtarget);
2695027020 return;
2695127021 }
27022+ case ISD::ADDRSPACECAST: {
27023+ SDValue V = LowerADDRSPACECAST(SDValue(N, 0), DAG);
27024+ Results.push_back(V);
27025+ return;
27026+ }
2695227027 case ISD::ATOMIC_LOAD:
2695327028 case ISD::LOAD: {
2695427029 MemSDNode *LoadNode = cast<MemSDNode>(N);
0 commit comments