@@ -533,6 +533,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
533
533
setOperationAction(ISD::XOR, MVT::i32, Custom);
534
534
setOperationAction(ISD::XOR, MVT::i64, Custom);
535
535
536
+ setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
537
+ setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
538
+
536
539
// Virtually no operation on f128 is legal, but LLVM can't expand them when
537
540
// there's a valid register class, so we need custom operations in most cases.
538
541
setOperationAction(ISD::FABS, MVT::f128, Expand);
@@ -6722,6 +6725,37 @@ static SDValue LowerTruncateVectorStore(SDLoc DL, StoreSDNode *ST,
6722
6725
ST->getBasePtr(), ST->getMemOperand());
6723
6726
}
6724
6727
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
+
6725
6759
// Custom lowering for any store, vector or scalar and/or default or with
6726
6760
// a truncate operations. Currently only custom lower truncate operation
6727
6761
// from vector v4i16 to v4i8 or volatile stores of i128.
@@ -7375,6 +7409,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
7375
7409
case ISD::SIGN_EXTEND:
7376
7410
case ISD::ZERO_EXTEND:
7377
7411
return LowerFixedLengthVectorIntExtendToSVE(Op, DAG);
7412
+ case ISD::ADDRSPACECAST:
7413
+ return LowerADDRSPACECAST(Op, DAG);
7378
7414
case ISD::SIGN_EXTEND_INREG: {
7379
7415
// Only custom lower when ExtraVT has a legal byte based element type.
7380
7416
EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
@@ -23361,6 +23397,26 @@ static SDValue performLOADCombine(SDNode *N,
23361
23397
performTBISimplification(N->getOperand(1), DCI, DAG);
23362
23398
23363
23399
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
+
23364
23420
if (LD->isVolatile() || !Subtarget->isLittleEndian())
23365
23421
return SDValue(N, 0);
23366
23422
@@ -23370,13 +23426,11 @@ static SDValue performLOADCombine(SDNode *N,
23370
23426
if (!LD->isNonTemporal())
23371
23427
return SDValue(N, 0);
23372
23428
23373
- EVT MemVT = LD->getMemoryVT();
23374
23429
if (MemVT.isScalableVector() || MemVT.getSizeInBits() <= 256 ||
23375
23430
MemVT.getSizeInBits() % 256 == 0 ||
23376
23431
256 % MemVT.getScalarSizeInBits() != 0)
23377
23432
return SDValue(N, 0);
23378
23433
23379
- SDLoc DL(LD);
23380
23434
SDValue Chain = LD->getChain();
23381
23435
SDValue BasePtr = LD->getBasePtr();
23382
23436
SDNodeFlags Flags = LD->getFlags();
@@ -23636,12 +23690,28 @@ static SDValue performSTORECombine(SDNode *N,
23636
23690
SDValue Value = ST->getValue();
23637
23691
SDValue Ptr = ST->getBasePtr();
23638
23692
EVT ValueVT = Value.getValueType();
23693
+ EVT MemVT = ST->getMemoryVT();
23694
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23695
+ SDLoc DL(ST);
23639
23696
23640
23697
auto hasValidElementTypeForFPTruncStore = [](EVT VT) {
23641
23698
EVT EltVT = VT.getVectorElementType();
23642
23699
return EltVT == MVT::f32 || EltVT == MVT::f64;
23643
23700
};
23644
23701
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
+
23645
23715
if (SDValue Res = combineI8TruncStore(ST, DAG, Subtarget))
23646
23716
return Res;
23647
23717
@@ -23655,8 +23725,8 @@ static SDValue performSTORECombine(SDNode *N,
23655
23725
ValueVT.isFixedLengthVector() &&
23656
23726
ValueVT.getFixedSizeInBits() >= Subtarget->getMinSVEVectorSizeInBits() &&
23657
23727
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());
23660
23730
23661
23731
if (SDValue Split = splitStores(N, DCI, DAG, Subtarget))
23662
23732
return Split;
@@ -26983,6 +27053,11 @@ void AArch64TargetLowering::ReplaceNodeResults(
26983
27053
ReplaceATOMIC_LOAD_128Results(N, Results, DAG, Subtarget);
26984
27054
return;
26985
27055
}
27056
+ case ISD::ADDRSPACECAST: {
27057
+ SDValue V = LowerADDRSPACECAST(SDValue(N, 0), DAG);
27058
+ Results.push_back(V);
27059
+ return;
27060
+ }
26986
27061
case ISD::ATOMIC_LOAD:
26987
27062
case ISD::LOAD: {
26988
27063
MemSDNode *LoadNode = cast<MemSDNode>(N);
0 commit comments