[llvm] [AArch64][NFC] Extract a `LowerNTStore()` method (PR #176872)
Tomer Shafir via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 19 23:55:11 PST 2026
https://github.com/tomershafir created https://github.com/llvm/llvm-project/pull/176872
Extracts nontermporal store lowering from `LowerSTORE` into its own private method `LowerNTStore`. The refactoring improves overall code structure (and prepares for later scaling of custom STNP lowering logic).
>From cfff768a25b6873394ac5094f808391859cabdba Mon Sep 17 00:00:00 2001
From: tomershafir <tomer.shafir8 at gmail.com>
Date: Sun, 18 Jan 2026 15:06:59 +0200
Subject: [PATCH] [AArch64][NFC] Extract a `LowerNTStore()` method
Extracts nontermporal store lowering from `LowerSTORE` into its own private method `LowerNTStore`. The refactoring improves overall code structure (and prepares for later scaling of custom STNP lowering logic).
---
.../Target/AArch64/AArch64ISelLowering.cpp | 76 ++++++++++++-------
llvm/lib/Target/AArch64/AArch64ISelLowering.h | 2 +
2 files changed, 49 insertions(+), 29 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index c81f457898d7c..73b5474152592 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -7335,6 +7335,13 @@ SDValue AArch64TargetLowering::LowerSTORE(SDValue Op,
EVT VT = Value.getValueType();
EVT MemVT = StoreNode->getMemoryVT();
+ // Currently, STNP lowering can only either keep or increase code size, thus
+ // we predicate it to not apply when optimizing for code size.
+ if (StoreNode->isNonTemporal() && !DAG.shouldOptForSize()) {
+ if (auto MaybeSTNP = LowerNTStore(StoreNode, VT, MemVT, Dl, DAG))
+ return MaybeSTNP;
+ }
+
if (VT.isVector()) {
if (useSVEForFixedLengthVectorVT(
VT,
@@ -7354,55 +7361,66 @@ SDValue AArch64TargetLowering::LowerSTORE(SDValue Op,
MemVT == MVT::v4i8) {
return LowerTruncateVectorStore(Dl, StoreNode, VT, MemVT, DAG);
}
+ } else if (MemVT == MVT::i128 && StoreNode->isVolatile()) {
+ return LowerStore128(Op, DAG);
+ } else if (MemVT == MVT::i64x8) {
+ SDValue Value = StoreNode->getValue();
+ assert(Value->getValueType(0) == MVT::i64x8);
+ SDValue Chain = StoreNode->getChain();
+ SDValue Base = StoreNode->getBasePtr();
+ EVT PtrVT = Base.getValueType();
+ for (unsigned i = 0; i < 8; i++) {
+ SDValue Part = DAG.getNode(AArch64ISD::LS64_EXTRACT, Dl, MVT::i64,
+ Value, DAG.getConstant(i, Dl, MVT::i32));
+ SDValue Ptr = DAG.getNode(ISD::ADD, Dl, PtrVT, Base,
+ DAG.getConstant(i * 8, Dl, PtrVT));
+ Chain = DAG.getStore(Chain, Dl, Part, Ptr, StoreNode->getPointerInfo(),
+ StoreNode->getBaseAlign());
+ }
+ return Chain;
+ }
+
+ return SDValue();
+}
+
+// Lower non-temporal stores that would otherwise be broken by legalization.
+SDValue AArch64TargetLowering::LowerNTStore(StoreSDNode *StoreNode, EVT VT,
+ EVT MemVT, const SDLoc &DL,
+ SelectionDAG &DAG) const {
+ assert(StoreNode && "Expected a store operation");
+ assert(StoreNode->isNonTemporal() && "Expected a non-temporal store");
+
+ // Currently we only support NT stores lowering for little-endian targets.
+ if (!Subtarget->isLittleEndian())
+ return SDValue();
+
+ if (VT.isVector()) {
// 256 bit non-temporal stores can be lowered to STNP. Do this as part of
// the custom lowering, as there are no un-paired non-temporal stores and
// legalization will break up 256 bit inputs.
- //
- // Currently, STNP lowering can only either keep or increase code size, thus
- // we predicate it to not apply when optimizing for code size.
ElementCount EC = MemVT.getVectorElementCount();
- if (StoreNode->isNonTemporal() && MemVT.getSizeInBits() == 256u &&
- EC.isKnownEven() && DAG.getDataLayout().isLittleEndian() &&
- !DAG.shouldOptForSize() &&
+ if (VT.isVector() && MemVT.getSizeInBits() == 256u && EC.isKnownEven() &&
(MemVT.getScalarSizeInBits() == 8u ||
MemVT.getScalarSizeInBits() == 16u ||
MemVT.getScalarSizeInBits() == 32u ||
MemVT.getScalarSizeInBits() == 64u)) {
SDValue Lo =
- DAG.getNode(ISD::EXTRACT_SUBVECTOR, Dl,
+ DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL,
MemVT.getHalfNumVectorElementsVT(*DAG.getContext()),
- StoreNode->getValue(), DAG.getConstant(0, Dl, MVT::i64));
+ StoreNode->getValue(), DAG.getConstant(0, DL, MVT::i64));
SDValue Hi =
- DAG.getNode(ISD::EXTRACT_SUBVECTOR, Dl,
+ DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL,
MemVT.getHalfNumVectorElementsVT(*DAG.getContext()),
StoreNode->getValue(),
- DAG.getConstant(EC.getKnownMinValue() / 2, Dl, MVT::i64));
+ DAG.getConstant(EC.getKnownMinValue() / 2, DL, MVT::i64));
SDValue Result = DAG.getMemIntrinsicNode(
- AArch64ISD::STNP, Dl, DAG.getVTList(MVT::Other),
+ AArch64ISD::STNP, DL, DAG.getVTList(MVT::Other),
{StoreNode->getChain(), DAG.getBitcast(MVT::v2i64, Lo),
DAG.getBitcast(MVT::v2i64, Hi), StoreNode->getBasePtr()},
StoreNode->getMemoryVT(), StoreNode->getMemOperand());
return Result;
}
- } else if (MemVT == MVT::i128 && StoreNode->isVolatile()) {
- return LowerStore128(Op, DAG);
- } else if (MemVT == MVT::i64x8) {
- SDValue Value = StoreNode->getValue();
- assert(Value->getValueType(0) == MVT::i64x8);
- SDValue Chain = StoreNode->getChain();
- SDValue Base = StoreNode->getBasePtr();
- EVT PtrVT = Base.getValueType();
- for (unsigned i = 0; i < 8; i++) {
- SDValue Part = DAG.getNode(AArch64ISD::LS64_EXTRACT, Dl, MVT::i64,
- Value, DAG.getConstant(i, Dl, MVT::i32));
- SDValue Ptr = DAG.getNode(ISD::ADD, Dl, PtrVT, Base,
- DAG.getConstant(i * 8, Dl, PtrVT));
- Chain = DAG.getStore(Chain, Dl, Part, Ptr, StoreNode->getPointerInfo(),
- StoreNode->getBaseAlign());
- }
- return Chain;
}
-
return SDValue();
}
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 8dacd08ddf8a7..dec34b2923fcf 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -614,6 +614,8 @@ class AArch64TargetLowering : public TargetLowering {
SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerNTStore(StoreSDNode *, EVT VT, EVT MemVT, const SDLoc &DL,
+ SelectionDAG &DAG) const;
SDValue LowerStore128(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerABS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFMUL(SDValue Op, SelectionDAG &DAG) const;
More information about the llvm-commits
mailing list