Skip to content

[GISel] Introduce MachineIRBuilder::(build|materialize)ObjectPtrOffset #150392

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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
42 changes: 38 additions & 4 deletions llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,21 @@ class LLVM_ABI MachineIRBuilder {
const SrcOp &Op1,
std::optional<unsigned> Flags = std::nullopt);

/// Build and insert an instruction with appropriate flags for addressing some
/// offset of an object, i.e.: \p Res = nuw G_PTR_ADD \p Op0, \p Op1
/// The value of \p Op0 must be a pointer into or just after an object, adding
/// the value of \p Op1 to it must yield to a pointer into or just after the
/// same object.
///
/// \pre setBasicBlock or setMI must have been called.
/// \pre \p Res and \p Op0 must be generic virtual registers with pointer
/// type.
/// \pre \p Op1 must be a generic virtual register with scalar type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildObjectPtrOffset(const DstOp &Res, const SrcOp &Op0,
const SrcOp &Op1);

/// Materialize and insert \p Res = G_PTR_ADD \p Op0, (G_CONSTANT \p Value)
///
/// G_PTR_ADD adds \p Value bytes to the pointer specified by \p Op0,
Expand All @@ -534,10 +549,29 @@ class LLVM_ABI MachineIRBuilder {
/// type as \p Op0 or \p Op0 itself.
///
/// \return a MachineInstrBuilder for the newly created instruction.
std::optional<MachineInstrBuilder> materializePtrAdd(Register &Res,
Register Op0,
const LLT ValueTy,
uint64_t Value);
std::optional<MachineInstrBuilder>
materializePtrAdd(Register &Res, Register Op0, const LLT ValueTy,
uint64_t Value,
std::optional<unsigned> Flags = std::nullopt);

/// Materialize and insert an instruction with appropriate flags for
/// addressing some offset of an object, i.e.:
/// \p Res = nuw G_PTR_ADD \p Op0, (G_CONSTANT \p Value)
/// The value of \p Op0 must be a pointer into or just after an object, adding
/// \p Value to it must yield to a pointer into or just after the same object.
///
/// \pre setBasicBlock or setMI must have been called.
/// \pre \p Op0 must be a generic virtual register with pointer type.
/// \pre \p ValueTy must be a scalar type.
/// \pre \p Res must be 0. This is to detect confusion between
/// materializeObjectPtrOffset() and buildObjectPtrOffset().
/// \post \p Res will either be a new generic virtual register of the same
/// type as \p Op0 or \p Op0 itself.
///
/// \return a MachineInstrBuilder for the newly created instruction.
std::optional<MachineInstrBuilder>
materializeObjectPtrOffset(Register &Res, Register Op0, const LLT ValueTy,
uint64_t Value);

/// Build and insert \p Res = G_PTRMASK \p Op0, \p Op1
MachineInstrBuilder buildPtrMask(const DstOp &Res, const SrcOp &Op0,
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,8 @@ void CallLowering::insertSRetLoads(MachineIRBuilder &MIRBuilder, Type *RetTy,

for (unsigned I = 0; I < NumValues; ++I) {
Register Addr;
MIRBuilder.materializePtrAdd(Addr, DemoteReg, OffsetLLTy, Offsets[I]);
MIRBuilder.materializeObjectPtrOffset(Addr, DemoteReg, OffsetLLTy,
Offsets[I]);
auto *MMO = MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad,
MRI.getType(VRegs[I]),
commonAlignment(BaseAlign, Offsets[I]));
Expand Down Expand Up @@ -1039,7 +1040,8 @@ void CallLowering::insertSRetStores(MachineIRBuilder &MIRBuilder, Type *RetTy,

for (unsigned I = 0; I < NumValues; ++I) {
Register Addr;
MIRBuilder.materializePtrAdd(Addr, DemoteReg, OffsetLLTy, Offsets[I]);
MIRBuilder.materializeObjectPtrOffset(Addr, DemoteReg, OffsetLLTy,
Offsets[I]);
auto *MMO = MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOStore,
MRI.getType(VRegs[I]),
commonAlignment(BaseAlign, Offsets[I]));
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1409,7 +1409,7 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
Regs.size() == 1 ? LI.getMetadata(LLVMContext::MD_range) : nullptr;
for (unsigned i = 0; i < Regs.size(); ++i) {
Register Addr;
MIRBuilder.materializePtrAdd(Addr, Base, OffsetTy, Offsets[i] / 8);
MIRBuilder.materializeObjectPtrOffset(Addr, Base, OffsetTy, Offsets[i] / 8);

MachinePointerInfo Ptr(LI.getPointerOperand(), Offsets[i] / 8);
Align BaseAlign = getMemOpAlign(LI);
Expand Down Expand Up @@ -1448,7 +1448,7 @@ bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) {

for (unsigned i = 0; i < Vals.size(); ++i) {
Register Addr;
MIRBuilder.materializePtrAdd(Addr, Base, OffsetTy, Offsets[i] / 8);
MIRBuilder.materializeObjectPtrOffset(Addr, Base, OffsetTy, Offsets[i] / 8);

MachinePointerInfo Ptr(SI.getPointerOperand(), Offsets[i] / 8);
Align BaseAlign = getMemOpAlign(SI);
Expand Down
18 changes: 9 additions & 9 deletions llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4170,7 +4170,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerLoad(GAnyLoad &LoadMI) {
auto OffsetCst = MIRBuilder.buildConstant(LLT::scalar(PtrTy.getSizeInBits()),
LargeSplitSize / 8);
Register PtrAddReg = MRI.createGenericVirtualRegister(PtrTy);
auto SmallPtr = MIRBuilder.buildPtrAdd(PtrAddReg, PtrReg, OffsetCst);
auto SmallPtr = MIRBuilder.buildObjectPtrOffset(PtrAddReg, PtrReg, OffsetCst);
auto SmallLoad = MIRBuilder.buildLoadInstr(LoadMI.getOpcode(), AnyExtTy,
SmallPtr, *SmallMMO);

Expand Down Expand Up @@ -4277,8 +4277,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerStore(GStore &StoreMI) {
LLT PtrTy = MRI.getType(PtrReg);
auto OffsetCst = MIRBuilder.buildConstant(
LLT::scalar(PtrTy.getSizeInBits()), LargeSplitSize / 8);
auto SmallPtr =
MIRBuilder.buildPtrAdd(PtrTy, PtrReg, OffsetCst);
auto SmallPtr = MIRBuilder.buildObjectPtrOffset(PtrTy, PtrReg, OffsetCst);

MachineMemOperand *LargeMMO =
MF.getMachineMemOperand(&MMO, 0, LargeSplitSize / 8);
Expand Down Expand Up @@ -5349,7 +5348,8 @@ LegalizerHelper::reduceLoadStoreWidth(GLoadStore &LdStMI, unsigned TypeIdx,
unsigned ByteOffset = Offset / 8;
Register NewAddrReg;

MIRBuilder.materializePtrAdd(NewAddrReg, AddrReg, OffsetTy, ByteOffset);
MIRBuilder.materializeObjectPtrOffset(NewAddrReg, AddrReg, OffsetTy,
ByteOffset);

MachineMemOperand *NewMMO =
MF.getMachineMemOperand(&MMO, ByteOffset, PartTy);
Expand Down Expand Up @@ -9822,7 +9822,7 @@ LegalizerHelper::lowerMemset(MachineInstr &MI, Register Dst, Register Val,
if (DstOff != 0) {
auto Offset =
MIB.buildConstant(LLT::scalar(PtrTy.getSizeInBits()), DstOff);
Ptr = MIB.buildPtrAdd(PtrTy, Dst, Offset).getReg(0);
Ptr = MIB.buildObjectPtrOffset(PtrTy, Dst, Offset).getReg(0);
}

MIB.buildStore(Value, Ptr, *StoreMMO);
Expand Down Expand Up @@ -9962,15 +9962,15 @@ LegalizerHelper::lowerMemcpy(MachineInstr &MI, Register Dst, Register Src,
LLT SrcTy = MRI.getType(Src);
Offset = MIB.buildConstant(LLT::scalar(SrcTy.getSizeInBits()), CurrOffset)
.getReg(0);
LoadPtr = MIB.buildPtrAdd(SrcTy, Src, Offset).getReg(0);
LoadPtr = MIB.buildObjectPtrOffset(SrcTy, Src, Offset).getReg(0);
}
auto LdVal = MIB.buildLoad(CopyTy, LoadPtr, *LoadMMO);

// Create the store.
Register StorePtr = Dst;
if (CurrOffset != 0) {
LLT DstTy = MRI.getType(Dst);
StorePtr = MIB.buildPtrAdd(DstTy, Dst, Offset).getReg(0);
StorePtr = MIB.buildObjectPtrOffset(DstTy, Dst, Offset).getReg(0);
}
MIB.buildStore(LdVal, StorePtr, *StoreMMO);
CurrOffset += CopyTy.getSizeInBytes();
Expand Down Expand Up @@ -10060,7 +10060,7 @@ LegalizerHelper::lowerMemmove(MachineInstr &MI, Register Dst, Register Src,
LLT SrcTy = MRI.getType(Src);
auto Offset =
MIB.buildConstant(LLT::scalar(SrcTy.getSizeInBits()), CurrOffset);
LoadPtr = MIB.buildPtrAdd(SrcTy, Src, Offset).getReg(0);
LoadPtr = MIB.buildObjectPtrOffset(SrcTy, Src, Offset).getReg(0);
}
LoadVals.push_back(MIB.buildLoad(CopyTy, LoadPtr, *LoadMMO).getReg(0));
CurrOffset += CopyTy.getSizeInBytes();
Expand All @@ -10078,7 +10078,7 @@ LegalizerHelper::lowerMemmove(MachineInstr &MI, Register Dst, Register Src,
LLT DstTy = MRI.getType(Dst);
auto Offset =
MIB.buildConstant(LLT::scalar(DstTy.getSizeInBits()), CurrOffset);
StorePtr = MIB.buildPtrAdd(DstTy, Dst, Offset).getReg(0);
StorePtr = MIB.buildObjectPtrOffset(DstTy, Dst, Offset).getReg(0);
}
MIB.buildStore(LoadVals[I], StorePtr, *StoreMMO);
CurrOffset += CopyTy.getSizeInBytes();
Expand Down
19 changes: 16 additions & 3 deletions llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,18 @@ MachineIRBuilder::buildPtrAdd(const DstOp &Res, const SrcOp &Op0,
return buildInstr(TargetOpcode::G_PTR_ADD, {Res}, {Op0, Op1}, Flags);
}

MachineInstrBuilder MachineIRBuilder::buildObjectPtrOffset(const DstOp &Res,
const SrcOp &Op0,
const SrcOp &Op1) {
return buildPtrAdd(Res, Op0, Op1, MachineInstr::MIFlag::NoUWrap);
}

std::optional<MachineInstrBuilder>
MachineIRBuilder::materializePtrAdd(Register &Res, Register Op0,
const LLT ValueTy, uint64_t Value) {
const LLT ValueTy, uint64_t Value,
std::optional<unsigned> Flags) {
assert(Res == 0 && "Res is a result argument");
assert(ValueTy.isScalar() && "invalid offset type");
assert(ValueTy.isScalar() && "invalid offset type");

if (Value == 0) {
Res = Op0;
Expand All @@ -221,7 +228,13 @@ MachineIRBuilder::materializePtrAdd(Register &Res, Register Op0,

Res = getMRI()->createGenericVirtualRegister(getMRI()->getType(Op0));
auto Cst = buildConstant(ValueTy, Value);
return buildPtrAdd(Res, Op0, Cst.getReg(0));
return buildPtrAdd(Res, Op0, Cst.getReg(0), Flags);
}

std::optional<MachineInstrBuilder> MachineIRBuilder::materializeObjectPtrOffset(
Register &Res, Register Op0, const LLT ValueTy, uint64_t Value) {
return materializePtrAdd(Res, Op0, ValueTy, Value,
MachineInstr::MIFlag::NoUWrap);
}

MachineInstrBuilder MachineIRBuilder::buildMaskLowPtrBits(const DstOp &Res,
Expand Down
Loading