@@ -532,6 +532,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
532
532
setOperationAction(ISD::XOR, MVT::i32, Custom);
533
533
setOperationAction(ISD::XOR, MVT::i64, Custom);
534
534
535
+ setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
536
+ setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
537
+
535
538
// Virtually no operation on f128 is legal, but LLVM can't expand them when
536
539
// there's a valid register class, so we need custom operations in most cases.
537
540
setOperationAction(ISD::FABS, MVT::f128, Expand);
@@ -6713,6 +6716,37 @@ static SDValue LowerTruncateVectorStore(SDLoc DL, StoreSDNode *ST,
6713
6716
ST->getBasePtr(), ST->getMemOperand());
6714
6717
}
6715
6718
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
+
6716
6750
// Custom lowering for any store, vector or scalar and/or default or with
6717
6751
// a truncate operations. Currently only custom lower truncate operation
6718
6752
// from vector v4i16 to v4i8 or volatile stores of i128.
@@ -7366,6 +7400,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
7366
7400
case ISD::SIGN_EXTEND:
7367
7401
case ISD::ZERO_EXTEND:
7368
7402
return LowerFixedLengthVectorIntExtendToSVE(Op, DAG);
7403
+ case ISD::ADDRSPACECAST:
7404
+ return LowerADDRSPACECAST(Op, DAG);
7369
7405
case ISD::SIGN_EXTEND_INREG: {
7370
7406
// Only custom lower when ExtraVT has a legal byte based element type.
7371
7407
EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
@@ -23327,6 +23363,26 @@ static SDValue performLOADCombine(SDNode *N,
23327
23363
performTBISimplification(N->getOperand(1), DCI, DAG);
23328
23364
23329
23365
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
+
23330
23386
if (LD->isVolatile() || !Subtarget->isLittleEndian())
23331
23387
return SDValue(N, 0);
23332
23388
@@ -23336,13 +23392,11 @@ static SDValue performLOADCombine(SDNode *N,
23336
23392
if (!LD->isNonTemporal())
23337
23393
return SDValue(N, 0);
23338
23394
23339
- EVT MemVT = LD->getMemoryVT();
23340
23395
if (MemVT.isScalableVector() || MemVT.getSizeInBits() <= 256 ||
23341
23396
MemVT.getSizeInBits() % 256 == 0 ||
23342
23397
256 % MemVT.getScalarSizeInBits() != 0)
23343
23398
return SDValue(N, 0);
23344
23399
23345
- SDLoc DL(LD);
23346
23400
SDValue Chain = LD->getChain();
23347
23401
SDValue BasePtr = LD->getBasePtr();
23348
23402
SDNodeFlags Flags = LD->getFlags();
@@ -23602,12 +23656,28 @@ static SDValue performSTORECombine(SDNode *N,
23602
23656
SDValue Value = ST->getValue();
23603
23657
SDValue Ptr = ST->getBasePtr();
23604
23658
EVT ValueVT = Value.getValueType();
23659
+ EVT MemVT = ST->getMemoryVT();
23660
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23661
+ SDLoc DL(ST);
23605
23662
23606
23663
auto hasValidElementTypeForFPTruncStore = [](EVT VT) {
23607
23664
EVT EltVT = VT.getVectorElementType();
23608
23665
return EltVT == MVT::f32 || EltVT == MVT::f64;
23609
23666
};
23610
23667
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
+
23611
23681
if (SDValue Res = combineI8TruncStore(ST, DAG, Subtarget))
23612
23682
return Res;
23613
23683
@@ -23621,8 +23691,8 @@ static SDValue performSTORECombine(SDNode *N,
23621
23691
ValueVT.isFixedLengthVector() &&
23622
23692
ValueVT.getFixedSizeInBits() >= Subtarget->getMinSVEVectorSizeInBits() &&
23623
23693
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());
23626
23696
23627
23697
if (SDValue Split = splitStores(N, DCI, DAG, Subtarget))
23628
23698
return Split;
@@ -26949,6 +27019,11 @@ void AArch64TargetLowering::ReplaceNodeResults(
26949
27019
ReplaceATOMIC_LOAD_128Results(N, Results, DAG, Subtarget);
26950
27020
return;
26951
27021
}
27022
+ case ISD::ADDRSPACECAST: {
27023
+ SDValue V = LowerADDRSPACECAST(SDValue(N, 0), DAG);
27024
+ Results.push_back(V);
27025
+ return;
27026
+ }
26952
27027
case ISD::ATOMIC_LOAD:
26953
27028
case ISD::LOAD: {
26954
27029
MemSDNode *LoadNode = cast<MemSDNode>(N);
0 commit comments