Skip to content

Commit 75e41ae

Browse files
committed
[SDAG] Introduce inbounds flag for pointer arithmetic
This patch introduces an inbounds SDNodeFlag, to show that a pointer addition SDNode implements an inbounds getelementptr operation (i.e., the pointer operand is in bounds wrt. the 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. A follow-up patch will start using it for AMDGPU's flat memory instructions, where the immediate offset must not affect the memory aperture of the address. A similar patch for gMIR and GlobalISel will follow. For SWDEV-516125.
1 parent 0cdb310 commit 75e41ae

File tree

4 files changed

+14
-3
lines changed

4 files changed

+14
-3
lines changed

Diff for: llvm/include/llvm/CodeGen/SelectionDAGNodes.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -415,12 +415,15 @@ struct SDNodeFlags {
415415
Unpredictable = 1 << 13,
416416
// Compare instructions which may carry the samesign flag.
417417
SameSign = 1 << 14,
418+
// Pointer arithmetic instructions that remain in bounds, e.g., implementing
419+
// an inbounds GEP.
420+
InBounds = 1 << 15,
418421

419422
// NOTE: Please update LargestValue in LLVM_DECLARE_ENUM_AS_BITMASK below
420423
// the class definition when adding new flags.
421424

422425
PoisonGeneratingFlags = NoUnsignedWrap | NoSignedWrap | Exact | Disjoint |
423-
NonNeg | NoNaNs | NoInfs | SameSign,
426+
NonNeg | NoNaNs | NoInfs | SameSign | InBounds,
424427
FastMathFlags = NoNaNs | NoInfs | NoSignedZeros | AllowReciprocal |
425428
AllowContract | ApproximateFuncs | AllowReassociation,
426429
};
@@ -455,6 +458,7 @@ struct SDNodeFlags {
455458
void setAllowReassociation(bool b) { setFlag<AllowReassociation>(b); }
456459
void setNoFPExcept(bool b) { setFlag<NoFPExcept>(b); }
457460
void setUnpredictable(bool b) { setFlag<Unpredictable>(b); }
461+
void setInBounds(bool b) { setFlag<InBounds>(b); }
458462

459463
// These are accessors for each flag.
460464
bool hasNoUnsignedWrap() const { return Flags & NoUnsignedWrap; }
@@ -472,6 +476,7 @@ struct SDNodeFlags {
472476
bool hasAllowReassociation() const { return Flags & AllowReassociation; }
473477
bool hasNoFPExcept() const { return Flags & NoFPExcept; }
474478
bool hasUnpredictable() const { return Flags & Unpredictable; }
479+
bool hasInBounds() const { return Flags & InBounds; }
475480

476481
bool operator==(const SDNodeFlags &Other) const {
477482
return Flags == Other.Flags;
@@ -481,7 +486,7 @@ struct SDNodeFlags {
481486
};
482487

483488
LLVM_DECLARE_ENUM_AS_BITMASK(decltype(SDNodeFlags::None),
484-
SDNodeFlags::SameSign);
489+
SDNodeFlags::InBounds);
485490

486491
inline SDNodeFlags operator|(SDNodeFlags LHS, SDNodeFlags RHS) {
487492
LHS |= RHS;

Diff for: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -4283,6 +4283,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
42834283
if (NW.hasNoUnsignedWrap() ||
42844284
(int64_t(Offset) >= 0 && NW.hasNoUnsignedSignedWrap()))
42854285
Flags |= SDNodeFlags::NoUnsignedWrap;
4286+
Flags.setInBounds(NW.isInBounds());
42864287

42874288
N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N,
42884289
DAG.getConstant(Offset, dl, N.getValueType()), Flags);
@@ -4326,6 +4327,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
43264327
if (NW.hasNoUnsignedWrap() ||
43274328
(Offs.isNonNegative() && NW.hasNoUnsignedSignedWrap()))
43284329
Flags.setNoUnsignedWrap(true);
4330+
Flags.setInBounds(NW.isInBounds());
43294331

43304332
OffsVal = DAG.getSExtOrTrunc(OffsVal, dl, N.getValueType());
43314333

@@ -4388,6 +4390,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
43884390
// pointer index type (add nuw).
43894391
SDNodeFlags AddFlags;
43904392
AddFlags.setNoUnsignedWrap(NW.hasNoUnsignedWrap());
4393+
AddFlags.setInBounds(NW.isInBounds());
43914394

43924395
N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N, IdxN, AddFlags);
43934396
}

Diff for: llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,9 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
663663
if (getFlags().hasSameSign())
664664
OS << " samesign";
665665

666+
if (getFlags().hasInBounds())
667+
OS << " inbounds";
668+
666669
if (getFlags().hasNonNeg())
667670
OS << " nneg";
668671

Diff for: llvm/test/CodeGen/X86/merge-store-partially-alias-loads.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
; DBGDAG-LABEL: Optimized legalized selection DAG: %bb.0 'merge_store_partial_overlap_load:'
1717
; DBGDAG: [[ENTRYTOKEN:t[0-9]+]]: ch,glue = EntryToken
1818
; DBGDAG-DAG: [[BASEPTR:t[0-9]+]]: i64,ch = CopyFromReg [[ENTRYTOKEN]],
19-
; DBGDAG-DAG: [[ADDPTR:t[0-9]+]]: i64 = add {{(nuw )?}}[[BASEPTR]], Constant:i64<2>
19+
; DBGDAG-DAG: [[ADDPTR:t[0-9]+]]: i64 = add {{(nuw )?}}{{(inbounds )?}}[[BASEPTR]], Constant:i64<2>
2020

2121
; DBGDAG-DAG: [[LD2:t[0-9]+]]: i16,ch = load<(load (s16) from %ir.tmp81, align 1)> [[ENTRYTOKEN]], [[BASEPTR]], undef:i64
2222
; DBGDAG-DAG: [[LD1:t[0-9]+]]: i8,ch = load<(load (s8) from %ir.tmp12)> [[ENTRYTOKEN]], [[ADDPTR]], undef:i64

0 commit comments

Comments
 (0)