[llvm-branch-commits] [IRTranslator] Handle ptrtoaddr (PR #139601)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon May 12 11:18:36 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
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