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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits