Skip to content

Commit a8f0109

Browse files
committed
[SDAG] Introduce inbounds flag for ISD::PTRADD
This patch introduces SDNodeFlags::InBounds, to show that an ISD::PTRADD SDNode implements an inbounds getelementptr operation (i.e., the pointer operand is in bounds wrt. an allocated object it is based on, and the arithmetic does not change that). The flag is set in the DAG construction when lowering inbounds GEPs. Inbounds information is useful in the ISel when selecting memory instructions that perform address computations whose intermediate steps must be in the same memory region as the final result. Follow-up patches to propagate the flag in DAGCombines and to use it when lowering AMDGPU's flat memory instructions, where the immediate offset must not affect the memory aperture of the address (similar to this GISel patch: #153001), are planned. This mirrors #150900, which has introduced a similar flag in GlobalISel. This patch supersedes #131862, which previously attempted to introduce an SDNodeFlags::InBounds flag. The difference between this PR and #131862 is that there is now an ISD::PTRADD opcode (PR #140017) and the InBounds flag is only defined to apply to ISD::PTRADD DAG nodes. It is therefore unambiguous that in-bounds-ness refers to a memory object into which the left operand of the PTRADD node points (in contrast to #131862, where InBounds would have applied to commutative ISD::ADD nodes, so that the semantics would be more difficult to reason about). For SWDEV-516125.
1 parent a1f9ad2 commit a8f0109

File tree

4 files changed

+18
-3
lines changed

4 files changed

+18
-3
lines changed

llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,12 +418,16 @@ struct SDNodeFlags {
418418
Unpredictable = 1 << 13,
419419
// Compare instructions which may carry the samesign flag.
420420
SameSign = 1 << 14,
421+
// ISD::PTRADD operations that remain in bounds, i.e., the left operand is
422+
// an address in a memory object in which the result of the operation also
423+
// lies.
424+
InBounds = 1 << 15,
421425

422426
// NOTE: Please update LargestValue in LLVM_DECLARE_ENUM_AS_BITMASK below
423427
// the class definition when adding new flags.
424428

425429
PoisonGeneratingFlags = NoUnsignedWrap | NoSignedWrap | Exact | Disjoint |
426-
NonNeg | NoNaNs | NoInfs | SameSign,
430+
NonNeg | NoNaNs | NoInfs | SameSign | InBounds,
427431
FastMathFlags = NoNaNs | NoInfs | NoSignedZeros | AllowReciprocal |
428432
AllowContract | ApproximateFuncs | AllowReassociation,
429433
};
@@ -458,6 +462,7 @@ struct SDNodeFlags {
458462
void setAllowReassociation(bool b) { setFlag<AllowReassociation>(b); }
459463
void setNoFPExcept(bool b) { setFlag<NoFPExcept>(b); }
460464
void setUnpredictable(bool b) { setFlag<Unpredictable>(b); }
465+
void setInBounds(bool b) { setFlag<InBounds>(b); }
461466

462467
// These are accessors for each flag.
463468
bool hasNoUnsignedWrap() const { return Flags & NoUnsignedWrap; }
@@ -475,6 +480,7 @@ struct SDNodeFlags {
475480
bool hasAllowReassociation() const { return Flags & AllowReassociation; }
476481
bool hasNoFPExcept() const { return Flags & NoFPExcept; }
477482
bool hasUnpredictable() const { return Flags & Unpredictable; }
483+
bool hasInBounds() const { return Flags & InBounds; }
478484

479485
bool operator==(const SDNodeFlags &Other) const {
480486
return Flags == Other.Flags;
@@ -484,7 +490,7 @@ struct SDNodeFlags {
484490
};
485491

486492
LLVM_DECLARE_ENUM_AS_BITMASK(decltype(SDNodeFlags::None),
487-
SDNodeFlags::SameSign);
493+
SDNodeFlags::InBounds);
488494

489495
inline SDNodeFlags operator|(SDNodeFlags LHS, SDNodeFlags RHS) {
490496
LHS |= RHS;

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8615,7 +8615,10 @@ SDValue SelectionDAG::getMemBasePlusOffset(SDValue Ptr, SDValue Offset,
86158615
if (TLI->shouldPreservePtrArith(this->getMachineFunction().getFunction(),
86168616
BasePtrVT))
86178617
return getNode(ISD::PTRADD, DL, BasePtrVT, Ptr, Offset, Flags);
8618-
return getNode(ISD::ADD, DL, BasePtrVT, Ptr, Offset, Flags);
8618+
// InBounds only applies to PTRADD, don't set it if we generate ADD.
8619+
SDNodeFlags AddFlags = Flags;
8620+
AddFlags.setInBounds(false);
8621+
return getNode(ISD::ADD, DL, BasePtrVT, Ptr, Offset, AddFlags);
86198622
}
86208623

86218624
/// Returns true if memcpy source is constant data.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4375,6 +4375,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
43754375
if (NW.hasNoUnsignedWrap() ||
43764376
(int64_t(Offset) >= 0 && NW.hasNoUnsignedSignedWrap()))
43774377
Flags |= SDNodeFlags::NoUnsignedWrap;
4378+
Flags.setInBounds(NW.isInBounds());
43784379

43794380
N = DAG.getMemBasePlusOffset(
43804381
N, DAG.getConstant(Offset, dl, N.getValueType()), dl, Flags);
@@ -4418,6 +4419,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
44184419
if (NW.hasNoUnsignedWrap() ||
44194420
(Offs.isNonNegative() && NW.hasNoUnsignedSignedWrap()))
44204421
Flags.setNoUnsignedWrap(true);
4422+
Flags.setInBounds(NW.isInBounds());
44214423

44224424
OffsVal = DAG.getSExtOrTrunc(OffsVal, dl, N.getValueType());
44234425

@@ -4487,6 +4489,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
44874489
// pointer index type (add nuw).
44884490
SDNodeFlags AddFlags;
44894491
AddFlags.setNoUnsignedWrap(NW.hasNoUnsignedWrap());
4492+
AddFlags.setInBounds(NW.isInBounds());
44904493

44914494
N = DAG.getMemBasePlusOffset(N, IdxN, dl, AddFlags);
44924495
}

llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,9 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
688688
if (getFlags().hasSameSign())
689689
OS << " samesign";
690690

691+
if (getFlags().hasInBounds())
692+
OS << " inbounds";
693+
691694
if (getFlags().hasNonNeg())
692695
OS << " nneg";
693696

0 commit comments

Comments
 (0)