[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