Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[IRTranslator] Handle ptrtoaddr #139601

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

Open
wants to merge 2 commits into
base: users/arichardson/spr/main.irtranslator-handle-ptrtoaddr
Choose a base branch
Loading
from

Conversation

arichardson
Copy link
Member

We lower ptrtoaddr by emitting a G_PTRTOINT, truncating that to the
address size and then truncate/zext to the final integer type.

This has exposed an issue in the GlobalIsel postlegalizer combines where
the truncate is incorrectly being removed.
See #139598

Created using spr 1.3.6-beta.1
@llvmbot
Copy link
Member

llvmbot commented May 12, 2025

@llvm/pr-subscribers-backend-amdgpu

Author: Alexander Richardson (arichardson)

Changes

We lower ptrtoaddr by emitting a G_PTRTOINT, truncating that to the
address size and then truncate/zext to the final integer type.

This has exposed an issue in the GlobalIsel postlegalizer combines where
the truncate is incorrectly being removed.
See #139598


Full diff: https://github.com/llvm/llvm-project/pull/139601.diff

3 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h (+1-3)
  • (modified) llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp (+20)
  • (added) llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll (+187)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index fcdc733d92c7f..41d03c9fb3ed5 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -486,9 +486,7 @@ 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) {
-    return translatePtrToInt(U, MIRBuilder);
-  }
+  bool translatePtrToAddr(const User &U, MachineIRBuilder &MIRBuilder);
   bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
     return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
   }
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 8ab2533afc15f..5666c9e9f45bc 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -1583,6 +1583,26 @@ bool IRTranslator::translateCast(unsigned Opcode, const User &U,
   return true;
 }
 
+bool IRTranslator::translatePtrToAddr(const User &U,
+                                      MachineIRBuilder &MIRBuilder) {
+  if (containsBF16Type(U))
+    return false;
+
+  uint32_t Flags = 0;
+  if (const Instruction *I = dyn_cast<Instruction>(&U))
+    Flags = MachineInstr::copyFlagsFromInstruction(*I);
+
+  Register Op = getOrCreateVReg(*U.getOperand(0));
+  Type *PtrTy = U.getOperand(0)->getType();
+  LLT AddrTy = getLLTForType(*DL->getIndexType(PtrTy), *DL);
+  auto IntPtrTy = getLLTForType(*DL->getIntPtrType(PtrTy), *DL);
+  auto PtrToInt = MIRBuilder.buildPtrToInt(IntPtrTy, Op);
+  PtrToInt->setFlags(Flags);
+  auto 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);
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll
new file mode 100644
index 0000000000000..30f9dbfcaacf8
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll
@@ -0,0 +1,187 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=amdgcn -global-isel -verify-machineinstrs --print-changed --debug < %s | FileCheck %s --check-prefixes=CHECK,GISEL
+; RUN: llc -mtriple=amdgcn -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,SDAG
+;; Check that we can lower ptrtoaddr differently from ptrtoint.
+;; Includes an ignored argument so the registers actually need to be written
+
+define i128 @ptrtoint(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; GISEL-LABEL: ptrtoint:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    v_mov_b32_e32 v2, v6
+; GISEL-NEXT:    v_mov_b32_e32 v3, v7
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoint:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v3, v7
+; SDAG-NEXT:    v_mov_b32_e32 v2, v6
+; SDAG-NEXT:    v_mov_b32_e32 v1, v5
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoint ptr addrspace(8) %ptr to i128
+  ret i128 %ret
+}
+
+define i48 @ptrtoaddr(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; GISEL-LABEL: ptrtoaddr:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoaddr:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v1, v5
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoaddr ptr addrspace(8) %ptr to i48
+  ret i48 %ret
+}
+
+define <2 x i128> @ptrtoint_vec(ptr addrspace(8) %ignored, <2 x ptr addrspace(8)> %ptr) {
+; GISEL-LABEL: ptrtoint_vec:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    v_mov_b32_e32 v2, v6
+; GISEL-NEXT:    v_mov_b32_e32 v3, v7
+; GISEL-NEXT:    v_mov_b32_e32 v4, v8
+; GISEL-NEXT:    v_mov_b32_e32 v5, v9
+; GISEL-NEXT:    v_mov_b32_e32 v6, v10
+; GISEL-NEXT:    v_mov_b32_e32 v7, v11
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoint_vec:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v3, v7
+; SDAG-NEXT:    v_mov_b32_e32 v2, v6
+; SDAG-NEXT:    v_mov_b32_e32 v1, v5
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    v_mov_b32_e32 v4, v8
+; SDAG-NEXT:    v_mov_b32_e32 v5, v9
+; SDAG-NEXT:    v_mov_b32_e32 v6, v10
+; SDAG-NEXT:    v_mov_b32_e32 v7, v11
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoint <2 x ptr addrspace(8)> %ptr to <2 x i128>
+  ret <2 x i128> %ret
+}
+
+define <2 x i64> @ptrtoaddr_vec(ptr addrspace(8) %ignored, <2 x ptr addrspace(8)> %ptr) {
+; GISEL-LABEL: ptrtoaddr_vec:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    v_mov_b32_e32 v2, v8
+; GISEL-NEXT:    v_mov_b32_e32 v3, v9
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoaddr_vec:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v2, v8
+; SDAG-NEXT:    v_and_b32_e32 v1, 0xffff, v5
+; SDAG-NEXT:    v_and_b32_e32 v3, 0xffff, v9
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoaddr <2 x ptr addrspace(8)> %ptr to <2 x i64>
+  ret <2 x i64> %ret
+}
+
+define i256 @ptrtoint_ext(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; GISEL-LABEL: ptrtoint_ext:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    v_mov_b32_e32 v2, v6
+; GISEL-NEXT:    v_mov_b32_e32 v3, v7
+; GISEL-NEXT:    v_mov_b32_e32 v4, 0
+; GISEL-NEXT:    v_mov_b32_e32 v5, 0
+; GISEL-NEXT:    v_mov_b32_e32 v6, 0
+; GISEL-NEXT:    v_mov_b32_e32 v7, 0
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoint_ext:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v3, v7
+; SDAG-NEXT:    v_mov_b32_e32 v2, v6
+; SDAG-NEXT:    v_mov_b32_e32 v1, v5
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    v_mov_b32_e32 v4, 0
+; SDAG-NEXT:    v_mov_b32_e32 v5, 0
+; SDAG-NEXT:    v_mov_b32_e32 v6, 0
+; SDAG-NEXT:    v_mov_b32_e32 v7, 0
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoint ptr addrspace(8) %ptr to i256
+  ret i256 %ret
+}
+
+;; FIXME: this is wrong for the GlobalISel case, we are removing the trunc:
+;; https://github.com/llvm/llvm-project/issues/139598
+define i256 @ptrtoaddr_ext(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; GISEL-LABEL: ptrtoaddr_ext:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    v_mov_b32_e32 v2, v6
+; GISEL-NEXT:    v_mov_b32_e32 v3, v7
+; GISEL-NEXT:    v_mov_b32_e32 v4, 0
+; GISEL-NEXT:    v_mov_b32_e32 v5, 0
+; GISEL-NEXT:    v_mov_b32_e32 v6, 0
+; GISEL-NEXT:    v_mov_b32_e32 v7, 0
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoaddr_ext:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    v_and_b32_e32 v1, 0xffff, v5
+; SDAG-NEXT:    v_mov_b32_e32 v2, 0
+; SDAG-NEXT:    v_mov_b32_e32 v3, 0
+; SDAG-NEXT:    v_mov_b32_e32 v4, 0
+; SDAG-NEXT:    v_mov_b32_e32 v5, 0
+; SDAG-NEXT:    v_mov_b32_e32 v6, 0
+; SDAG-NEXT:    v_mov_b32_e32 v7, 0
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoaddr ptr addrspace(8) %ptr to i256
+  ret i256 %ret
+}
+
+define i64 @ptrtoint_trunc(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; GISEL-LABEL: ptrtoint_trunc:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoint_trunc:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v1, v5
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoint ptr addrspace(8) %ptr to i64
+  ret i64 %ret
+}
+
+define i16 @ptrtoaddr_trunc(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; CHECK-LABEL: ptrtoaddr_trunc:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, v4
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoaddr ptr addrspace(8) %ptr to i16
+  ret i16 %ret
+}

@llvmbot
Copy link
Member

llvmbot commented May 12, 2025

@llvm/pr-subscribers-llvm-globalisel

Author: Alexander Richardson (arichardson)

Changes

We lower ptrtoaddr by emitting a G_PTRTOINT, truncating that to the
address size and then truncate/zext to the final integer type.

This has exposed an issue in the GlobalIsel postlegalizer combines where
the truncate is incorrectly being removed.
See #139598


Full diff: https://github.com/llvm/llvm-project/pull/139601.diff

3 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h (+1-3)
  • (modified) llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp (+20)
  • (added) llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll (+187)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index fcdc733d92c7f..41d03c9fb3ed5 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -486,9 +486,7 @@ 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) {
-    return translatePtrToInt(U, MIRBuilder);
-  }
+  bool translatePtrToAddr(const User &U, MachineIRBuilder &MIRBuilder);
   bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
     return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
   }
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 8ab2533afc15f..5666c9e9f45bc 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -1583,6 +1583,26 @@ bool IRTranslator::translateCast(unsigned Opcode, const User &U,
   return true;
 }
 
+bool IRTranslator::translatePtrToAddr(const User &U,
+                                      MachineIRBuilder &MIRBuilder) {
+  if (containsBF16Type(U))
+    return false;
+
+  uint32_t Flags = 0;
+  if (const Instruction *I = dyn_cast<Instruction>(&U))
+    Flags = MachineInstr::copyFlagsFromInstruction(*I);
+
+  Register Op = getOrCreateVReg(*U.getOperand(0));
+  Type *PtrTy = U.getOperand(0)->getType();
+  LLT AddrTy = getLLTForType(*DL->getIndexType(PtrTy), *DL);
+  auto IntPtrTy = getLLTForType(*DL->getIntPtrType(PtrTy), *DL);
+  auto PtrToInt = MIRBuilder.buildPtrToInt(IntPtrTy, Op);
+  PtrToInt->setFlags(Flags);
+  auto 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);
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll
new file mode 100644
index 0000000000000..30f9dbfcaacf8
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/ptrtoint-ptrtoaddr-p8.ll
@@ -0,0 +1,187 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=amdgcn -global-isel -verify-machineinstrs --print-changed --debug < %s | FileCheck %s --check-prefixes=CHECK,GISEL
+; RUN: llc -mtriple=amdgcn -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,SDAG
+;; Check that we can lower ptrtoaddr differently from ptrtoint.
+;; Includes an ignored argument so the registers actually need to be written
+
+define i128 @ptrtoint(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; GISEL-LABEL: ptrtoint:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    v_mov_b32_e32 v2, v6
+; GISEL-NEXT:    v_mov_b32_e32 v3, v7
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoint:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v3, v7
+; SDAG-NEXT:    v_mov_b32_e32 v2, v6
+; SDAG-NEXT:    v_mov_b32_e32 v1, v5
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoint ptr addrspace(8) %ptr to i128
+  ret i128 %ret
+}
+
+define i48 @ptrtoaddr(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; GISEL-LABEL: ptrtoaddr:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoaddr:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v1, v5
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoaddr ptr addrspace(8) %ptr to i48
+  ret i48 %ret
+}
+
+define <2 x i128> @ptrtoint_vec(ptr addrspace(8) %ignored, <2 x ptr addrspace(8)> %ptr) {
+; GISEL-LABEL: ptrtoint_vec:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    v_mov_b32_e32 v2, v6
+; GISEL-NEXT:    v_mov_b32_e32 v3, v7
+; GISEL-NEXT:    v_mov_b32_e32 v4, v8
+; GISEL-NEXT:    v_mov_b32_e32 v5, v9
+; GISEL-NEXT:    v_mov_b32_e32 v6, v10
+; GISEL-NEXT:    v_mov_b32_e32 v7, v11
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoint_vec:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v3, v7
+; SDAG-NEXT:    v_mov_b32_e32 v2, v6
+; SDAG-NEXT:    v_mov_b32_e32 v1, v5
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    v_mov_b32_e32 v4, v8
+; SDAG-NEXT:    v_mov_b32_e32 v5, v9
+; SDAG-NEXT:    v_mov_b32_e32 v6, v10
+; SDAG-NEXT:    v_mov_b32_e32 v7, v11
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoint <2 x ptr addrspace(8)> %ptr to <2 x i128>
+  ret <2 x i128> %ret
+}
+
+define <2 x i64> @ptrtoaddr_vec(ptr addrspace(8) %ignored, <2 x ptr addrspace(8)> %ptr) {
+; GISEL-LABEL: ptrtoaddr_vec:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    v_mov_b32_e32 v2, v8
+; GISEL-NEXT:    v_mov_b32_e32 v3, v9
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoaddr_vec:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v2, v8
+; SDAG-NEXT:    v_and_b32_e32 v1, 0xffff, v5
+; SDAG-NEXT:    v_and_b32_e32 v3, 0xffff, v9
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoaddr <2 x ptr addrspace(8)> %ptr to <2 x i64>
+  ret <2 x i64> %ret
+}
+
+define i256 @ptrtoint_ext(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; GISEL-LABEL: ptrtoint_ext:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    v_mov_b32_e32 v2, v6
+; GISEL-NEXT:    v_mov_b32_e32 v3, v7
+; GISEL-NEXT:    v_mov_b32_e32 v4, 0
+; GISEL-NEXT:    v_mov_b32_e32 v5, 0
+; GISEL-NEXT:    v_mov_b32_e32 v6, 0
+; GISEL-NEXT:    v_mov_b32_e32 v7, 0
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoint_ext:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v3, v7
+; SDAG-NEXT:    v_mov_b32_e32 v2, v6
+; SDAG-NEXT:    v_mov_b32_e32 v1, v5
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    v_mov_b32_e32 v4, 0
+; SDAG-NEXT:    v_mov_b32_e32 v5, 0
+; SDAG-NEXT:    v_mov_b32_e32 v6, 0
+; SDAG-NEXT:    v_mov_b32_e32 v7, 0
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoint ptr addrspace(8) %ptr to i256
+  ret i256 %ret
+}
+
+;; FIXME: this is wrong for the GlobalISel case, we are removing the trunc:
+;; https://github.com/llvm/llvm-project/issues/139598
+define i256 @ptrtoaddr_ext(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; GISEL-LABEL: ptrtoaddr_ext:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    v_mov_b32_e32 v2, v6
+; GISEL-NEXT:    v_mov_b32_e32 v3, v7
+; GISEL-NEXT:    v_mov_b32_e32 v4, 0
+; GISEL-NEXT:    v_mov_b32_e32 v5, 0
+; GISEL-NEXT:    v_mov_b32_e32 v6, 0
+; GISEL-NEXT:    v_mov_b32_e32 v7, 0
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoaddr_ext:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    v_and_b32_e32 v1, 0xffff, v5
+; SDAG-NEXT:    v_mov_b32_e32 v2, 0
+; SDAG-NEXT:    v_mov_b32_e32 v3, 0
+; SDAG-NEXT:    v_mov_b32_e32 v4, 0
+; SDAG-NEXT:    v_mov_b32_e32 v5, 0
+; SDAG-NEXT:    v_mov_b32_e32 v6, 0
+; SDAG-NEXT:    v_mov_b32_e32 v7, 0
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoaddr ptr addrspace(8) %ptr to i256
+  ret i256 %ret
+}
+
+define i64 @ptrtoint_trunc(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; GISEL-LABEL: ptrtoint_trunc:
+; GISEL:       ; %bb.0:
+; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v0, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; SDAG-LABEL: ptrtoint_trunc:
+; SDAG:       ; %bb.0:
+; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-NEXT:    v_mov_b32_e32 v1, v5
+; SDAG-NEXT:    v_mov_b32_e32 v0, v4
+; SDAG-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoint ptr addrspace(8) %ptr to i64
+  ret i64 %ret
+}
+
+define i16 @ptrtoaddr_trunc(ptr addrspace(8) %ignored, ptr addrspace(8) %ptr) {
+; CHECK-LABEL: ptrtoaddr_trunc:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, v4
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %ret = ptrtoaddr ptr addrspace(8) %ptr to i16
+  ret i16 %ret
+}

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp Outdated Show resolved Hide resolved
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp Outdated Show resolved Hide resolved
Type *PtrTy = U.getOperand(0)->getType();
LLT AddrTy = getLLTForType(*DL->getIndexType(PtrTy), *DL);
auto IntPtrTy = getLLTForType(*DL->getIntPtrType(PtrTy), *DL);
auto PtrToInt = MIRBuilder.buildPtrToInt(IntPtrTy, Op);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not introduce a 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.

I would be perfectly happy with that, not familar with GlobalIsel so not sure what the threshold is for adding a new operation. Happy to do that if it's cleaner?

Copy link
Contributor

Choose a reason for hiding this comment

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

In general I expect a 1:1 mapping with IR opcodes

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried this in #140300 but it seems to me that adding this node introduces a lot of complexity for no real gain. I don't think we track provenance at the MIR level, so having the dedicated node probably doesn't enable much optimization over G_PTRTOINT+G_TRUNC?

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe, but what if some legalization wants to introduce a ptrtoaddr? Are there any cases where that's useful?

Created using spr 1.3.6-beta.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.