@@ -531,6 +531,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
531
531
setOperationAction(ISD::XOR, MVT::i32, Custom);
532
532
setOperationAction(ISD::XOR, MVT::i64, Custom);
533
533
534
+ setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
535
+ setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
536
+
534
537
// Virtually no operation on f128 is legal, but LLVM can't expand them when
535
538
// there's a valid register class, so we need custom operations in most cases.
536
539
setOperationAction(ISD::FABS, MVT::f128, Expand);
@@ -6651,6 +6654,37 @@ static SDValue LowerTruncateVectorStore(SDLoc DL, StoreSDNode *ST,
6651
6654
ST->getBasePtr(), ST->getMemOperand());
6652
6655
}
6653
6656
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
+
6654
6688
// Custom lowering for any store, vector or scalar and/or default or with
6655
6689
// a truncate operations. Currently only custom lower truncate operation
6656
6690
// from vector v4i16 to v4i8 or volatile stores of i128.
@@ -7304,6 +7338,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
7304
7338
case ISD::SIGN_EXTEND:
7305
7339
case ISD::ZERO_EXTEND:
7306
7340
return LowerFixedLengthVectorIntExtendToSVE(Op, DAG);
7341
+ case ISD::ADDRSPACECAST:
7342
+ return LowerADDRSPACECAST(Op, DAG);
7307
7343
case ISD::SIGN_EXTEND_INREG: {
7308
7344
// Only custom lower when ExtraVT has a legal byte based element type.
7309
7345
EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
@@ -23215,6 +23251,26 @@ static SDValue performLOADCombine(SDNode *N,
23215
23251
performTBISimplification(N->getOperand(1), DCI, DAG);
23216
23252
23217
23253
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
+
23218
23274
if (LD->isVolatile() || !Subtarget->isLittleEndian())
23219
23275
return SDValue(N, 0);
23220
23276
@@ -23224,13 +23280,11 @@ static SDValue performLOADCombine(SDNode *N,
23224
23280
if (!LD->isNonTemporal())
23225
23281
return SDValue(N, 0);
23226
23282
23227
- EVT MemVT = LD->getMemoryVT();
23228
23283
if (MemVT.isScalableVector() || MemVT.getSizeInBits() <= 256 ||
23229
23284
MemVT.getSizeInBits() % 256 == 0 ||
23230
23285
256 % MemVT.getScalarSizeInBits() != 0)
23231
23286
return SDValue(N, 0);
23232
23287
23233
- SDLoc DL(LD);
23234
23288
SDValue Chain = LD->getChain();
23235
23289
SDValue BasePtr = LD->getBasePtr();
23236
23290
SDNodeFlags Flags = LD->getFlags();
@@ -23490,12 +23544,28 @@ static SDValue performSTORECombine(SDNode *N,
23490
23544
SDValue Value = ST->getValue();
23491
23545
SDValue Ptr = ST->getBasePtr();
23492
23546
EVT ValueVT = Value.getValueType();
23547
+ EVT MemVT = ST->getMemoryVT();
23548
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
23549
+ SDLoc DL(ST);
23493
23550
23494
23551
auto hasValidElementTypeForFPTruncStore = [](EVT VT) {
23495
23552
EVT EltVT = VT.getVectorElementType();
23496
23553
return EltVT == MVT::f32 || EltVT == MVT::f64;
23497
23554
};
23498
23555
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
+
23499
23569
if (SDValue Res = combineI8TruncStore(ST, DAG, Subtarget))
23500
23570
return Res;
23501
23571
@@ -23509,8 +23579,8 @@ static SDValue performSTORECombine(SDNode *N,
23509
23579
ValueVT.isFixedLengthVector() &&
23510
23580
ValueVT.getFixedSizeInBits() >= Subtarget->getMinSVEVectorSizeInBits() &&
23511
23581
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());
23514
23584
23515
23585
if (SDValue Split = splitStores(N, DCI, DAG, Subtarget))
23516
23586
return Split;
@@ -26832,6 +26902,11 @@ void AArch64TargetLowering::ReplaceNodeResults(
26832
26902
ReplaceATOMIC_LOAD_128Results(N, Results, DAG, Subtarget);
26833
26903
return;
26834
26904
}
26905
+ case ISD::ADDRSPACECAST: {
26906
+ SDValue V = LowerADDRSPACECAST(SDValue(N, 0), DAG);
26907
+ Results.push_back(V);
26908
+ return;
26909
+ }
26835
26910
case ISD::ATOMIC_LOAD:
26836
26911
case ISD::LOAD: {
26837
26912
MemSDNode *LoadNode = cast<MemSDNode>(N);
0 commit comments