forked from OSchip/llvm-project
[NFC] Implement SelectionDAG::getObjectPtrOffset() using getMemBasePlusOffset()
Summary: This change is preparatory work to use this helper functions in more places. In order to make this change, getMemBasePlusOffset() has been extended to also take a SDNodeFlags parameter. The motivation for this change is our out-of-tree CHERI backend (https://github.com/CTSRD-CHERI/llvm-project). We use a separate register type to store pointers (128-bit capabilities, which are effectively unforgeable and monotonic fat pointers). These capabilities permit a reduced set of operations and therefore use a separate ValueType (iFATPTR). to represent pointers implemented as capabilities. Therefore, we need to avoid using ISD::ADD for our patterns that operate on pointers and need to use a function that chooses ISD::ADD or a new ISD::PTRADD opcode depending on the value type. We originally added a new DAG.getPointerAdd() function, but after this patch series we can modify the implementation of getMemBasePlusOffset() instead. Avoiding direct uses of ISD::ADD for pointer types will significantly reduce the amount of assertion/instruction selection failures for us in future upstream merges. Reviewers: spatel Reviewed By: spatel Subscribers: merge_guards_bot, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71206
This commit is contained in:
parent
ea8888d1af
commit
fc83f53a86
|
@ -848,22 +848,28 @@ public:
|
||||||
/// Create a logical NOT operation as (XOR Val, BooleanOne).
|
/// Create a logical NOT operation as (XOR Val, BooleanOne).
|
||||||
SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT);
|
SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT);
|
||||||
|
|
||||||
|
/// Returns sum of the base pointer and offset.
|
||||||
|
/// Unlike getObjectPtrOffset this does not set NoUnsignedWrap by default.
|
||||||
|
SDValue getMemBasePlusOffset(SDValue Base, int64_t Offset, const SDLoc &DL,
|
||||||
|
const SDNodeFlags Flags = SDNodeFlags());
|
||||||
|
SDValue getMemBasePlusOffset(SDValue Base, SDValue Offset, const SDLoc &DL,
|
||||||
|
const SDNodeFlags Flags = SDNodeFlags());
|
||||||
|
|
||||||
/// Create an add instruction with appropriate flags when used for
|
/// 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
|
/// 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 from the base pointer to the offset.
|
||||||
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Op, int64_t Offset) {
|
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, int64_t Offset) {
|
||||||
EVT VT = Op.getValueType();
|
SDNodeFlags Flags;
|
||||||
return getObjectPtrOffset(SL, Op, getConstant(Offset, SL, VT));
|
Flags.setNoUnsignedWrap(true);
|
||||||
|
return getMemBasePlusOffset(Ptr, Offset, SL, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Op, SDValue Offset) {
|
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, SDValue Offset) {
|
||||||
EVT VT = Op.getValueType();
|
|
||||||
|
|
||||||
// The object itself can't wrap around the address space, so it shouldn't be
|
// 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.
|
// possible for the adds of the offsets to the split parts to overflow.
|
||||||
SDNodeFlags Flags;
|
SDNodeFlags Flags;
|
||||||
Flags.setNoUnsignedWrap(true);
|
Flags.setNoUnsignedWrap(true);
|
||||||
return getNode(ISD::ADD, SL, VT, Op, Offset, Flags);
|
return getMemBasePlusOffset(Ptr, Offset, SL, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a new CALLSEQ_START node, that starts new call frame, in which
|
/// Return a new CALLSEQ_START node, that starts new call frame, in which
|
||||||
|
@ -1137,11 +1143,6 @@ public:
|
||||||
SDValue getIndexedStore(SDValue OrigStore, const SDLoc &dl, SDValue Base,
|
SDValue getIndexedStore(SDValue OrigStore, const SDLoc &dl, SDValue Base,
|
||||||
SDValue Offset, ISD::MemIndexedMode AM);
|
SDValue Offset, ISD::MemIndexedMode AM);
|
||||||
|
|
||||||
/// Returns sum of the base pointer and offset.
|
|
||||||
/// Unlike getObjectPtrOffset this does not set NoUnsignedWrap by default.
|
|
||||||
SDValue getMemBasePlusOffset(SDValue Base, int64_t Offset, const SDLoc &DL);
|
|
||||||
SDValue getMemBasePlusOffset(SDValue Base, SDValue Offset, const SDLoc &DL);
|
|
||||||
|
|
||||||
SDValue getMaskedLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Base,
|
SDValue getMaskedLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Base,
|
||||||
SDValue Offset, SDValue Mask, SDValue Src0, EVT MemVT,
|
SDValue Offset, SDValue Mask, SDValue Src0, EVT MemVT,
|
||||||
MachineMemOperand *MMO, ISD::MemIndexedMode AM,
|
MachineMemOperand *MMO, ISD::MemIndexedMode AM,
|
||||||
|
|
|
@ -5733,16 +5733,18 @@ static SDValue getMemsetStringVal(EVT VT, const SDLoc &dl, SelectionDAG &DAG,
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue SelectionDAG::getMemBasePlusOffset(SDValue Base, int64_t Offset,
|
SDValue SelectionDAG::getMemBasePlusOffset(SDValue Base, int64_t Offset,
|
||||||
const SDLoc &DL) {
|
const SDLoc &DL,
|
||||||
|
const SDNodeFlags Flags) {
|
||||||
EVT VT = Base.getValueType();
|
EVT VT = Base.getValueType();
|
||||||
return getMemBasePlusOffset(Base, getConstant(Offset, DL, VT), DL);
|
return getMemBasePlusOffset(Base, getConstant(Offset, DL, VT), DL, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue SelectionDAG::getMemBasePlusOffset(SDValue Ptr, SDValue Offset,
|
SDValue SelectionDAG::getMemBasePlusOffset(SDValue Ptr, SDValue Offset,
|
||||||
const SDLoc &DL) {
|
const SDLoc &DL,
|
||||||
|
const SDNodeFlags Flags) {
|
||||||
assert(Offset.getValueType().isInteger());
|
assert(Offset.getValueType().isInteger());
|
||||||
EVT BasePtrVT = Ptr.getValueType();
|
EVT BasePtrVT = Ptr.getValueType();
|
||||||
return getNode(ISD::ADD, DL, BasePtrVT, Ptr, Offset);
|
return getNode(ISD::ADD, DL, BasePtrVT, Ptr, Offset, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if memcpy source is constant data.
|
/// Returns true if memcpy source is constant data.
|
||||||
|
|
Loading…
Reference in New Issue