[llvm] 96bd7b6 - [CodeGen] Add additional params to `TargetLoweringBase::getTruncStoreAction` (#187422)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 16:52:51 PDT 2026
Author: Demetrius Kanios
Date: 2026-03-30T16:52:45-07:00
New Revision: 96bd7b6e152387c6d1ccb4b0e392773aa1bdec1e
URL: https://github.com/llvm/llvm-project/commit/96bd7b6e152387c6d1ccb4b0e392773aa1bdec1e
DIFF: https://github.com/llvm/llvm-project/commit/96bd7b6e152387c6d1ccb4b0e392773aa1bdec1e.diff
LOG: [CodeGen] Add additional params to `TargetLoweringBase::getTruncStoreAction` (#187422)
The truncating store analogue of #181104.
Adds `Alignment` and `AddrSpace` parameters to
`TargetLoweringBase::getTruncStoreAction` and dependents, and introduces
a `getCustomTruncStoreAction` hook for targets to customize legalization
behavior using this new information.
This change is fully backwards compatible from the target's point of
view, with `setTruncStoreAction` having identical functionality. The
change is purely additive.
Added:
Modified:
llvm/include/llvm/Analysis/TargetTransformInfo.h
llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
llvm/include/llvm/CodeGen/BasicTTIImpl.h
llvm/include/llvm/CodeGen/TargetLowering.h
llvm/lib/Analysis/TargetTransformInfo.cpp
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
llvm/lib/Target/AMDGPU/R600ISelLowering.h
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/lib/Target/X86/X86TargetTransformInfo.cpp
llvm/lib/Target/X86/X86TargetTransformInfo.h
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 531c5b1179fe4..9059c1ee6f606 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -1392,9 +1392,12 @@ class TargetTransformInfo {
/// \param VF Initial estimation of the minimum vector factor.
/// \param ScalarMemTy Scalar memory type of the store operation.
/// \param ScalarValTy Scalar type of the stored value.
+ /// \param Alignment Alignment of the store
+ /// \param AddrSpace Address space of the store
/// Currently only used by the SLP vectorizer.
LLVM_ABI unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
- Type *ScalarValTy) const;
+ Type *ScalarValTy, Align Alignment,
+ unsigned AddrSpace) const;
/// \return True if it should be considered for address type promotion.
/// \p AllowPromotionWithoutCommonHeader Set true if promoting \p I is
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index 419f2eedd6d8f..f0439b065a8cd 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -668,7 +668,8 @@ class TargetTransformInfoImplBase {
virtual unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const {
return 0;
}
- virtual unsigned getStoreMinimumVF(unsigned VF, Type *, Type *) const {
+ virtual unsigned getStoreMinimumVF(unsigned VF, Type *, Type *, Align,
+ unsigned) const {
return VF;
}
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 7812a301efbd7..ef61ccb87d756 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -44,6 +44,7 @@
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
+#include "llvm/Support/Alignment.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
@@ -480,9 +481,11 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
return getTLI()->getPreferredLargeGEPBaseOffset(MinOffset, MaxOffset);
}
- unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
- Type *ScalarValTy) const override {
- auto &&IsSupportedByTarget = [this, ScalarMemTy, ScalarValTy](unsigned VF) {
+ unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy,
+ Align Alignment,
+ unsigned AddrSpace) const override {
+ auto &&IsSupportedByTarget = [this, ScalarMemTy, ScalarValTy, Alignment,
+ AddrSpace](unsigned VF) {
auto *SrcTy = FixedVectorType::get(ScalarMemTy, VF / 2);
EVT VT = getTLI()->getValueType(DL, SrcTy);
if (getTLI()->isOperationLegal(ISD::STORE, VT) ||
@@ -493,7 +496,8 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
getTLI()->getValueType(DL, FixedVectorType::get(ScalarValTy, VF / 2));
EVT LegalizedVT =
getTLI()->getTypeToTransformTo(ScalarMemTy->getContext(), VT);
- return getTLI()->isTruncStoreLegal(LegalizedVT, ValVT);
+ return getTLI()->isTruncStoreLegal(LegalizedVT, ValVT, Alignment,
+ AddrSpace);
};
while (VF > 2 && IsSupportedByTarget(VF))
VF /= 2;
@@ -1573,7 +1577,8 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
TargetLowering::LegalizeAction LA = TargetLowering::Expand;
EVT MemVT = getTLI()->getValueType(DL, Src);
if (Opcode == Instruction::Store)
- LA = getTLI()->getTruncStoreAction(LT.second, MemVT);
+ LA = getTLI()->getTruncStoreAction(LT.second, MemVT, Alignment,
+ AddressSpace);
else
LA = getTLI()->getLoadAction(LT.second, MemVT, Alignment, AddressSpace,
ISD::EXTLOAD, false);
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index ee6f29b4dce82..8efa574b6d1ef 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -1548,38 +1548,64 @@ class LLVM_ABI TargetLoweringBase {
return Action == Legal || Action == Custom;
}
+ /// Returns an alternative action to use when the coarser lookups (configured
+ /// through `setTruncStoreAction` yield
+ /// `LegalizeAction::Custom`. Allows targets to use builtin behaviors (e.g.
+ /// Legal, Promote) specialized by Alignment and AddrSpace, rather than just
+ /// types.
+ virtual LegalizeAction getCustomTruncStoreAction(EVT ValVT, EVT MemVT,
+ Align Alignment,
+ unsigned AddrSpace) const {
+ return LegalizeAction::Custom;
+ }
+
/// Return how this store with truncation should be treated: either it is
/// legal, needs to be promoted to a larger size, needs to be expanded to some
/// other code sequence, or the target has a custom expander for it.
- LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT) const {
- if (ValVT.isExtended() || MemVT.isExtended()) return Expand;
- unsigned ValI = (unsigned) ValVT.getSimpleVT().SimpleTy;
- unsigned MemI = (unsigned) MemVT.getSimpleVT().SimpleTy;
+ LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT, Align Alignment,
+ unsigned AddrSpace) const {
+ if (ValVT.isExtended() || MemVT.isExtended())
+ return Expand;
+ unsigned ValI = (unsigned)ValVT.getSimpleVT().SimpleTy;
+ unsigned MemI = (unsigned)MemVT.getSimpleVT().SimpleTy;
assert(ValI < MVT::VALUETYPE_SIZE && MemI < MVT::VALUETYPE_SIZE &&
"Table isn't big enough!");
- return TruncStoreActions[ValI][MemI];
+
+ LegalizeAction Action = TruncStoreActions[ValI][MemI];
+
+ if (Action == LegalizeAction::Custom) {
+ return getCustomTruncStoreAction(ValVT, MemVT, Alignment, AddrSpace);
+ }
+
+ return Action;
}
/// Return true if the specified store with truncation is legal on this
/// target.
- bool isTruncStoreLegal(EVT ValVT, EVT MemVT) const {
- return isTypeLegal(ValVT) && getTruncStoreAction(ValVT, MemVT) == Legal;
+ bool isTruncStoreLegal(EVT ValVT, EVT MemVT, Align Alignment,
+ unsigned AddrSpace) const {
+ return isTypeLegal(ValVT) &&
+ getTruncStoreAction(ValVT, MemVT, Alignment, AddrSpace) == Legal;
}
/// Return true if the specified store with truncation has solution on this
/// target.
- bool isTruncStoreLegalOrCustom(EVT ValVT, EVT MemVT) const {
- return isTypeLegal(ValVT) &&
- (getTruncStoreAction(ValVT, MemVT) == Legal ||
- getTruncStoreAction(ValVT, MemVT) == Custom);
+ bool isTruncStoreLegalOrCustom(EVT ValVT, EVT MemVT, Align Alignment,
+ unsigned AddrSpace) const {
+ if (!isTypeLegal(ValVT))
+ return false;
+
+ LegalizeAction Action =
+ getTruncStoreAction(ValVT, MemVT, Alignment, AddrSpace);
+ return (Action == Legal || Action == Custom);
}
- virtual bool canCombineTruncStore(EVT ValVT, EVT MemVT,
- bool LegalOnly) const {
+ virtual bool canCombineTruncStore(EVT ValVT, EVT MemVT, Align Alignment,
+ unsigned AddrSpace, bool LegalOnly) const {
if (LegalOnly)
- return isTruncStoreLegal(ValVT, MemVT);
+ return isTruncStoreLegal(ValVT, MemVT, Alignment, AddrSpace);
- return isTruncStoreLegalOrCustom(ValVT, MemVT);
+ return isTruncStoreLegalOrCustom(ValVT, MemVT, Alignment, AddrSpace);
}
/// Return how the indexed load should be treated: either it is legal, needs
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index 4a1aa4aa91232..85a1e3f8fbbb9 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -860,8 +860,11 @@ unsigned TargetTransformInfo::getMaximumVF(unsigned ElemWidth,
}
unsigned TargetTransformInfo::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
- Type *ScalarValTy) const {
- return TTIImpl->getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy);
+ Type *ScalarValTy,
+ Align Alignment,
+ unsigned AddrSpace) const {
+ return TTIImpl->getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy, Alignment,
+ AddrSpace);
}
bool TargetTransformInfo::shouldConsiderAddressTypePromotion(
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 760d968fe82bd..d0936d5c92fb4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -7164,7 +7164,8 @@ bool DAGCombiner::isLegalNarrowLdSt(LSBaseSDNode *LDST,
return false;
if (LegalOperations &&
- !TLI.isTruncStoreLegal(Store->getValue().getValueType(), MemVT))
+ !TLI.isTruncStoreLegal(Store->getValue().getValueType(), MemVT,
+ Store->getAlign(), Store->getAddressSpace()))
return false;
}
return true;
@@ -13195,7 +13196,8 @@ SDValue DAGCombiner::visitMSTORE(SDNode *N) {
if ((Value.getOpcode() == ISD::TRUNCATE) && Value->hasOneUse() &&
MST->isUnindexed() && !MST->isCompressingStore() &&
TLI.canCombineTruncStore(Value.getOperand(0).getValueType(),
- MST->getMemoryVT(), LegalOperations)) {
+ MST->getMemoryVT(), MST->getAlign(),
+ MST->getAddressSpace(), LegalOperations)) {
auto Mask = TLI.promoteTargetBoolean(DAG, MST->getMask(),
Value.getOperand(0).getValueType());
return DAG.getMaskedStore(Chain, SDLoc(N), Value.getOperand(0), Ptr,
@@ -21779,7 +21781,8 @@ ShrinkLoadReplaceStoreWithStore(const std::pair<unsigned, unsigned> &MaskInfo,
if (DC->isTypeLegal(VT))
UseTruncStore = false;
else if (TLI.isTypeLegal(IVal.getValueType()) &&
- TLI.isTruncStoreLegal(IVal.getValueType(), VT))
+ TLI.isTruncStoreLegal(IVal.getValueType(), VT, St->getAlign(),
+ St->getAddressSpace()))
UseTruncStore = true;
else
return SDValue();
@@ -22724,7 +22727,8 @@ bool DAGCombiner::tryStoreMergeOfConstants(
TargetLowering::TypePromoteInteger) {
EVT LegalizedStoredValTy =
TLI.getTypeToTransformTo(Context, StoredVal.getValueType());
- if (TLI.isTruncStoreLegal(LegalizedStoredValTy, StoreTy) &&
+ if (TLI.isTruncStoreLegal(LegalizedStoredValTy, StoreTy,
+ FirstStoreAlign, FirstStoreAS) &&
TLI.canMergeStoresTo(FirstStoreAS, LegalizedStoredValTy,
DAG.getMachineFunction()) &&
TLI.allowsMemoryAccess(Context, DL, StoreTy,
@@ -23002,7 +23006,8 @@ bool DAGCombiner::tryStoreMergeOfLoads(SmallVectorImpl<MemOpLink> &StoreNodes,
} else if (TLI.getTypeAction(Context, StoreTy) ==
TargetLowering::TypePromoteInteger) {
EVT LegalizedStoredValTy = TLI.getTypeToTransformTo(Context, StoreTy);
- if (TLI.isTruncStoreLegal(LegalizedStoredValTy, StoreTy) &&
+ if (TLI.isTruncStoreLegal(LegalizedStoredValTy, StoreTy,
+ FirstStoreAlign, FirstStoreAS) &&
TLI.canMergeStoresTo(FirstStoreAS, LegalizedStoredValTy,
DAG.getMachineFunction()) &&
TLI.isLoadLegal(LegalizedStoredValTy, StoreTy,
@@ -23696,9 +23701,10 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
Value.getOpcode() == ISD::TRUNCATE) &&
Value->hasOneUse() && ST->isUnindexed() &&
TLI.canCombineTruncStore(Value.getOperand(0).getValueType(),
- ST->getMemoryVT(), LegalOperations)) {
- return DAG.getTruncStore(Chain, SDLoc(N), Value.getOperand(0),
- Ptr, ST->getMemoryVT(), ST->getMemOperand());
+ ST->getMemoryVT(), ST->getAlign(),
+ ST->getAddressSpace(), LegalOperations)) {
+ return DAG.getTruncStore(Chain, SDLoc(N), Value.getOperand(0), Ptr,
+ ST->getMemoryVT(), ST->getMemOperand());
}
// Always perform this optimization before types are legal. If the target
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index a4e4a5ee640f6..c9de7faf4f2ee 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -623,8 +623,10 @@ void SelectionDAGLegalize::LegalizeStoreOps(SDNode *Node) {
SDValue Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
ReplaceNode(SDValue(Node, 0), Result);
} else {
- switch (TLI.getTruncStoreAction(ST->getValue().getValueType(), StVT)) {
- default: llvm_unreachable("This action is not supported yet!");
+ switch (TLI.getTruncStoreAction(ST->getValue().getValueType(), StVT,
+ ST->getAlign(), ST->getAddressSpace())) {
+ default:
+ llvm_unreachable("This action is not supported yet!");
case TargetLowering::Legal: {
EVT MemVT = ST->getMemoryVT();
// If this is an unaligned store and the target doesn't support it,
@@ -1863,8 +1865,9 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, EVT SlotVT,
Align DestAlign = DAG.getDataLayout().getPrefTypeAlign(DestType);
// Don't convert with stack if the load/store is expensive.
- if ((SrcVT.bitsGT(SlotVT) &&
- !TLI.isTruncStoreLegalOrCustom(SrcOp.getValueType(), SlotVT)) ||
+ if ((SrcVT.bitsGT(SlotVT) && !TLI.isTruncStoreLegalOrCustom(
+ SrcOp.getValueType(), SlotVT, DestAlign,
+ DAG.getDataLayout().getAllocaAddrSpace())) ||
(SlotVT.bitsLT(DestVT) &&
!TLI.isLoadLegalOrCustom(DestVT, SlotVT, DestAlign,
DAG.getDataLayout().getAllocaAddrSpace(),
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index 2409a1f31e26e..d648600d7cf9e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
@@ -307,7 +307,8 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
EVT StVT = ST->getMemoryVT();
MVT ValVT = ST->getValue().getSimpleValueType();
if (StVT.isVector() && ST->isTruncatingStore())
- Action = TLI.getTruncStoreAction(ValVT, StVT);
+ Action = TLI.getTruncStoreAction(ValVT, StVT, ST->getAlign(),
+ ST->getAddressSpace());
break;
}
case ISD::MERGE_VALUES:
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
index c7716020da13c..cde391bdcaea8 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
@@ -537,13 +537,15 @@ class AArch64TTIImpl final : public BasicTTIImplBase<AArch64TTIImpl> {
bool shouldTreatInstructionLikeSelect(const Instruction *I) const override;
- unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
- Type *ScalarValTy) const override {
+ unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy,
+ Align Alignment,
+ unsigned AddrSpace) const override {
// We can vectorize store v4i8.
if (ScalarMemTy->isIntegerTy(8) && isPowerOf2_32(VF) && VF >= 4)
return 4;
- return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy);
+ return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy, Alignment,
+ AddrSpace);
}
std::optional<unsigned> getMinPageSize() const override { return 4096; }
diff --git a/llvm/lib/Target/AMDGPU/R600ISelLowering.h b/llvm/lib/Target/AMDGPU/R600ISelLowering.h
index 9559cf883dd10..e70b78de6bf15 100644
--- a/llvm/lib/Target/AMDGPU/R600ISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/R600ISelLowering.h
@@ -54,13 +54,14 @@ class R600TargetLowering final : public AMDGPUTargetLowering {
MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
unsigned *IsFast = nullptr) const override;
- bool canCombineTruncStore(EVT ValVT, EVT MemVT,
+ bool canCombineTruncStore(EVT ValVT, EVT MemVT, Align Alignment,
+ unsigned AddrSpace,
bool LegalOperations) const override {
// R600 has "custom" lowering for truncating stores despite not supporting
// those instructions. If we allow that custom lowering in the DAG combiner
// then all truncates are merged into truncating stores, giving worse code
// generation. This hook prevents the DAG combiner performing that combine.
- return isTruncStoreLegal(ValVT, MemVT);
+ return isTruncStoreLegal(ValVT, MemVT, Alignment, AddrSpace);
}
private:
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 902a2deab46e3..32796c3e56781 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -54220,7 +54220,8 @@ static SDValue combineMaskedStore(SDNode *N, SelectionDAG &DAG,
}
if (Value.getOpcode() == ISD::TRUNCATE && Value.getNode()->hasOneUse() &&
- TLI.isTruncStoreLegal(Value.getOperand(0).getValueType(), MemVT)) {
+ TLI.isTruncStoreLegal(Value.getOperand(0).getValueType(), MemVT,
+ Mst->getAlign(), Mst->getAddressSpace())) {
return DAG.getMaskedStore(Mst->getChain(), DL, Value.getOperand(0),
Mst->getBasePtr(), Mst->getOffset(), Mask, MemVT,
Mst->getMemOperand(), Mst->getAddressingMode(),
@@ -54363,7 +54364,8 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
(SrcVT == MVT::v2i32 && VT == MVT::v2i16) ||
(SrcVT == MVT::v2i16 && VT == MVT::v2i8)) {
MVT ExtVT = SrcVT == MVT::v4i16 ? MVT::v4i32 : MVT::v2i64;
- if (TLI.isTruncStoreLegal(ExtVT, VT)) {
+ if (TLI.isTruncStoreLegal(ExtVT, VT, St->getAlign(),
+ St->getAddressSpace())) {
SDValue Ext = DAG.getNode(ISD::ANY_EXTEND, dl, ExtVT, Src);
return DAG.getTruncStore(St->getChain(), dl, Ext, St->getBasePtr(),
VT, St->getMemOperand());
@@ -54505,7 +54507,8 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
if (!St->isTruncatingStore() && VT == MVT::v16i8 && !Subtarget.hasBWI() &&
St->getValue().getOpcode() == ISD::TRUNCATE &&
St->getValue().getOperand(0).getValueType() == MVT::v16i16 &&
- TLI.isTruncStoreLegal(MVT::v16i32, MVT::v16i8) &&
+ TLI.isTruncStoreLegal(MVT::v16i32, MVT::v16i8, St->getAlign(),
+ St->getAddressSpace()) &&
St->getValue().hasOneUse() && !DCI.isBeforeLegalizeOps()) {
SDValue Ext = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::v16i32,
St->getValue().getOperand(0));
@@ -54518,11 +54521,12 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
(StoredVal.getOpcode() == X86ISD::VTRUNCUS ||
StoredVal.getOpcode() == X86ISD::VTRUNCS) &&
StoredVal.hasOneUse() &&
- TLI.isTruncStoreLegal(StoredVal.getOperand(0).getValueType(), VT)) {
+ TLI.isTruncStoreLegal(StoredVal.getOperand(0).getValueType(), VT,
+ St->getAlign(), St->getAddressSpace())) {
bool IsSigned = StoredVal.getOpcode() == X86ISD::VTRUNCS;
- return EmitTruncSStore(IsSigned, St->getChain(),
- dl, StoredVal.getOperand(0), St->getBasePtr(),
- VT, St->getMemOperand(), DAG);
+ return EmitTruncSStore(IsSigned, St->getChain(), dl,
+ StoredVal.getOperand(0), St->getBasePtr(), VT,
+ St->getMemOperand(), DAG);
}
// Try to fold a extract_element(VTRUNC) pattern into a truncating store.
@@ -54547,7 +54551,8 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
unsigned NumTruncBits = DstVT.getScalarSizeInBits() * NumSrcElts;
MVT TruncVT = MVT::getVectorVT(DstVT.getScalarType(), NumSrcElts);
if (NumTruncBits == VT.getSizeInBits() &&
- TLI.isTruncStoreLegal(SrcVT, TruncVT)) {
+ TLI.isTruncStoreLegal(SrcVT, TruncVT, St->getAlign(),
+ St->getAddressSpace())) {
return DAG.getTruncStore(St->getChain(), dl, Src, St->getBasePtr(),
TruncVT, St->getMemOperand());
}
@@ -54559,7 +54564,8 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
// First, pack all of the elements in one place. Next, store to memory
// in fewer chunks.
if (St->isTruncatingStore() && VT.isVector()) {
- if (TLI.isTruncStoreLegal(VT, StVT)) {
+ if (TLI.isTruncStoreLegal(VT, StVT, St->getAlign(),
+ St->getAddressSpace())) {
if (SDValue Val = detectSSatPattern(St->getValue(), St->getMemoryVT()))
return EmitTruncSStore(true /* Signed saturation */, St->getChain(),
dl, Val, St->getBasePtr(),
diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp
index f4889d7e48890..1bc0ff397e476 100644
--- a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp
+++ b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp
@@ -7226,11 +7226,13 @@ bool X86TTIImpl::isVectorShiftByScalarCheap(Type *Ty) const {
}
unsigned X86TTIImpl::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
- Type *ScalarValTy) const {
+ Type *ScalarValTy, Align Alignment,
+ unsigned AddrSpace) const {
if (ST->hasF16C() && ScalarMemTy->isHalfTy()) {
return 4;
}
- return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy);
+ return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy, Alignment,
+ AddrSpace);
}
bool X86TTIImpl::isProfitableToSinkOperands(Instruction *I,
diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.h b/llvm/lib/Target/X86/X86TargetTransformInfo.h
index b3dde1555d0a0..dbab8edfc6a2c 100644
--- a/llvm/lib/Target/X86/X86TargetTransformInfo.h
+++ b/llvm/lib/Target/X86/X86TargetTransformInfo.h
@@ -322,8 +322,9 @@ class X86TTIImpl final : public BasicTTIImplBase<X86TTIImpl> {
bool isVectorShiftByScalarCheap(Type *Ty) const override;
- unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
- Type *ScalarValTy) const override;
+ unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy,
+ Align Alignment,
+ unsigned AddrSpace) const override;
bool useFastCCForInternalCall(Function &F) const override;
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 3eadbf9289c23..e48b68fafd806 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -25543,7 +25543,8 @@ bool StoreChainContext::initializeContext(BoUpSLP &R, const DataLayout &DL,
Type *StoreScalarTy = StoreTy->getScalarType();
MinVF = PowerOf2Ceil(TTI.getStoreMinimumVF(
R.getMinVF(DL.getTypeStoreSizeInBits(StoreScalarTy)), StoreScalarTy,
- ValueTy->getScalarType()));
+ ValueTy->getScalarType(), Store->getAlign(),
+ Store->getPointerAddressSpace()));
MinVF /= getNumElements(StoreTy);
MinVF = std::max<unsigned>(2, MinVF);
More information about the llvm-commits
mailing list