@@ -531,6 +531,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
531531 setOperationAction(ISD::XOR, MVT::i32, Custom);
532532 setOperationAction(ISD::XOR, MVT::i64, Custom);
533533
534+ setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
535+ setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
536+
534537 // Virtually no operation on f128 is legal, but LLVM can't expand them when
535538 // there's a valid register class, so we need custom operations in most cases.
536539 setOperationAction(ISD::FABS, MVT::f128, Expand);
@@ -6651,6 +6654,37 @@ static SDValue LowerTruncateVectorStore(SDLoc DL, StoreSDNode *ST,
66516654 ST->getBasePtr(), ST->getMemOperand());
66526655}
66536656
6657+ static SDValue LowerADDRSPACECAST(SDValue Op, SelectionDAG &DAG) {
6658+ SDLoc dl(Op);
6659+ SDValue Src = Op.getOperand(0);
6660+ MVT DestVT = Op.getSimpleValueType();
6661+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6662+ AddrSpaceCastSDNode *N = cast<AddrSpaceCastSDNode>(Op.getNode());
6663+
6664+ unsigned SrcAS = N->getSrcAddressSpace();
6665+ unsigned DestAS = N->getDestAddressSpace();
6666+ assert(SrcAS != DestAS &&
6667+ "addrspacecast must be between different address spaces");
6668+ assert(TLI.getTargetMachine().getPointerSize(SrcAS) !=
6669+ TLI.getTargetMachine().getPointerSize(DestAS) &&
6670+ "addrspacecast must be between different ptr sizes");
6671+
6672+ if (SrcAS == ARM64AS::PTR32_SPTR) {
6673+ return DAG.getNode(ISD::SIGN_EXTEND, dl, DestVT, Src,
6674+ DAG.getTargetConstant(0, dl, DestVT));
6675+ } else if (SrcAS == ARM64AS::PTR32_UPTR) {
6676+ return DAG.getNode(ISD::ZERO_EXTEND, dl, DestVT, Src,
6677+ DAG.getTargetConstant(0, dl, DestVT));
6678+ } else if ((DestAS == ARM64AS::PTR32_SPTR) ||
6679+ (DestAS == ARM64AS::PTR32_UPTR)) {
6680+ SDValue Ext = DAG.getAnyExtOrTrunc(Src, dl, DestVT);
6681+ SDValue Trunc = DAG.getZeroExtendInReg(Ext, dl, DestVT);
6682+ return Trunc;
6683+ } else {
6684+ return Src;
6685+ }
6686+ }
6687+
66546688// Custom lowering for any store, vector or scalar and/or default or with
66556689// a truncate operations. Currently only custom lower truncate operation
66566690// from vector v4i16 to v4i8 or volatile stores of i128.
@@ -7304,6 +7338,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
73047338 case ISD::SIGN_EXTEND:
73057339 case ISD::ZERO_EXTEND:
73067340 return LowerFixedLengthVectorIntExtendToSVE(Op, DAG);
7341+ case ISD::ADDRSPACECAST:
7342+ return LowerADDRSPACECAST(Op, DAG);
73077343 case ISD::SIGN_EXTEND_INREG: {
73087344 // Only custom lower when ExtraVT has a legal byte based element type.
73097345 EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
@@ -23215,6 +23251,26 @@ static SDValue performLOADCombine(SDNode *N,
2321523251 performTBISimplification(N->getOperand(1), DCI, DAG);
2321623252
2321723253 LoadSDNode *LD = cast<LoadSDNode>(N);
23254+ EVT RegVT = LD->getValueType(0);
23255+ EVT MemVT = LD->getMemoryVT();
23256+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23257+ SDLoc DL(LD);
23258+
23259+ // Cast ptr32 and ptr64 pointers to the default address space before a load.
23260+ unsigned AddrSpace = LD->getAddressSpace();
23261+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
23262+ AddrSpace == ARM64AS::PTR32_UPTR) {
23263+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
23264+ if (PtrVT != LD->getBasePtr().getSimpleValueType()) {
23265+ SDValue Cast =
23266+ DAG.getAddrSpaceCast(DL, PtrVT, LD->getBasePtr(), AddrSpace, 0);
23267+ return DAG.getExtLoad(LD->getExtensionType(), DL, RegVT, LD->getChain(),
23268+ Cast, LD->getPointerInfo(), MemVT,
23269+ LD->getOriginalAlign(),
23270+ LD->getMemOperand()->getFlags());
23271+ }
23272+ }
23273+
2321823274 if (LD->isVolatile() || !Subtarget->isLittleEndian())
2321923275 return SDValue(N, 0);
2322023276
@@ -23224,13 +23280,11 @@ static SDValue performLOADCombine(SDNode *N,
2322423280 if (!LD->isNonTemporal())
2322523281 return SDValue(N, 0);
2322623282
23227- EVT MemVT = LD->getMemoryVT();
2322823283 if (MemVT.isScalableVector() || MemVT.getSizeInBits() <= 256 ||
2322923284 MemVT.getSizeInBits() % 256 == 0 ||
2323023285 256 % MemVT.getScalarSizeInBits() != 0)
2323123286 return SDValue(N, 0);
2323223287
23233- SDLoc DL(LD);
2323423288 SDValue Chain = LD->getChain();
2323523289 SDValue BasePtr = LD->getBasePtr();
2323623290 SDNodeFlags Flags = LD->getFlags();
@@ -23490,12 +23544,28 @@ static SDValue performSTORECombine(SDNode *N,
2349023544 SDValue Value = ST->getValue();
2349123545 SDValue Ptr = ST->getBasePtr();
2349223546 EVT ValueVT = Value.getValueType();
23547+ EVT MemVT = ST->getMemoryVT();
23548+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23549+ SDLoc DL(ST);
2349323550
2349423551 auto hasValidElementTypeForFPTruncStore = [](EVT VT) {
2349523552 EVT EltVT = VT.getVectorElementType();
2349623553 return EltVT == MVT::f32 || EltVT == MVT::f64;
2349723554 };
2349823555
23556+ // Cast ptr32 and ptr64 pointers to the default address space before a store.
23557+ unsigned AddrSpace = ST->getAddressSpace();
23558+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
23559+ AddrSpace == ARM64AS::PTR32_UPTR) {
23560+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
23561+ if (PtrVT != Ptr.getSimpleValueType()) {
23562+ SDValue Cast = DAG.getAddrSpaceCast(DL, PtrVT, Ptr, AddrSpace, 0);
23563+ return DAG.getStore(Chain, DL, Value, Cast, ST->getPointerInfo(),
23564+ ST->getOriginalAlign(),
23565+ ST->getMemOperand()->getFlags(), ST->getAAInfo());
23566+ }
23567+ }
23568+
2349923569 if (SDValue Res = combineI8TruncStore(ST, DAG, Subtarget))
2350023570 return Res;
2350123571
@@ -23509,8 +23579,8 @@ static SDValue performSTORECombine(SDNode *N,
2350923579 ValueVT.isFixedLengthVector() &&
2351023580 ValueVT.getFixedSizeInBits() >= Subtarget->getMinSVEVectorSizeInBits() &&
2351123581 hasValidElementTypeForFPTruncStore(Value.getOperand(0).getValueType()))
23512- return DAG.getTruncStore(Chain, SDLoc(N) , Value.getOperand(0), Ptr,
23513- ST->getMemoryVT(), ST-> getMemOperand());
23582+ return DAG.getTruncStore(Chain, DL , Value.getOperand(0), Ptr, MemVT ,
23583+ ST->getMemOperand());
2351423584
2351523585 if (SDValue Split = splitStores(N, DCI, DAG, Subtarget))
2351623586 return Split;
@@ -26832,6 +26902,11 @@ void AArch64TargetLowering::ReplaceNodeResults(
2683226902 ReplaceATOMIC_LOAD_128Results(N, Results, DAG, Subtarget);
2683326903 return;
2683426904 }
26905+ case ISD::ADDRSPACECAST: {
26906+ SDValue V = LowerADDRSPACECAST(SDValue(N, 0), DAG);
26907+ Results.push_back(V);
26908+ return;
26909+ }
2683526910 case ISD::ATOMIC_LOAD:
2683626911 case ISD::LOAD: {
2683726912 MemSDNode *LoadNode = cast<MemSDNode>(N);
0 commit comments