Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,8 @@ class SelectionDAG {
SDValue Mask, SDValue EVL);

/// Returns sum of the base pointer and offset.
/// Unlike getObjectPtrOffset this does not set NoUnsignedWrap by default.
/// Unlike getObjectPtrOffset this does not set NoUnsignedWrap and InBounds by
/// default.
LLVM_ABI SDValue
getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL,
const SDNodeFlags Flags = SDNodeFlags());
Expand All @@ -1123,15 +1124,18 @@ class SelectionDAG {

/// Create an add instruction with appropriate flags when used for
/// addressing some offset of an object. i.e. if a load is split into multiple
/// components, create an add nuw from the base pointer to the offset.
/// components, create an add nuw (or ptradd nuw inbounds) from the base
/// pointer to the offset.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset) {
return getMemBasePlusOffset(Ptr, Offset, SL, SDNodeFlags::NoUnsignedWrap);
return getMemBasePlusOffset(
Ptr, Offset, SL, SDNodeFlags::NoUnsignedWrap | SDNodeFlags::InBounds);
}

SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, SDValue Offset) {
// The object itself can't wrap around the address space, so it shouldn't be
// possible for the adds of the offsets to the split parts to overflow.
return getMemBasePlusOffset(Ptr, Offset, SL, SDNodeFlags::NoUnsignedWrap);
return getMemBasePlusOffset(
Ptr, Offset, SL, SDNodeFlags::NoUnsignedWrap | SDNodeFlags::InBounds);
}

/// Return a new CALLSEQ_START node, that starts new call frame, in which
Expand Down
30 changes: 24 additions & 6 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -5649,17 +5649,35 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
/// Get a pointer to vector element \p Idx located in memory for a vector of
/// type \p VecVT starting at a base address of \p VecPtr. If \p Idx is out of
/// bounds the returned pointer is unspecified, but will be within the vector
/// bounds.
SDValue getVectorElementPointer(SelectionDAG &DAG, SDValue VecPtr, EVT VecVT,
SDValue Index) const;
/// bounds. \p PtrArithFlags can be used to mark that arithmetic within the
/// vector in memory is known to not wrap or to be inbounds.
SDValue getVectorElementPointer(
SelectionDAG &DAG, SDValue VecPtr, EVT VecVT, SDValue Index,
const SDNodeFlags PtrArithFlags = SDNodeFlags()) const;

/// Get a pointer to vector element \p Idx located in memory for a vector of
/// type \p VecVT starting at a base address of \p VecPtr. If \p Idx is out of
/// bounds the returned pointer is unspecified, but will be within the vector
/// bounds. \p VecPtr is guaranteed to point to the beginning of a memory
/// location large enough for the vector.
SDValue getInboundsVectorElementPointer(SelectionDAG &DAG, SDValue VecPtr,
EVT VecVT, SDValue Index) const {
return getVectorElementPointer(DAG, VecPtr, VecVT, Index,
SDNodeFlags::NoUnsignedWrap |
SDNodeFlags::InBounds);
}

/// Get a pointer to a sub-vector of type \p SubVecVT at index \p Idx located
/// in memory for a vector of type \p VecVT starting at a base address of
/// \p VecPtr. If \p Idx plus the size of \p SubVecVT is out of bounds the
/// returned pointer is unspecified, but the value returned will be such that
/// the entire subvector would be within the vector bounds.
SDValue getVectorSubVecPointer(SelectionDAG &DAG, SDValue VecPtr, EVT VecVT,
EVT SubVecVT, SDValue Index) const;
/// the entire subvector would be within the vector bounds. \p PtrArithFlags
/// can be used to mark that arithmetic within the vector in memory is known
/// to not wrap or to be inbounds.
SDValue
getVectorSubVecPointer(SelectionDAG &DAG, SDValue VecPtr, EVT VecVT,
EVT SubVecVT, SDValue Index,
const SDNodeFlags PtrArithFlags = SDNodeFlags()) const;

/// Method for building the DAG expansion of ISD::[US][MIN|MAX]. This
/// method accepts integers as its arguments.
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22760,7 +22760,10 @@ SDValue DAGCombiner::replaceStoreOfInsertLoad(StoreSDNode *ST) {
NewPtr = DAG.getMemBasePlusOffset(Ptr, TypeSize::getFixed(COffset), DL);
PointerInfo = ST->getPointerInfo().getWithOffset(COffset);
} else {
NewPtr = TLI.getVectorElementPointer(DAG, Ptr, Value.getValueType(), Idx);
// The original DAG loaded the entire vector from memory, so arithmetic
// within it must be inbounds.
NewPtr = TLI.getInboundsVectorElementPointer(DAG, Ptr, Value.getValueType(),
Idx);
}

return DAG.getStore(Chain, DL, Elt, NewPtr, PointerInfo, ST->getAlign(),
Expand Down
25 changes: 14 additions & 11 deletions llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10668,19 +10668,20 @@ static SDValue clampDynamicVectorIndex(SelectionDAG &DAG, SDValue Idx,
DAG.getConstant(MaxIndex, dl, IdxVT));
}

SDValue TargetLowering::getVectorElementPointer(SelectionDAG &DAG,
SDValue VecPtr, EVT VecVT,
SDValue Index) const {
SDValue
TargetLowering::getVectorElementPointer(SelectionDAG &DAG, SDValue VecPtr,
EVT VecVT, SDValue Index,
const SDNodeFlags PtrArithFlags) const {
return getVectorSubVecPointer(
DAG, VecPtr, VecVT,
EVT::getVectorVT(*DAG.getContext(), VecVT.getVectorElementType(), 1),
Index);
Index, PtrArithFlags);
}

SDValue TargetLowering::getVectorSubVecPointer(SelectionDAG &DAG,
SDValue VecPtr, EVT VecVT,
EVT SubVecVT,
SDValue Index) const {
SDValue
TargetLowering::getVectorSubVecPointer(SelectionDAG &DAG, SDValue VecPtr,
EVT VecVT, EVT SubVecVT, SDValue Index,
const SDNodeFlags PtrArithFlags) const {
SDLoc dl(Index);
// Make sure the index type is big enough to compute in.
Index = DAG.getZExtOrTrunc(Index, dl, VecPtr.getValueType());
Expand All @@ -10704,7 +10705,7 @@ SDValue TargetLowering::getVectorSubVecPointer(SelectionDAG &DAG,

Index = DAG.getNode(ISD::MUL, dl, IdxVT, Index,
DAG.getConstant(EltSize, dl, IdxVT));
return DAG.getMemBasePlusOffset(VecPtr, Index, dl);
return DAG.getMemBasePlusOffset(VecPtr, Index, dl, PtrArithFlags);
}

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -12382,8 +12383,10 @@ SDValue TargetLowering::scalarizeExtractedVectorLoad(EVT ResultVT,
!IsFast)
return SDValue();

SDValue NewPtr =
getVectorElementPointer(DAG, OriginalLoad->getBasePtr(), InVecVT, EltNo);
// The original DAG loaded the entire vector from memory, so arithmetic
// within it must be inbounds.
SDValue NewPtr = getInboundsVectorElementPointer(
DAG, OriginalLoad->getBasePtr(), InVecVT, EltNo);

// We are replacing a vector load with a scalar load. The new load must have
// identical memory op ordering to the original.
Expand Down