@@ -533,6 +533,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
533533 setOperationAction(ISD::XOR, MVT::i32, Custom);
534534 setOperationAction(ISD::XOR, MVT::i64, Custom);
535535
536+ setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
537+ setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
538+
536539 // Virtually no operation on f128 is legal, but LLVM can't expand them when
537540 // there's a valid register class, so we need custom operations in most cases.
538541 setOperationAction(ISD::FABS, MVT::f128, Expand);
@@ -6722,6 +6725,37 @@ static SDValue LowerTruncateVectorStore(SDLoc DL, StoreSDNode *ST,
67226725 ST->getBasePtr(), ST->getMemOperand());
67236726}
67246727
6728+ static SDValue LowerADDRSPACECAST(SDValue Op, SelectionDAG &DAG) {
6729+ SDLoc dl(Op);
6730+ SDValue Src = Op.getOperand(0);
6731+ MVT DestVT = Op.getSimpleValueType();
6732+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6733+ AddrSpaceCastSDNode *N = cast<AddrSpaceCastSDNode>(Op.getNode());
6734+
6735+ unsigned SrcAS = N->getSrcAddressSpace();
6736+ unsigned DestAS = N->getDestAddressSpace();
6737+ assert(SrcAS != DestAS &&
6738+ "addrspacecast must be between different address spaces");
6739+ assert(TLI.getTargetMachine().getPointerSize(SrcAS) !=
6740+ TLI.getTargetMachine().getPointerSize(DestAS) &&
6741+ "addrspacecast must be between different ptr sizes");
6742+
6743+ if (SrcAS == ARM64AS::PTR32_SPTR) {
6744+ return DAG.getNode(ISD::SIGN_EXTEND, dl, DestVT, Src,
6745+ DAG.getTargetConstant(0, dl, DestVT));
6746+ } else if (SrcAS == ARM64AS::PTR32_UPTR) {
6747+ return DAG.getNode(ISD::ZERO_EXTEND, dl, DestVT, Src,
6748+ DAG.getTargetConstant(0, dl, DestVT));
6749+ } else if ((DestAS == ARM64AS::PTR32_SPTR) ||
6750+ (DestAS == ARM64AS::PTR32_UPTR)) {
6751+ SDValue Ext = DAG.getAnyExtOrTrunc(Src, dl, DestVT);
6752+ SDValue Trunc = DAG.getZeroExtendInReg(Ext, dl, DestVT);
6753+ return Trunc;
6754+ } else {
6755+ return Src;
6756+ }
6757+ }
6758+
67256759// Custom lowering for any store, vector or scalar and/or default or with
67266760// a truncate operations. Currently only custom lower truncate operation
67276761// from vector v4i16 to v4i8 or volatile stores of i128.
@@ -7375,6 +7409,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
73757409 case ISD::SIGN_EXTEND:
73767410 case ISD::ZERO_EXTEND:
73777411 return LowerFixedLengthVectorIntExtendToSVE(Op, DAG);
7412+ case ISD::ADDRSPACECAST:
7413+ return LowerADDRSPACECAST(Op, DAG);
73787414 case ISD::SIGN_EXTEND_INREG: {
73797415 // Only custom lower when ExtraVT has a legal byte based element type.
73807416 EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
@@ -23361,6 +23397,26 @@ static SDValue performLOADCombine(SDNode *N,
2336123397 performTBISimplification(N->getOperand(1), DCI, DAG);
2336223398
2336323399 LoadSDNode *LD = cast<LoadSDNode>(N);
23400+ EVT RegVT = LD->getValueType(0);
23401+ EVT MemVT = LD->getMemoryVT();
23402+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23403+ SDLoc DL(LD);
23404+
23405+ // Cast ptr32 and ptr64 pointers to the default address space before a load.
23406+ unsigned AddrSpace = LD->getAddressSpace();
23407+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
23408+ AddrSpace == ARM64AS::PTR32_UPTR) {
23409+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
23410+ if (PtrVT != LD->getBasePtr().getSimpleValueType()) {
23411+ SDValue Cast =
23412+ DAG.getAddrSpaceCast(DL, PtrVT, LD->getBasePtr(), AddrSpace, 0);
23413+ return DAG.getExtLoad(LD->getExtensionType(), DL, RegVT, LD->getChain(),
23414+ Cast, LD->getPointerInfo(), MemVT,
23415+ LD->getOriginalAlign(),
23416+ LD->getMemOperand()->getFlags());
23417+ }
23418+ }
23419+
2336423420 if (LD->isVolatile() || !Subtarget->isLittleEndian())
2336523421 return SDValue(N, 0);
2336623422
@@ -23370,13 +23426,11 @@ static SDValue performLOADCombine(SDNode *N,
2337023426 if (!LD->isNonTemporal())
2337123427 return SDValue(N, 0);
2337223428
23373- EVT MemVT = LD->getMemoryVT();
2337423429 if (MemVT.isScalableVector() || MemVT.getSizeInBits() <= 256 ||
2337523430 MemVT.getSizeInBits() % 256 == 0 ||
2337623431 256 % MemVT.getScalarSizeInBits() != 0)
2337723432 return SDValue(N, 0);
2337823433
23379- SDLoc DL(LD);
2338023434 SDValue Chain = LD->getChain();
2338123435 SDValue BasePtr = LD->getBasePtr();
2338223436 SDNodeFlags Flags = LD->getFlags();
@@ -23636,12 +23690,28 @@ static SDValue performSTORECombine(SDNode *N,
2363623690 SDValue Value = ST->getValue();
2363723691 SDValue Ptr = ST->getBasePtr();
2363823692 EVT ValueVT = Value.getValueType();
23693+ EVT MemVT = ST->getMemoryVT();
23694+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23695+ SDLoc DL(ST);
2363923696
2364023697 auto hasValidElementTypeForFPTruncStore = [](EVT VT) {
2364123698 EVT EltVT = VT.getVectorElementType();
2364223699 return EltVT == MVT::f32 || EltVT == MVT::f64;
2364323700 };
2364423701
23702+ // Cast ptr32 and ptr64 pointers to the default address space before a store.
23703+ unsigned AddrSpace = ST->getAddressSpace();
23704+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
23705+ AddrSpace == ARM64AS::PTR32_UPTR) {
23706+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
23707+ if (PtrVT != Ptr.getSimpleValueType()) {
23708+ SDValue Cast = DAG.getAddrSpaceCast(DL, PtrVT, Ptr, AddrSpace, 0);
23709+ return DAG.getStore(Chain, DL, Value, Cast, ST->getPointerInfo(),
23710+ ST->getOriginalAlign(),
23711+ ST->getMemOperand()->getFlags(), ST->getAAInfo());
23712+ }
23713+ }
23714+
2364523715 if (SDValue Res = combineI8TruncStore(ST, DAG, Subtarget))
2364623716 return Res;
2364723717
@@ -23655,8 +23725,8 @@ static SDValue performSTORECombine(SDNode *N,
2365523725 ValueVT.isFixedLengthVector() &&
2365623726 ValueVT.getFixedSizeInBits() >= Subtarget->getMinSVEVectorSizeInBits() &&
2365723727 hasValidElementTypeForFPTruncStore(Value.getOperand(0).getValueType()))
23658- return DAG.getTruncStore(Chain, SDLoc(N) , Value.getOperand(0), Ptr,
23659- ST->getMemoryVT(), ST-> getMemOperand());
23728+ return DAG.getTruncStore(Chain, DL , Value.getOperand(0), Ptr, MemVT ,
23729+ ST->getMemOperand());
2366023730
2366123731 if (SDValue Split = splitStores(N, DCI, DAG, Subtarget))
2366223732 return Split;
@@ -26983,6 +27053,11 @@ void AArch64TargetLowering::ReplaceNodeResults(
2698327053 ReplaceATOMIC_LOAD_128Results(N, Results, DAG, Subtarget);
2698427054 return;
2698527055 }
27056+ case ISD::ADDRSPACECAST: {
27057+ SDValue V = LowerADDRSPACECAST(SDValue(N, 0), DAG);
27058+ Results.push_back(V);
27059+ return;
27060+ }
2698627061 case ISD::ATOMIC_LOAD:
2698727062 case ISD::LOAD: {
2698827063 MemSDNode *LoadNode = cast<MemSDNode>(N);
0 commit comments