Skip to content

Commit 14a9067

Browse files
committed
[GISel] Introduce MachineIRBuilder::(build|materialize)ObjectPtrOffset
These functions are for building G_PTR_ADDs when we know that the base pointer and the result are both valid pointers into (or just after) the same object. They are similar to SelectionDAG::getObjectPtrOffset. This PR also changes call sites of the generic (build|materialize)PtrAdd functions that implement pointer arithmetic to split large memory accesses to the new functions. Since memory accesses have to fit into an object in memory, pointer arithmetic to an offset into a large memory access also yields an address in that object. Currently, these (build|materialize)ObjectPtrOffset functions only add "nuw" to the generated G_PTR_ADD, but I intend to introduce an "inbounds" MIFlag in a later PR (analogous to a concurrent effort in SDAG: #131862, related: #140017, #141725) that will also be set in the (build|materialize)ObjectPtrOffset functions. Most test changes just add "nuw" to G_PTR_ADDs. Exceptions are AMDGPU's call-outgoing-stack-args.ll, flat-scratch.ll, and freeze.ll tests, where offsets are now folded into scratch instructions, and cases where the behavior of the check regeneration script changed, resulting, e.g., in better checks for "nusw G_PTR_ADD" instructions, matched empty lines, and the use of "CHECK-NEXT" in MIPS tests. For SWDEV-516125.
1 parent 1a3e857 commit 14a9067

File tree

77 files changed

+11342
-11269
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+11342
-11269
lines changed

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,21 @@ class LLVM_ABI MachineIRBuilder {
518518
const SrcOp &Op1,
519519
std::optional<unsigned> Flags = std::nullopt);
520520

521+
/// Build and insert an instruction with appropriate flags for addressing some
522+
/// offset of an object, i.e.: \p Res = nuw G_PTR_ADD \p Op0, \p Op1
523+
/// The value of \p Op0 must be a pointer into or just after an object, adding
524+
/// the value of \p Op1 to it must yield to a pointer into or just after the
525+
/// same object.
526+
///
527+
/// \pre setBasicBlock or setMI must have been called.
528+
/// \pre \p Res and \p Op0 must be generic virtual registers with pointer
529+
/// type.
530+
/// \pre \p Op1 must be a generic virtual register with scalar type.
531+
///
532+
/// \return a MachineInstrBuilder for the newly created instruction.
533+
MachineInstrBuilder buildObjectPtrOffset(const DstOp &Res, const SrcOp &Op0,
534+
const SrcOp &Op1);
535+
521536
/// Materialize and insert \p Res = G_PTR_ADD \p Op0, (G_CONSTANT \p Value)
522537
///
523538
/// G_PTR_ADD adds \p Value bytes to the pointer specified by \p Op0,
@@ -534,10 +549,29 @@ class LLVM_ABI MachineIRBuilder {
534549
/// type as \p Op0 or \p Op0 itself.
535550
///
536551
/// \return a MachineInstrBuilder for the newly created instruction.
537-
std::optional<MachineInstrBuilder> materializePtrAdd(Register &Res,
538-
Register Op0,
539-
const LLT ValueTy,
540-
uint64_t Value);
552+
std::optional<MachineInstrBuilder>
553+
materializePtrAdd(Register &Res, Register Op0, const LLT ValueTy,
554+
uint64_t Value,
555+
std::optional<unsigned> Flags = std::nullopt);
556+
557+
/// Materialize and insert an instruction with appropriate flags for
558+
/// addressing some offset of an object, i.e.:
559+
/// \p Res = nuw G_PTR_ADD \p Op0, (G_CONSTANT \p Value)
560+
/// The value of \p Op0 must be a pointer into or just after an object, adding
561+
/// \p Value to it must yield to a pointer into or just after the same object.
562+
///
563+
/// \pre setBasicBlock or setMI must have been called.
564+
/// \pre \p Op0 must be a generic virtual register with pointer type.
565+
/// \pre \p ValueTy must be a scalar type.
566+
/// \pre \p Res must be 0. This is to detect confusion between
567+
/// materializeObjectPtrOffset() and buildObjectPtrOffset().
568+
/// \post \p Res will either be a new generic virtual register of the same
569+
/// type as \p Op0 or \p Op0 itself.
570+
///
571+
/// \return a MachineInstrBuilder for the newly created instruction.
572+
std::optional<MachineInstrBuilder>
573+
materializeObjectPtrOffset(Register &Res, Register Op0, const LLT ValueTy,
574+
uint64_t Value);
541575

542576
/// Build and insert \p Res = G_PTRMASK \p Op0, \p Op1
543577
MachineInstrBuilder buildPtrMask(const DstOp &Res, const SrcOp &Op0,

llvm/lib/CodeGen/GlobalISel/CallLowering.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,8 @@ void CallLowering::insertSRetLoads(MachineIRBuilder &MIRBuilder, Type *RetTy,
10091009

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

10401041
for (unsigned I = 0; I < NumValues; ++I) {
10411042
Register Addr;
1042-
MIRBuilder.materializePtrAdd(Addr, DemoteReg, OffsetLLTy, Offsets[I]);
1043+
MIRBuilder.materializeObjectPtrOffset(Addr, DemoteReg, OffsetLLTy,
1044+
Offsets[I]);
10431045
auto *MMO = MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOStore,
10441046
MRI.getType(VRegs[I]),
10451047
commonAlignment(BaseAlign, Offsets[I]));

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,7 +1409,7 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
14091409
Regs.size() == 1 ? LI.getMetadata(LLVMContext::MD_range) : nullptr;
14101410
for (unsigned i = 0; i < Regs.size(); ++i) {
14111411
Register Addr;
1412-
MIRBuilder.materializePtrAdd(Addr, Base, OffsetTy, Offsets[i] / 8);
1412+
MIRBuilder.materializeObjectPtrOffset(Addr, Base, OffsetTy, Offsets[i] / 8);
14131413

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

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

14531453
MachinePointerInfo Ptr(SI.getPointerOperand(), Offsets[i] / 8);
14541454
Align BaseAlign = getMemOpAlign(SI);

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4170,7 +4170,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerLoad(GAnyLoad &LoadMI) {
41704170
auto OffsetCst = MIRBuilder.buildConstant(LLT::scalar(PtrTy.getSizeInBits()),
41714171
LargeSplitSize / 8);
41724172
Register PtrAddReg = MRI.createGenericVirtualRegister(PtrTy);
4173-
auto SmallPtr = MIRBuilder.buildPtrAdd(PtrAddReg, PtrReg, OffsetCst);
4173+
auto SmallPtr = MIRBuilder.buildObjectPtrOffset(PtrAddReg, PtrReg, OffsetCst);
41744174
auto SmallLoad = MIRBuilder.buildLoadInstr(LoadMI.getOpcode(), AnyExtTy,
41754175
SmallPtr, *SmallMMO);
41764176

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

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

5352-
MIRBuilder.materializePtrAdd(NewAddrReg, AddrReg, OffsetTy, ByteOffset);
5351+
MIRBuilder.materializeObjectPtrOffset(NewAddrReg, AddrReg, OffsetTy,
5352+
ByteOffset);
53535353

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

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

99699969
// Create the store.
99709970
Register StorePtr = Dst;
99719971
if (CurrOffset != 0) {
99729972
LLT DstTy = MRI.getType(Dst);
9973-
StorePtr = MIB.buildPtrAdd(DstTy, Dst, Offset).getReg(0);
9973+
StorePtr = MIB.buildObjectPtrOffset(DstTy, Dst, Offset).getReg(0);
99749974
}
99759975
MIB.buildStore(LdVal, StorePtr, *StoreMMO);
99769976
CurrOffset += CopyTy.getSizeInBytes();
@@ -10060,7 +10060,7 @@ LegalizerHelper::lowerMemmove(MachineInstr &MI, Register Dst, Register Src,
1006010060
LLT SrcTy = MRI.getType(Src);
1006110061
auto Offset =
1006210062
MIB.buildConstant(LLT::scalar(SrcTy.getSizeInBits()), CurrOffset);
10063-
LoadPtr = MIB.buildPtrAdd(SrcTy, Src, Offset).getReg(0);
10063+
LoadPtr = MIB.buildObjectPtrOffset(SrcTy, Src, Offset).getReg(0);
1006410064
}
1006510065
LoadVals.push_back(MIB.buildLoad(CopyTy, LoadPtr, *LoadMMO).getReg(0));
1006610066
CurrOffset += CopyTy.getSizeInBytes();
@@ -10078,7 +10078,7 @@ LegalizerHelper::lowerMemmove(MachineInstr &MI, Register Dst, Register Src,
1007810078
LLT DstTy = MRI.getType(Dst);
1007910079
auto Offset =
1008010080
MIB.buildConstant(LLT::scalar(DstTy.getSizeInBits()), CurrOffset);
10081-
StorePtr = MIB.buildPtrAdd(DstTy, Dst, Offset).getReg(0);
10081+
StorePtr = MIB.buildObjectPtrOffset(DstTy, Dst, Offset).getReg(0);
1008210082
}
1008310083
MIB.buildStore(LoadVals[I], StorePtr, *StoreMMO);
1008410084
CurrOffset += CopyTy.getSizeInBytes();

llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,18 @@ MachineIRBuilder::buildPtrAdd(const DstOp &Res, const SrcOp &Op0,
208208
return buildInstr(TargetOpcode::G_PTR_ADD, {Res}, {Op0, Op1}, Flags);
209209
}
210210

211+
MachineInstrBuilder MachineIRBuilder::buildObjectPtrOffset(const DstOp &Res,
212+
const SrcOp &Op0,
213+
const SrcOp &Op1) {
214+
return buildPtrAdd(Res, Op0, Op1, MachineInstr::MIFlag::NoUWrap);
215+
}
216+
211217
std::optional<MachineInstrBuilder>
212218
MachineIRBuilder::materializePtrAdd(Register &Res, Register Op0,
213-
const LLT ValueTy, uint64_t Value) {
219+
const LLT ValueTy, uint64_t Value,
220+
std::optional<unsigned> Flags) {
214221
assert(Res == 0 && "Res is a result argument");
215-
assert(ValueTy.isScalar() && "invalid offset type");
222+
assert(ValueTy.isScalar() && "invalid offset type");
216223

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

222229
Res = getMRI()->createGenericVirtualRegister(getMRI()->getType(Op0));
223230
auto Cst = buildConstant(ValueTy, Value);
224-
return buildPtrAdd(Res, Op0, Cst.getReg(0));
231+
return buildPtrAdd(Res, Op0, Cst.getReg(0), Flags);
232+
}
233+
234+
std::optional<MachineInstrBuilder> MachineIRBuilder::materializeObjectPtrOffset(
235+
Register &Res, Register Op0, const LLT ValueTy, uint64_t Value) {
236+
return materializePtrAdd(Res, Op0, ValueTy, Value,
237+
MachineInstr::MIFlag::NoUWrap);
225238
}
226239

227240
MachineInstrBuilder MachineIRBuilder::buildMaskLowPtrBits(const DstOp &Res,

0 commit comments

Comments
 (0)