[llvm-branch-commits] [llvm] [WIP] Introduce a G_PTRTOADDR GIsel node (PR #140300)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Oct 15 16:11:48 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-mips
Author: Alexander Richardson (arichardson)
<details>
<summary>Changes</summary>
This is an alternative to https://github.com/llvm/llvm-project/pull/139601
---
Full diff: https://github.com/llvm/llvm-project/pull/140300.diff
18 Files Affected:
- (modified) llvm/docs/GlobalISel/GenericOpcode.rst (+9)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h (+1)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h (+1-2)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h (+1)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h (+5)
- (modified) llvm/include/llvm/Support/TargetOpcodes.def (+3)
- (modified) llvm/include/llvm/Target/GenericOpcodes.td (+6)
- (modified) llvm/include/llvm/Target/GlobalISel/Combine.td (+2-2)
- (modified) llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td (+1)
- (modified) llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp (+2-1)
- (modified) llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp (+1)
- (modified) llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp (+7-1)
- (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+31)
- (modified) llvm/lib/CodeGen/MachineVerifier.cpp (+6)
- (modified) llvm/lib/Target/ARM/ARMInstructionSelector.cpp (+1)
- (modified) llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp (+1)
- (modified) llvm/lib/Target/Mips/MipsInstructionSelector.cpp (+1)
- (modified) llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp (+1)
``````````diff
diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst
index b055327466739..7fb99116f2120 100644
--- a/llvm/docs/GlobalISel/GenericOpcode.rst
+++ b/llvm/docs/GlobalISel/GenericOpcode.rst
@@ -196,6 +196,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
^^^^^^^^^
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index 5faf57fd06228..0a620fdc54d31 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -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:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index 3d7ccd55ee042..722e3e61e542e 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -487,8 +487,7 @@ class IRTranslator : public MachineFunctionPass {
return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
}
bool translatePtrToAddr(const User &U, MachineIRBuilder &MIRBuilder) {
- // FIXME: this is not correct for pointers with addr width != pointer width
- return translatePtrToInt(U, MIRBuilder);
+ return translateCast(TargetOpcode::G_PTRTOADDR, U, MIRBuilder);
}
bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index c0e426c4a8db3..dc2f6db2313f4 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -475,6 +475,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);
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 40c7792f7e8a2..850ab1dbcc773 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -749,6 +749,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});
diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index e55314568d683..7d6baf7545ae8 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -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)
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index e3f995d53484f..aa6c99f6da3cb 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -155,6 +155,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);
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 3d21f522e97ce..042de83d3345b 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -453,8 +453,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),
diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
index c0d480294dd8b..5399731d63ff4 100644
--- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
+++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
@@ -57,6 +57,7 @@ def : GINodeEquiv<G_TRUNC_USAT_U, truncusat_u>;
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>;
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index b425b952bfc1d..26f18487392f0 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -4909,7 +4909,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;
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 04d93098a5260..309bf470deb66 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -485,6 +485,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.
diff --git a/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp b/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp
index 05923e5fc97cc..134c0cea92a35 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp
@@ -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() {
@@ -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) {
+ // FIXME: need to handle this better
+ return {Lower, Aspect.Type};
+ }
return findVectorLegalAction(Aspect);
}
@@ -382,4 +389,3 @@ LegacyLegalizerInfo::getAction(const LegalityQuery &Query) const {
LLVM_DEBUG(dbgs() << ".. (legacy) Legal\n");
return {Legal, 0, LLT{}};
}
-
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 38ec83f81f471..e74531a5ad1b8 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -1792,6 +1792,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;
@@ -3439,6 +3440,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;
@@ -4853,6 +4855,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:
@@ -5600,6 +5604,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:
@@ -7966,6 +7971,32 @@ 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_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();
+ LLT AddrTy = MRI.getType(DstReg);
+ LLT SrcTy = MRI.getType(SrcReg);
+ LLT IntPtrTy = getLLTForType(
+ *DL.getIntPtrType(MIRBuilder.getContext(), SrcTy.getAddressSpace()), DL);
+ if (SrcTy.isVector()) {
+ IntPtrTy = LLT::vector(SrcTy.getElementCount(), IntPtrTy);
+ }
+ if (AddrTy != IntPtrTy) {
+ auto PtrToInt = MIRBuilder.buildPtrToInt(IntPtrTy, SrcReg);
+ MIRBuilder.buildTrunc(DstReg, PtrToInt.getReg(0));
+ } else {
+ MIRBuilder.buildPtrToInt(DstReg, SrcReg);
+ }
+ MI.eraseFromParent();
+ return Legalized;
+}
+
LegalizerHelper::LegalizeResult
LegalizerHelper::lowerRotateWithReverseRotate(MachineInstr &MI) {
auto [Dst, DstTy, Src, SrcTy, Amt, AmtTy] = MI.getFirst3RegLLTs();
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 115485509c4a5..2f3037adcf533 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -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());
@@ -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())
diff --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
index 2d3cb71fbc3fd..21344e973ba66 100644
--- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
+++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
@@ -1018,6 +1018,7 @@ bool ARMInstructionSelector::select(MachineInstr &I) {
break;
}
case G_INTTOPTR:
+ case G_PTRTOADDR:
case G_PTRTOINT: {
auto SrcReg = I.getOperand(1).getReg();
auto DstReg = I.getOperand(0).getReg();
diff --git a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
index 0493fd9e317d5..637a578bfdeb5 100644
--- a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
@@ -215,6 +215,7 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_PTR_ADD:
case G_INTTOPTR:
case G_PTRTOINT:
+ case G_PTRTOADDR:
case G_CTLZ:
// FIXME: We're abusing the fact that everything lives in a GPR for now; in
// the real world we would use different mappings.
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index 332749165a3ff..7109cbeffa463 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -347,6 +347,7 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
break;
}
case G_INTTOPTR:
+ case G_PTRTOADDR:
case G_PTRTOINT: {
I.setDesc(TII.get(COPY));
return selectCopy(I, MRI);
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
index 4aecaf18db480..752ee7db00e66 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
@@ -422,6 +422,7 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_SEXTLOAD:
case G_PTR_ADD:
case G_INTTOPTR:
+ case G_PTRTOADDR:
case G_PTRTOINT:
case G_AND:
case G_OR:
``````````
</details>
https://github.com/llvm/llvm-project/pull/140300
More information about the llvm-branch-commits
mailing list