Skip to content

[WIP] Introduce a G_PTRTOADDR GIsel node #140300

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

Draft
wants to merge 2 commits into
base: users/arichardson/spr/main.wip-introduce-a-g_ptrtoaddr-gisel-node
Choose a base branch
from
Draft
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
9 changes: 9 additions & 0 deletions llvm/docs/GlobalISel/GenericOpcode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ Convert a pointer to an integer.

%1:_(s32) = G_PTRTOINT %0:_(p0)

G_PTRTOADDR
^^^^^^^^^^^

Extract the address part of a pointer to an integer.

.. code-block:: none

%1:_(s32) = G_PTRTOADDR %0:_(p0)

G_BITCAST
^^^^^^^^^

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,7 @@ class GCastOp : public GenericMachineInstr {
case TargetOpcode::G_FPTOUI_SAT:
case TargetOpcode::G_FPTRUNC:
case TargetOpcode::G_INTTOPTR:
case TargetOpcode::G_PTRTOADDR:
case TargetOpcode::G_PTRTOINT:
case TargetOpcode::G_SEXT:
case TargetOpcode::G_SITOFP:
Expand Down
4 changes: 3 additions & 1 deletion llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,9 @@ class IRTranslator : public MachineFunctionPass {
bool translatePtrToInt(const User &U, MachineIRBuilder &MIRBuilder) {
return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
}
bool translatePtrToAddr(const User &U, MachineIRBuilder &MIRBuilder);
bool translatePtrToAddr(const User &U, MachineIRBuilder &MIRBuilder) {
return translateCast(TargetOpcode::G_PTRTOADDR, U, MIRBuilder);
}
bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
}
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ class LegalizerHelper {
LLVM_ABI LegalizeResult lowerFunnelShift(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerEXT(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerTRUNC(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerPTRTOADDR(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerRotateWithReverseRotate(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerRotate(MachineInstr &MI);

Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,11 @@ class LLVM_ABI MachineIRBuilder {
return buildInstr(TargetOpcode::G_PTRTOINT, {Dst}, {Src});
}

/// Build and insert a G_PTRTOADDR instruction.
MachineInstrBuilder buildPtrToAddr(const DstOp &Dst, const SrcOp &Src) {
return buildInstr(TargetOpcode::G_PTRTOADDR, {Dst}, {Src});
}

/// Build and insert a G_INTTOPTR instruction.
MachineInstrBuilder buildIntToPtr(const DstOp &Dst, const SrcOp &Src) {
return buildInstr(TargetOpcode::G_INTTOPTR, {Dst}, {Src});
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/Support/TargetOpcodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,9 @@ HANDLE_TARGET_OPCODE(G_CONCAT_VECTORS)
/// Generic pointer to int conversion.
HANDLE_TARGET_OPCODE(G_PTRTOINT)

/// Generic pointer to address conversion.
HANDLE_TARGET_OPCODE(G_PTRTOADDR)

/// Generic int to pointer conversion.
HANDLE_TARGET_OPCODE(G_INTTOPTR)

Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/Target/GenericOpcodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ def G_PTRTOINT : GenericInstruction {
let hasSideEffects = false;
}

def G_PTRTOADDR : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
let hasSideEffects = false;
}

def G_BITCAST : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
Expand Down
4 changes: 2 additions & 2 deletions llvm/include/llvm/Target/GlobalISel/Combine.td
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,8 @@ def unary_undef_to_zero: GICombineRule<
def unary_undef_to_undef_frags : GICombinePatFrag<
(outs root:$dst), (ins),
!foreach(op,
[G_TRUNC, G_BITCAST, G_ANYEXT, G_PTRTOINT, G_INTTOPTR, G_FPTOSI,
G_FPTOUI],
[G_TRUNC, G_BITCAST, G_ANYEXT, G_PTRTOINT, G_PTRTOADDR, G_INTTOPTR,
G_FPTOSI, G_FPTOUI],
(pattern (op $dst, $x), (G_IMPLICIT_DEF $x)))>;
def unary_undef_to_undef : GICombineRule<
(defs root:$dst),
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def : GINodeEquiv<G_TRUNC, trunc>;
def : GINodeEquiv<G_BITCAST, bitconvert>;
// G_INTTOPTR - SelectionDAG has no equivalent.
// G_PTRTOINT - SelectionDAG has no equivalent.
// G_PTRTOADDR - SelectionDAG has no equivalent.
def : GINodeEquiv<G_CONSTANT, imm>;
// timm must not be materialized and therefore has no GlobalISel equivalent
def : GINodeEquiv<G_FCONSTANT, fpimm>;
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4814,7 +4814,8 @@ bool CombinerHelper::reassociationCanBreakAddressingModePattern(
MachineInstr *ConvUseMI = &UseMI;
unsigned ConvUseOpc = ConvUseMI->getOpcode();
while (ConvUseOpc == TargetOpcode::G_INTTOPTR ||
ConvUseOpc == TargetOpcode::G_PTRTOINT) {
ConvUseOpc == TargetOpcode::G_PTRTOINT ||
ConvUseOpc == TargetOpcode::G_PTRTOADDR) {
Register DefReg = ConvUseMI->getOperand(0).getReg();
if (!MRI.hasOneNonDBGUse(DefReg))
break;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
}
case TargetOpcode::G_INTTOPTR:
case TargetOpcode::G_PTRTOINT:
case TargetOpcode::G_PTRTOADDR:
if (DstTy.isVector())
break;
// Fall through and handle them the same as zext/trunc.
Expand Down
14 changes: 0 additions & 14 deletions llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1583,20 +1583,6 @@ bool IRTranslator::translateCast(unsigned Opcode, const User &U,
return true;
}

bool IRTranslator::translatePtrToAddr(const User &U,
MachineIRBuilder &MIRBuilder) {
Register Op = getOrCreateVReg(*U.getOperand(0));
Type *PtrTy = U.getOperand(0)->getType();
LLT AddrTy = getLLTForType(*DL->getAddressType(PtrTy), *DL);
auto IntPtrTy = getLLTForType(*DL->getIntPtrType(PtrTy), *DL);
auto PtrToInt = MIRBuilder.buildPtrToInt(IntPtrTy, Op);
auto Addr = PtrToInt;
if (AddrTy != IntPtrTy)
Addr = MIRBuilder.buildTrunc(AddrTy, PtrToInt.getReg(0));
MIRBuilder.buildZExtOrTrunc(getOrCreateVReg(U), Addr.getReg(0));
return true;
}

bool IRTranslator::translateGetElementPtr(const User &U,
MachineIRBuilder &MIRBuilder) {
Value &Op0 = *U.getOperand(0);
Expand Down
8 changes: 7 additions & 1 deletion llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ LegacyLegalizerInfo::LegacyLegalizerInfo() {
setLegalizeScalarToDifferentSizeStrategy(
TargetOpcode::G_EXTRACT, 1, narrowToSmallerAndUnsupportedIfTooSmall);
setScalarAction(TargetOpcode::G_FNEG, 0, {{1, Lower}});

setScalarAction(TargetOpcode::G_PTRTOADDR, 0, {{1, Lower}});
// FIXME: Lower G_PTRTOADDR for vector types using less hacky approach
}

void LegacyLegalizerInfo::computeTables() {
Expand Down Expand Up @@ -204,6 +207,10 @@ LegacyLegalizerInfo::getAspectAction(const InstrAspect &Aspect) const {
if (Aspect.Type.isScalar() || Aspect.Type.isPointer())
return findScalarLegalAction(Aspect);
assert(Aspect.Type.isVector());
if (Aspect.Opcode == TargetOpcode::G_PTRTOADDR) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really ugly and I don't know if there is a better solution?

// FIXME: need to handle this better
return {Lower, Aspect.Type};
}
return findVectorLegalAction(Aspect);
}

Expand Down Expand Up @@ -382,4 +389,3 @@ LegacyLegalizerInfo::getAction(const LegalityQuery &Query) const {
LLVM_DEBUG(dbgs() << ".. (legacy) Legal\n");
return {Legal, 0, LLT{}};
}

33 changes: 33 additions & 0 deletions llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1670,6 +1670,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
narrowScalarSrc(MI, NarrowTy, 1);
Observer.changedInstr(MI);
return Legalized;
case TargetOpcode::G_PTRTOADDR:
case TargetOpcode::G_PTRTOINT:
if (TypeIdx != 0)
return UnableToLegalize;
Expand Down Expand Up @@ -3305,6 +3306,7 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
Observer.changedInstr(MI);
return Legalized;
case TargetOpcode::G_PTRTOADDR:
case TargetOpcode::G_PTRTOINT:
if (TypeIdx != 0)
return UnableToLegalize;
Expand Down Expand Up @@ -4691,6 +4693,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
return lowerEXT(MI);
case G_TRUNC:
return lowerTRUNC(MI);
case G_PTRTOADDR:
return lowerPTRTOADDR(MI);
GISEL_VECREDUCE_CASES_NONSEQ
return lowerVectorReduction(MI);
case G_VAARG:
Expand Down Expand Up @@ -5420,6 +5424,7 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
case G_FPTOUI_SAT:
case G_INTTOPTR:
case G_PTRTOINT:
case G_PTRTOADDR:
case G_ADDRSPACE_CAST:
case G_UADDO:
case G_USUBO:
Expand Down Expand Up @@ -7407,6 +7412,34 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerTRUNC(MachineInstr &MI) {
return UnableToLegalize;
}

LegalizerHelper::LegalizeResult
LegalizerHelper::lowerPTRTOADDR(MachineInstr &MI) {
// Lower G_PTRTOADDR as a truncate to address width of G_PTROINT and then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Lower G_PTRTOADDR as a truncate to address width of G_PTROINT and then
// Lower G_PTRTOADDR as a truncate to address width of G_PTRTOINT and then

// zero extend to the target width if there is no native support for it.
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
const DataLayout &DL = MIRBuilder.getDataLayout();
assert(MI.getOpcode() == TargetOpcode::G_PTRTOADDR);
auto DstReg = MI.getOperand(0).getReg();
auto SrcReg = MI.getOperand(1).getReg();
Comment on lines +7422 to +7423
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
auto DstReg = MI.getOperand(0).getReg();
auto SrcReg = MI.getOperand(1).getReg();
Register DstReg = MI.getOperand(0).getReg();
Register SrcReg = MI.getOperand(1).getReg();

LLT SrcTy = MRI.getType(SrcReg);

LLT AddrTy = getLLTForType(
*DL.getAddressType(MIRBuilder.getContext(), SrcTy.getAddressSpace()), DL);
LLT IntPtrTy = getLLTForType(
*DL.getIntPtrType(MIRBuilder.getContext(), SrcTy.getAddressSpace()), DL);
if (SrcTy.isVector()) {
AddrTy = LLT::vector(SrcTy.getElementCount(), AddrTy);
IntPtrTy = LLT::vector(SrcTy.getElementCount(), IntPtrTy);
}
auto PtrToInt = MIRBuilder.buildPtrToInt(IntPtrTy, SrcReg);
auto Addr = PtrToInt;
if (AddrTy != IntPtrTy)
Addr = MIRBuilder.buildTrunc(AddrTy, PtrToInt.getReg(0));
MIRBuilder.buildZExtOrTrunc(DstReg, Addr.getReg(0));
Comment on lines +7434 to +7438
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
auto PtrToInt = MIRBuilder.buildPtrToInt(IntPtrTy, SrcReg);
auto Addr = PtrToInt;
if (AddrTy != IntPtrTy)
Addr = MIRBuilder.buildTrunc(AddrTy, PtrToInt.getReg(0));
MIRBuilder.buildZExtOrTrunc(DstReg, Addr.getReg(0));
Register Addr = MIRBuilder.buildPtrToInt(IntPtrTy, SrcReg).getReg(0);
if (AddrTy != IntPtrTy)
Addr = MIRBuilder.buildTrunc(AddrTy, Addr).getReg(0);
MIRBuilder.buildZExtOrTrunc(DstReg, Addr);

MI.eraseFromParent();
return Legalized;
}

LegalizerHelper::LegalizeResult
LegalizerHelper::lowerRotateWithReverseRotate(MachineInstr &MI) {
auto [Dst, DstTy, Src, SrcTy, Amt, AmtTy] = MI.getFirst3RegLLTs();
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/CodeGen/MachineVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,7 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
break;
}
case TargetOpcode::G_INTTOPTR:
case TargetOpcode::G_PTRTOADDR:
case TargetOpcode::G_PTRTOINT:
case TargetOpcode::G_ADDRSPACE_CAST: {
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
Expand All @@ -1366,6 +1367,11 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
report("ptrtoint source type must be a pointer", MI);
if (DstTy.isPointer())
report("ptrtoint result type must not be a pointer", MI);
} else if (MI->getOpcode() == TargetOpcode::G_PTRTOADDR) {
if (!SrcTy.isPointer())
report("ptrtoaddr source type must be a pointer", MI);
if (DstTy.isPointer())
report("ptrtoaddr result type must not be a pointer", MI);
} else {
assert(MI->getOpcode() == TargetOpcode::G_ADDRSPACE_CAST);
if (!SrcTy.isPointer() || !DstTy.isPointer())
Expand Down
Loading