[llvm] Support vector `ptrtoint` and `inttoptr` with X86 GlobalISel. (PR #175270)

via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 15 05:03:00 PST 2026


https://github.com/YohayAiTe updated https://github.com/llvm/llvm-project/pull/175270

>From fc2ac1562d01924a17c83e16bcffca69f23eadcb Mon Sep 17 00:00:00 2001
From: Yohay <yohay.ailon.tevet at gmail.com>
Date: Fri, 9 Jan 2026 23:11:36 +0200
Subject: [PATCH 1/3] Added tests for vectorised inttoptr and ptrtoint on X86
 GlobalISel.

---
 llvm/test/CodeGen/X86/GlobalISel/inttoptr.ll  |  12 --
 .../CodeGen/X86/GlobalISel/inttoptr_32.ll     | 148 ++++++++++++++++
 .../CodeGen/X86/GlobalISel/inttoptr_64.ll     | 115 ++++++++++++
 llvm/test/CodeGen/X86/GlobalISel/ptrtoint.ll  |  56 ------
 .../CodeGen/X86/GlobalISel/ptrtoint_32.ll     |  48 +++++
 .../CodeGen/X86/GlobalISel/ptrtoint_64.ll     | 166 ++++++++++++++++++
 6 files changed, 477 insertions(+), 68 deletions(-)
 delete mode 100644 llvm/test/CodeGen/X86/GlobalISel/inttoptr.ll
 create mode 100644 llvm/test/CodeGen/X86/GlobalISel/inttoptr_32.ll
 create mode 100644 llvm/test/CodeGen/X86/GlobalISel/inttoptr_64.ll
 delete mode 100644 llvm/test/CodeGen/X86/GlobalISel/ptrtoint.ll
 create mode 100644 llvm/test/CodeGen/X86/GlobalISel/ptrtoint_32.ll
 create mode 100644 llvm/test/CodeGen/X86/GlobalISel/ptrtoint_64.ll

diff --git a/llvm/test/CodeGen/X86/GlobalISel/inttoptr.ll b/llvm/test/CodeGen/X86/GlobalISel/inttoptr.ll
deleted file mode 100644
index 64daf4ea6d957..0000000000000
--- a/llvm/test/CodeGen/X86/GlobalISel/inttoptr.ll
+++ /dev/null
@@ -1,12 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=CHECK
-
-define ptr @inttoptr_p0_s64(i64 %val) {
-; CHECK-LABEL: inttoptr_p0_s64:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    movq %rdi, %rax
-; CHECK-NEXT:    retq
-entry:
-  %0 = inttoptr i64 %val to ptr
-  ret ptr %0
-}
diff --git a/llvm/test/CodeGen/X86/GlobalISel/inttoptr_32.ll b/llvm/test/CodeGen/X86/GlobalISel/inttoptr_32.ll
new file mode 100644
index 0000000000000..36d08356f1b43
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/inttoptr_32.ll
@@ -0,0 +1,148 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=i386-linux-gnu -global-isel -mattr=-sse2    -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=NO-SSE
+; RUN: llc -mtriple=i386-linux-gnu -global-isel -mattr=+sse2    -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=SSE
+; RUN: llc -mtriple=i386-linux-gnu -global-isel -mattr=+avx     -verify-machineinstrs < %s -o - | FileCheck %s --check-prefixes=AVX
+; RUN: llc -mtriple=i386-linux-gnu -global-isel -mattr=+avx512f -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=AVX512
+
+define ptr @inttoptr_p0_s32(i32 %val) {
+; CHECK-LABEL: inttoptr_p0_s32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl 4(%esp), %eax
+; CHECK-NEXT:    retl
+; NO-SSE-LABEL: inttoptr_p0_s32:
+; NO-SSE:       # %bb.0: # %entry
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; NO-SSE-NEXT:    retl
+;
+; SSE-LABEL: inttoptr_p0_s32:
+; SSE:       # %bb.0: # %entry
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SSE-NEXT:    retl
+;
+; AVX-LABEL: inttoptr_p0_s32:
+; AVX:       # %bb.0: # %entry
+; AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; AVX-NEXT:    retl
+;
+; AVX512-LABEL: inttoptr_p0_s32:
+; AVX512:       # %bb.0: # %entry
+; AVX512-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; AVX512-NEXT:    retl
+entry:
+  %0 = inttoptr i32 %val to ptr
+  ret ptr %0
+}
+
+define <4 x ptr> @inttoptr_v4p0_v4s32(<4 x i32> %val) {
+; NO-SSE-LABEL: inttoptr_v4p0_v4s32:
+; NO-SSE:       # %bb.0: # %entry
+; NO-SSE-NEXT:    pushl %edi
+; NO-SSE-NEXT:    .cfi_def_cfa_offset 8
+; NO-SSE-NEXT:    pushl %esi
+; NO-SSE-NEXT:    .cfi_def_cfa_offset 12
+; NO-SSE-NEXT:    .cfi_offset %esi, -12
+; NO-SSE-NEXT:    .cfi_offset %edi, -8
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %edi
+; NO-SSE-NEXT:    movl %ecx, (%eax)
+; NO-SSE-NEXT:    movl %edx, 4(%eax)
+; NO-SSE-NEXT:    movl %esi, 8(%eax)
+; NO-SSE-NEXT:    movl %edi, 12(%eax)
+; NO-SSE-NEXT:    popl %esi
+; NO-SSE-NEXT:    .cfi_def_cfa_offset 8
+; NO-SSE-NEXT:    popl %edi
+; NO-SSE-NEXT:    .cfi_def_cfa_offset 4
+; NO-SSE-NEXT:    retl
+;
+; SSE-LABEL: inttoptr_v4p0_v4s32:
+; SSE:       # %bb.0: # %entry
+; SSE-NEXT:    pushl %edi
+; SSE-NEXT:    .cfi_def_cfa_offset 8
+; SSE-NEXT:    pushl %esi
+; SSE-NEXT:    .cfi_def_cfa_offset 12
+; SSE-NEXT:    .cfi_offset %esi, -12
+; SSE-NEXT:    .cfi_offset %edi, -8
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %edi
+; SSE-NEXT:    movl %ecx, (%eax)
+; SSE-NEXT:    movl %edx, 4(%eax)
+; SSE-NEXT:    movl %esi, 8(%eax)
+; SSE-NEXT:    movl %edi, 12(%eax)
+; SSE-NEXT:    popl %esi
+; SSE-NEXT:    .cfi_def_cfa_offset 8
+; SSE-NEXT:    popl %edi
+; SSE-NEXT:    .cfi_def_cfa_offset 4
+; SSE-NEXT:    retl
+;
+; AVX-LABEL: inttoptr_v4p0_v4s32:
+; AVX:       # %bb.0: # %entry
+; AVX-NEXT:    retl
+;
+; AVX512-LABEL: inttoptr_v4p0_v4s32:
+; AVX512:       # %bb.0: # %entry
+; AVX512-NEXT:    retl
+entry:
+  %0 = inttoptr <4 x i32> %val to <4 x ptr>
+  ret <4 x ptr> %0
+}
+
+define <8 x ptr> @inttoptr_v8p0_v8s32(<8 x i32> %val) {
+; NO-SSE-LABEL: inttoptr_v8p0_v8s32:
+; NO-SSE:       # %bb.0: # %entry
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; NO-SSE-NEXT:    movl %ecx, (%eax)
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; NO-SSE-NEXT:    movl %ecx, 4(%eax)
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; NO-SSE-NEXT:    movl %ecx, 8(%eax)
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; NO-SSE-NEXT:    movl %ecx, 12(%eax)
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; NO-SSE-NEXT:    movl %ecx, 16(%eax)
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; NO-SSE-NEXT:    movl %ecx, 20(%eax)
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; NO-SSE-NEXT:    movl %ecx, 24(%eax)
+; NO-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; NO-SSE-NEXT:    movl %ecx, 28(%eax)
+; NO-SSE-NEXT:    retl
+;
+; SSE-LABEL: inttoptr_v8p0_v8s32:
+; SSE:       # %bb.0: # %entry
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SSE-NEXT:    movl %ecx, (%eax)
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SSE-NEXT:    movl %ecx, 4(%eax)
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SSE-NEXT:    movl %ecx, 8(%eax)
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SSE-NEXT:    movl %ecx, 12(%eax)
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SSE-NEXT:    movl %ecx, 16(%eax)
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SSE-NEXT:    movl %ecx, 20(%eax)
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SSE-NEXT:    movl %ecx, 24(%eax)
+; SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SSE-NEXT:    movl %ecx, 28(%eax)
+; SSE-NEXT:    retl
+;
+; AVX-LABEL: inttoptr_v8p0_v8s32:
+; AVX:       # %bb.0: # %entry
+; AVX-NEXT:    retl
+;
+; AVX512-LABEL: inttoptr_v8p0_v8s32:
+; AVX512:       # %bb.0: # %entry
+; AVX512-NEXT:    retl
+entry:
+  %0 = inttoptr <8 x i32> %val to <8 x ptr>
+  ret <8 x ptr> %0
+}
diff --git a/llvm/test/CodeGen/X86/GlobalISel/inttoptr_64.ll b/llvm/test/CodeGen/X86/GlobalISel/inttoptr_64.ll
new file mode 100644
index 0000000000000..f661ee8d9776f
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/inttoptr_64.ll
@@ -0,0 +1,115 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -mattr=-sse2    -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=NO-SSE
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel                 -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=SSE
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -mattr=+avx     -verify-machineinstrs < %s -o - | FileCheck %s --check-prefixes=AVX
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -mattr=+avx512f -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=AVX512
+
+define ptr @inttoptr_p0_s64(i64 %val) {
+; NO-SSE-LABEL: inttoptr_p0_s64:
+; NO-SSE:       # %bb.0: # %entry
+; NO-SSE-NEXT:    movq %rdi, %rax
+; NO-SSE-NEXT:    retq
+;
+; SSE-LABEL: inttoptr_p0_s64:
+; SSE:       # %bb.0: # %entry
+; SSE-NEXT:    movq %rdi, %rax
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: inttoptr_p0_s64:
+; AVX:       # %bb.0: # %entry
+; AVX-NEXT:    movq %rdi, %rax
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: inttoptr_p0_s64:
+; AVX512:       # %bb.0: # %entry
+; AVX512-NEXT:    movq %rdi, %rax
+; AVX512-NEXT:    retq
+entry:
+  %0 = inttoptr i64 %val to ptr
+  ret ptr %0
+}
+
+define <2 x ptr> @inttoptr_v2p0_v2s64(<2 x i64> %val) {
+; CHECK-LABEL: inttoptr_v2p0_v2s64:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    retq
+; NO-SSE-LABEL: inttoptr_v2p0_v2s64:
+; NO-SSE:       # %bb.0: # %entry
+; NO-SSE-NEXT:    movq %rdi, %rax
+; NO-SSE-NEXT:    movq %rsi, %rdx
+; NO-SSE-NEXT:    retq
+;
+; SSE-LABEL: inttoptr_v2p0_v2s64:
+; SSE:       # %bb.0: # %entry
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: inttoptr_v2p0_v2s64:
+; AVX:       # %bb.0: # %entry
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: inttoptr_v2p0_v2s64:
+; AVX512:       # %bb.0: # %entry
+; AVX512-NEXT:    retq
+entry:
+  %0 = inttoptr <2 x i64> %val to <2 x ptr>
+  ret <2 x ptr> %0
+}
+
+define <4 x ptr> @inttoptr_v4p0_v4s64(<4 x i64> %val) {
+; NO-SSE-LABEL: inttoptr_v4p0_v4s64:
+; NO-SSE:       # %bb.0: # %entry
+; NO-SSE-NEXT:    movq %rdi, %rax
+; NO-SSE-NEXT:    movq %rsi, (%rdi)
+; NO-SSE-NEXT:    movq %rdx, 8(%rdi)
+; NO-SSE-NEXT:    movq %rcx, 16(%rdi)
+; NO-SSE-NEXT:    movq %r8, 24(%rdi)
+; NO-SSE-NEXT:    retq
+;
+; SSE-LABEL: inttoptr_v4p0_v4s64:
+; SSE:       # %bb.0: # %entry
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: inttoptr_v4p0_v4s64:
+; AVX:       # %bb.0: # %entry
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: inttoptr_v4p0_v4s64:
+; AVX512:       # %bb.0: # %entry
+; AVX512-NEXT:    retq
+entry:
+  %0 = inttoptr <4 x i64> %val to <4 x ptr>
+  ret <4 x ptr> %0
+}
+
+define <8 x ptr> @inttoptr_v8p0_v8s64(<8 x i64> %val) {
+; NO-SSE-LABEL: inttoptr_v8p0_v8s64:
+; NO-SSE:       # %bb.0: # %entry
+; NO-SSE-NEXT:    movq %rdi, %rax
+; NO-SSE-NEXT:    movq {{[0-9]+}}(%rsp), %rdi
+; NO-SSE-NEXT:    movq {{[0-9]+}}(%rsp), %r10
+; NO-SSE-NEXT:    movq {{[0-9]+}}(%rsp), %r11
+; NO-SSE-NEXT:    movq %rsi, (%rax)
+; NO-SSE-NEXT:    movq %rdx, 8(%rax)
+; NO-SSE-NEXT:    movq %rcx, 16(%rax)
+; NO-SSE-NEXT:    movq %r8, 24(%rax)
+; NO-SSE-NEXT:    movq %r9, 32(%rax)
+; NO-SSE-NEXT:    movq %rdi, 40(%rax)
+; NO-SSE-NEXT:    movq %r10, 48(%rax)
+; NO-SSE-NEXT:    movq %r11, 56(%rax)
+; NO-SSE-NEXT:    retq
+;
+; SSE-LABEL: inttoptr_v8p0_v8s64:
+; SSE:       # %bb.0: # %entry
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: inttoptr_v8p0_v8s64:
+; AVX:       # %bb.0: # %entry
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: inttoptr_v8p0_v8s64:
+; AVX512:       # %bb.0: # %entry
+; AVX512-NEXT:    retq
+entry:
+  %0 = inttoptr <8 x i64> %val to <8 x ptr>
+  ret <8 x ptr> %0
+}
diff --git a/llvm/test/CodeGen/X86/GlobalISel/ptrtoint.ll b/llvm/test/CodeGen/X86/GlobalISel/ptrtoint.ll
deleted file mode 100644
index 01b4360087702..0000000000000
--- a/llvm/test/CodeGen/X86/GlobalISel/ptrtoint.ll
+++ /dev/null
@@ -1,56 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=CHECK
-
-define i1 @ptrtoint_s1_p0(ptr %p) {
-; CHECK-LABEL: ptrtoint_s1_p0:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    movq %rdi, %rax
-; CHECK-NEXT:    # kill: def $al killed $al killed $rax
-; CHECK-NEXT:    retq
-entry:
-  %0 = ptrtoint ptr %p to i1
-  ret i1 %0
-}
-
-define i8 @ptrtoint_s8_p0(ptr %p) {
-; CHECK-LABEL: ptrtoint_s8_p0:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    movq %rdi, %rax
-; CHECK-NEXT:    # kill: def $al killed $al killed $rax
-; CHECK-NEXT:    retq
-entry:
-  %0 = ptrtoint ptr %p to i8
-  ret i8 %0
-}
-
-define i16 @ptrtoint_s16_p0(ptr %p) {
-; CHECK-LABEL: ptrtoint_s16_p0:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    movq %rdi, %rax
-; CHECK-NEXT:    # kill: def $ax killed $ax killed $rax
-; CHECK-NEXT:    retq
-entry:
-  %0 = ptrtoint ptr %p to i16
-  ret i16 %0
-}
-
-define i32 @ptrtoint_s32_p0(ptr %p) {
-; CHECK-LABEL: ptrtoint_s32_p0:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    movq %rdi, %rax
-; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
-; CHECK-NEXT:    retq
-entry:
-  %0 = ptrtoint ptr %p to i32
-  ret i32 %0
-}
-
-define i64 @ptrtoint_s64_p0(ptr %p) {
-; CHECK-LABEL: ptrtoint_s64_p0:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    movq %rdi, %rax
-; CHECK-NEXT:    retq
-entry:
-  %0 = ptrtoint ptr %p to i64
-  ret i64 %0
-}
diff --git a/llvm/test/CodeGen/X86/GlobalISel/ptrtoint_32.ll b/llvm/test/CodeGen/X86/GlobalISel/ptrtoint_32.ll
new file mode 100644
index 0000000000000..9053ada99ff45
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/ptrtoint_32.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=i386-linux-gnu -global-isel -mattr=-sse2    -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=SCALAR
+; RUN: llc -mtriple=i386-linux-gnu -global-isel                 -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=SCALAR
+; RUN: llc -mtriple=i386-linux-gnu -global-isel -mattr=+avx     -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=SCALAR
+; RUN: llc -mtriple=i386-linux-gnu -global-isel -mattr=+avx512f -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=SCALAR
+
+define i1 @ptrtoint_s1_p0(ptr %p) {
+; SCALAR-LABEL: ptrtoint_s1_p0:
+; SCALAR:       # %bb.0: # %entry
+; SCALAR-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SCALAR-NEXT:    # kill: def $al killed $al killed $eax
+; SCALAR-NEXT:    retl
+entry:
+  %0 = ptrtoint ptr %p to i1
+  ret i1 %0
+}
+
+define i8 @ptrtoint_s8_p0(ptr %p) {
+; SCALAR-LABEL: ptrtoint_s8_p0:
+; SCALAR:       # %bb.0: # %entry
+; SCALAR-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SCALAR-NEXT:    # kill: def $al killed $al killed $eax
+; SCALAR-NEXT:    retl
+entry:
+  %0 = ptrtoint ptr %p to i8
+  ret i8 %0
+}
+
+define i16 @ptrtoint_s16_p0(ptr %p) {
+; SCALAR-LABEL: ptrtoint_s16_p0:
+; SCALAR:       # %bb.0: # %entry
+; SCALAR-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SCALAR-NEXT:    # kill: def $ax killed $ax killed $eax
+; SCALAR-NEXT:    retl
+entry:
+  %0 = ptrtoint ptr %p to i16
+  ret i16 %0
+}
+
+define i32 @ptrtoint_s32_p0(ptr %p) {
+; SCALAR-LABEL: ptrtoint_s32_p0:
+; SCALAR:       # %bb.0: # %entry
+; SCALAR-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SCALAR-NEXT:    retl
+entry:
+  %0 = ptrtoint ptr %p to i32
+  ret i32 %0
+}
diff --git a/llvm/test/CodeGen/X86/GlobalISel/ptrtoint_64.ll b/llvm/test/CodeGen/X86/GlobalISel/ptrtoint_64.ll
new file mode 100644
index 0000000000000..c55195124c5e5
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/ptrtoint_64.ll
@@ -0,0 +1,166 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -mattr=-sse2    -verify-machineinstrs < %s -o - | FileCheck %s --check-prefixes=SCALAR,NO-SSE
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel                 -verify-machineinstrs < %s -o - | FileCheck %s --check-prefixes=SCALAR,SSE
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -mattr=+avx     -verify-machineinstrs < %s -o - | FileCheck %s --check-prefixes=SCALAR,AVX
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -mattr=+avx512f -verify-machineinstrs < %s -o - | FileCheck %s --check-prefixes=SCALAR,AVX512
+
+define i1 @ptrtoint_s1_p0(ptr %p) {
+; SCALAR-LABEL: ptrtoint_s1_p0:
+; SCALAR:       # %bb.0: # %entry
+; SCALAR-NEXT:    movq %rdi, %rax
+; SCALAR-NEXT:    # kill: def $al killed $al killed $rax
+; SCALAR-NEXT:    retq
+entry:
+  %0 = ptrtoint ptr %p to i1
+  ret i1 %0
+}
+
+define i8 @ptrtoint_s8_p0(ptr %p) {
+; SCALAR-LABEL: ptrtoint_s8_p0:
+; SCALAR:       # %bb.0: # %entry
+; SCALAR-NEXT:    movq %rdi, %rax
+; SCALAR-NEXT:    # kill: def $al killed $al killed $rax
+; SCALAR-NEXT:    retq
+entry:
+  %0 = ptrtoint ptr %p to i8
+  ret i8 %0
+}
+
+define i16 @ptrtoint_s16_p0(ptr %p) {
+; SCALAR-LABEL: ptrtoint_s16_p0:
+; SCALAR:       # %bb.0: # %entry
+; SCALAR-NEXT:    movq %rdi, %rax
+; SCALAR-NEXT:    # kill: def $ax killed $ax killed $rax
+; SCALAR-NEXT:    retq
+entry:
+  %0 = ptrtoint ptr %p to i16
+  ret i16 %0
+}
+
+define i32 @ptrtoint_s32_p0(ptr %p) {
+; SCALAR-LABEL: ptrtoint_s32_p0:
+; SCALAR:       # %bb.0: # %entry
+; SCALAR-NEXT:    movq %rdi, %rax
+; SCALAR-NEXT:    # kill: def $eax killed $eax killed $rax
+; SCALAR-NEXT:    retq
+entry:
+  %0 = ptrtoint ptr %p to i32
+  ret i32 %0
+}
+
+define i64 @ptrtoint_s64_p0(ptr %p) {
+; SCALAR-LABEL: ptrtoint_s64_p0:
+; SCALAR:       # %bb.0: # %entry
+; SCALAR-NEXT:    movq %rdi, %rax
+; SCALAR-NEXT:    retq
+entry:
+  %0 = ptrtoint ptr %p to i64
+  ret i64 %0
+}
+
+define <2 x i1> @ptrtoint_v2s1_v2p0(<2 x ptr> %p) {
+; NO-SSE-LABEL: ptrtoint_v2s1_v2p0:
+; NO-SSE:       # %bb.0: # %entry
+; NO-SSE-NEXT:    movq %rdi, %rax
+; NO-SSE-NEXT:    movq %rsi, %rdx
+; NO-SSE-NEXT:    # kill: def $al killed $al killed $rax
+; NO-SSE-NEXT:    # kill: def $dl killed $dl killed $rdx
+; NO-SSE-NEXT:    retq
+;
+; SSE-LABEL: ptrtoint_v2s1_v2p0:
+; SSE:       # %bb.0: # %entry
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: ptrtoint_v2s1_v2p0:
+; AVX:       # %bb.0: # %entry
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: ptrtoint_v2s1_v2p0:
+; AVX512:       # %bb.0: # %entry
+; AVX512-NEXT:    retq
+entry:
+  %0 = ptrtoint <2 x ptr> %p to <2 x i1>
+  ret <2 x i1> %0
+}
+
+define <2 x i64> @ptrtoint_v2s64_v2p0(<2 x ptr> %p) {
+; NO-SSE-LABEL: ptrtoint_v2s64_v2p0:
+; NO-SSE:       # %bb.0: # %entry
+; NO-SSE-NEXT:    movq %rdi, %rax
+; NO-SSE-NEXT:    movq %rsi, %rdx
+; NO-SSE-NEXT:    retq
+;
+; SSE-LABEL: ptrtoint_v2s64_v2p0:
+; SSE:       # %bb.0: # %entry
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: ptrtoint_v2s64_v2p0:
+; AVX:       # %bb.0: # %entry
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: ptrtoint_v2s64_v2p0:
+; AVX512:       # %bb.0: # %entry
+; AVX512-NEXT:    retq
+entry:
+  %0 = ptrtoint <2 x ptr> %p to <2 x i64>
+  ret <2 x i64> %0
+}
+
+define <4 x i64> @ptrtoint_v4s64_v4p0(<4 x ptr> %p) {
+; NO-SSE-LABEL: ptrtoint_v4s64_v4p0:
+; NO-SSE:       # %bb.0: # %entry
+; NO-SSE-NEXT:    movq %rdi, %rax
+; NO-SSE-NEXT:    movq %rsi, (%rdi)
+; NO-SSE-NEXT:    movq %rdx, 8(%rdi)
+; NO-SSE-NEXT:    movq %rcx, 16(%rdi)
+; NO-SSE-NEXT:    movq %r8, 24(%rdi)
+; NO-SSE-NEXT:    retq
+;
+; SSE-LABEL: ptrtoint_v4s64_v4p0:
+; SSE:       # %bb.0: # %entry
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: ptrtoint_v4s64_v4p0:
+; AVX:       # %bb.0: # %entry
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: ptrtoint_v4s64_v4p0:
+; AVX512:       # %bb.0: # %entry
+; AVX512-NEXT:    retq
+entry:
+  %0 = ptrtoint <4 x ptr> %p to <4 x i64>
+  ret <4 x i64> %0
+}
+
+define <8 x i64> @ptrtoint_v8s64_v8p0(<8 x ptr> %p) {
+; NO-SSE-LABEL: ptrtoint_v8s64_v8p0:
+; NO-SSE:       # %bb.0: # %entry
+; NO-SSE-NEXT:    movq %rdi, %rax
+; NO-SSE-NEXT:    movq {{[0-9]+}}(%rsp), %rdi
+; NO-SSE-NEXT:    movq {{[0-9]+}}(%rsp), %r10
+; NO-SSE-NEXT:    movq {{[0-9]+}}(%rsp), %r11
+; NO-SSE-NEXT:    movq %rsi, (%rax)
+; NO-SSE-NEXT:    movq %rdx, 8(%rax)
+; NO-SSE-NEXT:    movq %rcx, 16(%rax)
+; NO-SSE-NEXT:    movq %r8, 24(%rax)
+; NO-SSE-NEXT:    movq %r9, 32(%rax)
+; NO-SSE-NEXT:    movq %rdi, 40(%rax)
+; NO-SSE-NEXT:    movq %r10, 48(%rax)
+; NO-SSE-NEXT:    movq %r11, 56(%rax)
+; NO-SSE-NEXT:    retq
+;
+; SSE-LABEL: ptrtoint_v8s64_v8p0:
+; SSE:       # %bb.0: # %entry
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: ptrtoint_v8s64_v8p0:
+; AVX:       # %bb.0: # %entry
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: ptrtoint_v8s64_v8p0:
+; AVX512:       # %bb.0: # %entry
+; AVX512-NEXT:    retq
+entry:
+  %0 = ptrtoint <8 x ptr> %p to <8 x i64>
+  ret <8 x i64> %0
+}

>From 86f065fc1e8461b2fd36e5ee3c8b54620337ad10 Mon Sep 17 00:00:00 2001
From: Yohay <yohay.ailon.tevet at gmail.com>
Date: Fri, 9 Jan 2026 23:15:08 +0200
Subject: [PATCH 2/3] Fixed bug that did not allow lowering function with a
 vector of pointers argument.

---
 llvm/lib/CodeGen/GlobalISel/CallLowering.cpp  | 2 +-
 llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
index 4256e9a42b889..be1d580c1978b 100644
--- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -228,7 +228,7 @@ void CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx,
   const AttributeList &Attrs = FuncInfo.getAttributes();
   addArgFlagsFromAttributes(Flags, Attrs, OpIdx);
 
-  PointerType *PtrTy = dyn_cast<PointerType>(Arg.Ty->getScalarType());
+  PointerType *PtrTy = dyn_cast<PointerType>(Arg.Ty);
   if (PtrTy) {
     Flags.setPointer();
     Flags.setPointerAddrSpace(PtrTy->getPointerAddressSpace());
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp
index 5c6affdae0c5b..ba8b40d133ebb 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp
@@ -430,9 +430,10 @@ void AMDGPUCallLowering::lowerParameter(MachineIRBuilder &B, ArgInfo &OrigArg,
     lowerParameterPtr(PtrReg, B, Offset + FieldOffsets[Idx]);
 
     LLT ArgTy = getLLTForType(*SplitArg.Ty, DL);
-    if (SplitArg.Flags[0].isPointer()) {
+    PointerType *OrigPtrTy = dyn_cast<PointerType>(OrigArg.Ty->getScalarType());
+    if (OrigPtrTy) {
       // Compensate for losing pointeriness in splitValueTypes.
-      LLT PtrTy = LLT::pointer(SplitArg.Flags[0].getPointerAddrSpace(),
+      LLT PtrTy = LLT::pointer(OrigPtrTy->getPointerAddressSpace(),
                                ArgTy.getScalarSizeInBits());
       ArgTy = ArgTy.isVector() ? LLT::vector(ArgTy.getElementCount(), PtrTy)
                                : PtrTy;

>From 7b16a505273797a13f0008a8992ded7da9400680 Mon Sep 17 00:00:00 2001
From: Yohay <yohay.ailon.tevet at gmail.com>
Date: Fri, 9 Jan 2026 23:35:28 +0200
Subject: [PATCH 3/3] Added support for vector ptrtoint and inttoptr for X86
 GlobalISel.

---
 .../X86/GISel/X86InstructionSelector.cpp      |  6 +++
 .../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 49 ++++++++++++++++---
 2 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
index bbc7f464eda4a..b99d6bdff9f37 100644
--- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
@@ -451,6 +451,7 @@ bool X86InstructionSelector::select(MachineInstr &I) {
   case TargetOpcode::G_PTRTOINT:
   case TargetOpcode::G_TRUNC:
     return selectTruncOrPtrToInt(I, MRI, MF);
+  case TargetOpcode::G_BITCAST:
   case TargetOpcode::G_INTTOPTR:
   case TargetOpcode::G_FREEZE:
     return selectCopy(I, MRI);
@@ -897,6 +898,11 @@ bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &I,
   if (canTurnIntoCOPY(DstRC, SrcRC))
     return selectTurnIntoCOPY(I, MRI, DstReg, DstRC, SrcReg, SrcRC);
 
+  // If the source and the destination are vectors, this is a ptrtoint of
+  // vectors to vectors, just replace it with a copy.
+  if (DstRB.getID() == X86::VECRRegBankID)
+    return selectTurnIntoCOPY(I, MRI, DstReg, DstRC, SrcReg, SrcRC);
+
   if (DstRB.getID() != X86::GPRRegBankID)
     return false;
 
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index fff9edb63b8ae..36217e36a33b2 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -13,16 +13,20 @@
 #include "X86LegalizerInfo.h"
 #include "X86Subtarget.h"
 #include "X86TargetMachine.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicsX86.h"
 #include "llvm/IR/Type.h"
+#include "llvm/Support/Debug.h"
 
 using namespace llvm;
 using namespace TargetOpcode;
@@ -77,6 +81,9 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
   const LLT v32s16 = LLT::fixed_vector(32, 16);
   const LLT v16s32 = LLT::fixed_vector(16, 32);
   const LLT v8s64 = LLT::fixed_vector(8, 64);
+  const LLT v8p0 = LLT::fixed_vector(8, p0);
+
+  const LLT v16p0 = LLT::fixed_vector(16, p0);
 
   const LLT s8MaxVector = HasAVX512 ? v64s8 : HasAVX ? v32s8 : v16s8;
   const LLT s16MaxVector = HasAVX512 ? v32s16 : HasAVX ? v16s16 : v8s16;
@@ -318,16 +325,42 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
 
   getActionDefinitionsBuilder(G_BRCOND).legalFor({s1});
 
-  // pointer handling
-  const std::initializer_list<LLT> PtrTypes32 = {s1, s8, s16, s32};
-  const std::initializer_list<LLT> PtrTypes64 = {s1, s8, s16, s32, s64};
-
   getActionDefinitionsBuilder(G_PTRTOINT)
-      .legalForCartesianProduct(Is64Bit ? PtrTypes64 : PtrTypes32, {p0})
-      .maxScalar(0, sMaxScalar)
-      .widenScalarToNextPow2(0, /*Min*/ 8);
+      .legalFor({p0, sMaxScalar})
+      .legalFor(HasSSE2, {{Is64Bit ? v2s64 : v2s32, v2p0}})
+      .legalFor(HasSSE2 && !Is64Bit, {{v4s32, v4p0}})
+      .legalFor(HasAVX, {{Is64Bit ? v4s64 : v8s32, Is64Bit ? v4p0 : v8p0}})
+      .legalFor(HasAVX512, {{Is64Bit ? v8s64 : v16s32, Is64Bit ? v8p0 : v16p0}})
+      .clampScalarOrElt(0, sMaxScalar, sMaxScalar)
+      .clampMaxNumElements(1, p0, Is64Bit ? s64MaxVector.getNumElements() : s32MaxVector.getNumElements())
+      .scalarize(0);
 
-  getActionDefinitionsBuilder(G_INTTOPTR).legalFor({{p0, sMaxScalar}});
+  getActionDefinitionsBuilder(G_INTTOPTR)
+      .legalFor({{p0, sMaxScalar}})
+      .legalFor(HasSSE2, {{v2p0, Is64Bit ? v2s64 : v2s32}})
+      .legalFor(HasSSE2 && !Is64Bit, {{v4p0, v4s32}})
+      .legalFor(HasAVX, {{Is64Bit ? v4p0 : v8p0, Is64Bit ? v4s64 : v8s32}})
+      .legalFor(HasAVX512, {{Is64Bit ? v8p0 : v16p0, Is64Bit ? v8s64 : v16s32}})
+      .clampMaxNumElements(0, p0,
+                           Is64Bit ? s64MaxVector.getNumElements()
+                                   : s32MaxVector.getNumElements())
+      .scalarize(0);
+
+  getActionDefinitionsBuilder(G_BITCAST)
+      .legalFor({{p0, sMaxScalar}})
+      .legalIf([=](const LegalityQuery &Query) -> bool {
+        auto SSE2Types = {Is64Bit ? v2p0 : v4p0, v2s64, v4s32, v8s16, v16s8};
+        auto AVXTypes = {Is64Bit ? v4p0 : v8p0, v4s64, v8s32, v16s16, v32s8};
+        auto AVX512Types = {Is64Bit ? v8p0 : v16p0, v8s64, v16s32, v32s16,
+                            v64s8};
+        if (HasSSE2 && typeInSet(0, SSE2Types) && typeInSet(1, SSE2Types))
+          return true;
+        if (HasAVX && typeInSet(0, AVXTypes) && typeInSet(1, AVXTypes))
+          return true;
+        if (HasAVX512 && typeInSet(0, AVX512Types) && typeInSet(1, AVX512Types))
+          return true;
+        return false;
+      });
 
   getActionDefinitionsBuilder(G_CONSTANT_POOL).legalFor({p0});
 



More information about the llvm-commits mailing list