[llvm-branch-commits] [IRTranslator] Handle ptrtoaddr (PR #139601)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon May 12 11:18:34 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Alexander Richardson (arichardson)

<details>
<summary>Changes</summary>

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 https://github.com/llvm/llvm-project/issues/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
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
+}

``````````

</details>


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


More information about the llvm-branch-commits mailing list