@@ -530,6 +530,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
530
530
setOperationAction(ISD::XOR, MVT::i32, Custom);
531
531
setOperationAction(ISD::XOR, MVT::i64, Custom);
532
532
533
+ setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
534
+ setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
535
+
533
536
// Virtually no operation on f128 is legal, but LLVM can't expand them when
534
537
// there's a valid register class, so we need custom operations in most cases.
535
538
setOperationAction(ISD::FABS, MVT::f128, Expand);
@@ -6746,6 +6749,37 @@ static SDValue LowerTruncateVectorStore(SDLoc DL, StoreSDNode *ST,
6746
6749
ST->getBasePtr(), ST->getMemOperand());
6747
6750
}
6748
6751
6752
+ static SDValue LowerADDRSPACECAST(SDValue Op, SelectionDAG &DAG) {
6753
+ SDLoc dl(Op);
6754
+ SDValue Src = Op.getOperand(0);
6755
+ MVT DestVT = Op.getSimpleValueType();
6756
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6757
+ AddrSpaceCastSDNode *N = cast<AddrSpaceCastSDNode>(Op.getNode());
6758
+
6759
+ unsigned SrcAS = N->getSrcAddressSpace();
6760
+ unsigned DestAS = N->getDestAddressSpace();
6761
+ assert(SrcAS != DestAS &&
6762
+ "addrspacecast must be between different address spaces");
6763
+ assert(TLI.getTargetMachine().getPointerSize(SrcAS) !=
6764
+ TLI.getTargetMachine().getPointerSize(DestAS) &&
6765
+ "addrspacecast must be between different ptr sizes");
6766
+
6767
+ if (SrcAS == ARM64AS::PTR32_SPTR) {
6768
+ return DAG.getNode(ISD::SIGN_EXTEND, dl, DestVT, Src,
6769
+ DAG.getTargetConstant(0, dl, DestVT));
6770
+ } else if (SrcAS == ARM64AS::PTR32_UPTR) {
6771
+ return DAG.getNode(ISD::ZERO_EXTEND, dl, DestVT, Src,
6772
+ DAG.getTargetConstant(0, dl, DestVT));
6773
+ } else if ((DestAS == ARM64AS::PTR32_SPTR) ||
6774
+ (DestAS == ARM64AS::PTR32_UPTR)) {
6775
+ SDValue Ext = DAG.getAnyExtOrTrunc(Src, dl, DestVT);
6776
+ SDValue Trunc = DAG.getZeroExtendInReg(Ext, dl, DestVT);
6777
+ return Trunc;
6778
+ } else {
6779
+ return Src;
6780
+ }
6781
+ }
6782
+
6749
6783
// Custom lowering for any store, vector or scalar and/or default or with
6750
6784
// a truncate operations. Currently only custom lower truncate operation
6751
6785
// from vector v4i16 to v4i8 or volatile stores of i128.
@@ -7399,6 +7433,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
7399
7433
case ISD::SIGN_EXTEND:
7400
7434
case ISD::ZERO_EXTEND:
7401
7435
return LowerFixedLengthVectorIntExtendToSVE(Op, DAG);
7436
+ case ISD::ADDRSPACECAST:
7437
+ return LowerADDRSPACECAST(Op, DAG);
7402
7438
case ISD::SIGN_EXTEND_INREG: {
7403
7439
// Only custom lower when ExtraVT has a legal byte based element type.
7404
7440
EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
@@ -23448,6 +23484,26 @@ static SDValue performLOADCombine(SDNode *N,
23448
23484
performTBISimplification(N->getOperand(1), DCI, DAG);
23449
23485
23450
23486
LoadSDNode *LD = cast<LoadSDNode>(N);
23487
+ EVT RegVT = LD->getValueType(0);
23488
+ EVT MemVT = LD->getMemoryVT();
23489
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23490
+ SDLoc DL(LD);
23491
+
23492
+ // Cast ptr32 and ptr64 pointers to the default address space before a load.
23493
+ unsigned AddrSpace = LD->getAddressSpace();
23494
+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
23495
+ AddrSpace == ARM64AS::PTR32_UPTR) {
23496
+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
23497
+ if (PtrVT != LD->getBasePtr().getSimpleValueType()) {
23498
+ SDValue Cast =
23499
+ DAG.getAddrSpaceCast(DL, PtrVT, LD->getBasePtr(), AddrSpace, 0);
23500
+ return DAG.getExtLoad(LD->getExtensionType(), DL, RegVT, LD->getChain(),
23501
+ Cast, LD->getPointerInfo(), MemVT,
23502
+ LD->getOriginalAlign(),
23503
+ LD->getMemOperand()->getFlags());
23504
+ }
23505
+ }
23506
+
23451
23507
if (LD->isVolatile() || !Subtarget->isLittleEndian())
23452
23508
return SDValue(N, 0);
23453
23509
@@ -23457,13 +23513,11 @@ static SDValue performLOADCombine(SDNode *N,
23457
23513
if (!LD->isNonTemporal())
23458
23514
return SDValue(N, 0);
23459
23515
23460
- EVT MemVT = LD->getMemoryVT();
23461
23516
if (MemVT.isScalableVector() || MemVT.getSizeInBits() <= 256 ||
23462
23517
MemVT.getSizeInBits() % 256 == 0 ||
23463
23518
256 % MemVT.getScalarSizeInBits() != 0)
23464
23519
return SDValue(N, 0);
23465
23520
23466
- SDLoc DL(LD);
23467
23521
SDValue Chain = LD->getChain();
23468
23522
SDValue BasePtr = LD->getBasePtr();
23469
23523
SDNodeFlags Flags = LD->getFlags();
@@ -23723,12 +23777,28 @@ static SDValue performSTORECombine(SDNode *N,
23723
23777
SDValue Value = ST->getValue();
23724
23778
SDValue Ptr = ST->getBasePtr();
23725
23779
EVT ValueVT = Value.getValueType();
23780
+ EVT MemVT = ST->getMemoryVT();
23781
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23782
+ SDLoc DL(ST);
23726
23783
23727
23784
auto hasValidElementTypeForFPTruncStore = [](EVT VT) {
23728
23785
EVT EltVT = VT.getVectorElementType();
23729
23786
return EltVT == MVT::f32 || EltVT == MVT::f64;
23730
23787
};
23731
23788
23789
+ // Cast ptr32 and ptr64 pointers to the default address space before a store.
23790
+ unsigned AddrSpace = ST->getAddressSpace();
23791
+ if (AddrSpace == ARM64AS::PTR64 || AddrSpace == ARM64AS::PTR32_SPTR ||
23792
+ AddrSpace == ARM64AS::PTR32_UPTR) {
23793
+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
23794
+ if (PtrVT != Ptr.getSimpleValueType()) {
23795
+ SDValue Cast = DAG.getAddrSpaceCast(DL, PtrVT, Ptr, AddrSpace, 0);
23796
+ return DAG.getStore(Chain, DL, Value, Cast, ST->getPointerInfo(),
23797
+ ST->getOriginalAlign(),
23798
+ ST->getMemOperand()->getFlags(), ST->getAAInfo());
23799
+ }
23800
+ }
23801
+
23732
23802
if (SDValue Res = combineI8TruncStore(ST, DAG, Subtarget))
23733
23803
return Res;
23734
23804
@@ -23742,8 +23812,8 @@ static SDValue performSTORECombine(SDNode *N,
23742
23812
ValueVT.isFixedLengthVector() &&
23743
23813
ValueVT.getFixedSizeInBits() >= Subtarget->getMinSVEVectorSizeInBits() &&
23744
23814
hasValidElementTypeForFPTruncStore(Value.getOperand(0).getValueType()))
23745
- return DAG.getTruncStore(Chain, SDLoc(N) , Value.getOperand(0), Ptr,
23746
- ST->getMemoryVT(), ST-> getMemOperand());
23815
+ return DAG.getTruncStore(Chain, DL , Value.getOperand(0), Ptr, MemVT ,
23816
+ ST->getMemOperand());
23747
23817
23748
23818
if (SDValue Split = splitStores(N, DCI, DAG, Subtarget))
23749
23819
return Split;
@@ -27070,6 +27140,11 @@ void AArch64TargetLowering::ReplaceNodeResults(
27070
27140
ReplaceATOMIC_LOAD_128Results(N, Results, DAG, Subtarget);
27071
27141
return;
27072
27142
}
27143
+ case ISD::ADDRSPACECAST: {
27144
+ SDValue V = LowerADDRSPACECAST(SDValue(N, 0), DAG);
27145
+ Results.push_back(V);
27146
+ return;
27147
+ }
27073
27148
case ISD::ATOMIC_LOAD:
27074
27149
case ISD::LOAD: {
27075
27150
MemSDNode *LoadNode = cast<MemSDNode>(N);
0 commit comments