Skip to content

[CIR][AArch64] Migrate vmovl_high_* NEON tests to widen.c - #217950

Open
E00N777 wants to merge 1 commit into
llvm:mainfrom
E00N777:feat/migrate_vmovl_high_tests
Open

[CIR][AArch64] Migrate vmovl_high_* NEON tests to widen.c#217950
E00N777 wants to merge 1 commit into
llvm:mainfrom
E00N777:feat/migrate_vmovl_high_tests

Conversation

@E00N777

@E00N777 E00N777 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

summary

Part of : #185382

This is a light patch and a follow up of :
#205508

All lowering logic have been implemented in this PR : #204285 , I just need to migrate these intrinsics.

Migrate the 6 test_vmovl_high_{s,u}{8,16,32} tests from neon-intrinsics.c to widen.c with LLVM + CIR checks, and drop the now-stale TODO in widen.c.

This PR completed with the assistance of DeepSeek

@E00N777
E00N777 requested a review from banach-space August 21, 2026 15:39
@E00N777 E00N777 assigned E00N777 and unassigned E00N777 Aug 21, 2026
@llvmorg-github-actions llvmorg-github-actions Bot added the clang Clang issues not falling into any other category label Aug 21, 2026
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-clang

Author: Jiahao Guo (E00N777)

Changes

summary

Part of : #185382

This is a light patch and a follow up of :
#205508

All lowering logic have been implemented in this PR : #204285 , I just need to migrate these intrinsics.

Migrate the 6 test_vmovl_high_{s,u}{8,16,32} tests from neon-intrinsics.c to widen.c with LLVM + CIR checks, and drop the now-stale TODO in widen.c.

This PR completed with the assistance of DeepSeek


Full diff: https://github.com/llvm/llvm-project/pull/217950.diff

2 Files Affected:

  • (modified) clang/test/CodeGen/AArch64/neon-intrinsics.c (-74)
  • (modified) clang/test/CodeGen/AArch64/neon/widen.c (+97-2)
diff --git a/clang/test/CodeGen/AArch64/neon-intrinsics.c b/clang/test/CodeGen/AArch64/neon-intrinsics.c
index 883897a18cbf6..f2aa080aa86a6 100644
--- a/clang/test/CodeGen/AArch64/neon-intrinsics.c
+++ b/clang/test/CodeGen/AArch64/neon-intrinsics.c
@@ -4562,80 +4562,6 @@ uint32x4_t test_vqshrn_high_n_u64(uint32x2_t a, uint64x2_t b) {
 }
 
 
-// CHECK-LABEL: define dso_local <8 x i16> @test_vmovl_high_s8(
-// CHECK-SAME: <16 x i8> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[SHUFFLE_I_I:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> [[A]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK-NEXT:    [[TMP0:%.*]] = sext <8 x i8> [[SHUFFLE_I_I]] to <8 x i16>
-// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
-//
-int16x8_t test_vmovl_high_s8(int8x16_t a) {
-  return vmovl_high_s8(a);
-}
-
-// CHECK-LABEL: define dso_local <4 x i32> @test_vmovl_high_s16(
-// CHECK-SAME: <8 x i16> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[A]], <8 x i16> [[A]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i16> [[SHUFFLE_I_I]] to <8 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
-// CHECK-NEXT:    [[TMP2:%.*]] = sext <4 x i16> [[TMP1]] to <4 x i32>
-// CHECK-NEXT:    ret <4 x i32> [[TMP2]]
-//
-int32x4_t test_vmovl_high_s16(int16x8_t a) {
-  return vmovl_high_s16(a);
-}
-
-// CHECK-LABEL: define dso_local <2 x i64> @test_vmovl_high_s32(
-// CHECK-SAME: <4 x i32> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[A]], <4 x i32> [[A]], <2 x i32> <i32 2, i32 3>
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
-// CHECK-NEXT:    [[TMP2:%.*]] = sext <2 x i32> [[TMP1]] to <2 x i64>
-// CHECK-NEXT:    ret <2 x i64> [[TMP2]]
-//
-int64x2_t test_vmovl_high_s32(int32x4_t a) {
-  return vmovl_high_s32(a);
-}
-
-// CHECK-LABEL: define dso_local <8 x i16> @test_vmovl_high_u8(
-// CHECK-SAME: <16 x i8> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[SHUFFLE_I_I:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> [[A]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-// CHECK-NEXT:    [[TMP0:%.*]] = zext <8 x i8> [[SHUFFLE_I_I]] to <8 x i16>
-// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
-//
-uint16x8_t test_vmovl_high_u8(uint8x16_t a) {
-  return vmovl_high_u8(a);
-}
-
-// CHECK-LABEL: define dso_local <4 x i32> @test_vmovl_high_u16(
-// CHECK-SAME: <8 x i16> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[A]], <8 x i16> [[A]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i16> [[SHUFFLE_I_I]] to <8 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
-// CHECK-NEXT:    [[TMP2:%.*]] = zext <4 x i16> [[TMP1]] to <4 x i32>
-// CHECK-NEXT:    ret <4 x i32> [[TMP2]]
-//
-uint32x4_t test_vmovl_high_u16(uint16x8_t a) {
-  return vmovl_high_u16(a);
-}
-
-// CHECK-LABEL: define dso_local <2 x i64> @test_vmovl_high_u32(
-// CHECK-SAME: <4 x i32> noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[A]], <4 x i32> [[A]], <2 x i32> <i32 2, i32 3>
-// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8>
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
-// CHECK-NEXT:    [[TMP2:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
-// CHECK-NEXT:    ret <2 x i64> [[TMP2]]
-//
-uint64x2_t test_vmovl_high_u32(uint32x4_t a) {
-  return vmovl_high_u32(a);
-}
-
 // CHECK-LABEL: define dso_local <8 x i16> @test_vabdl_s8(
 // CHECK-SAME: <8 x i8> noundef [[A:%.*]], <8 x i8> noundef [[B:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
diff --git a/clang/test/CodeGen/AArch64/neon/widen.c b/clang/test/CodeGen/AArch64/neon/widen.c
index 327506a771328..1572543909135 100644
--- a/clang/test/CodeGen/AArch64/neon/widen.c
+++ b/clang/test/CodeGen/AArch64/neon/widen.c
@@ -12,8 +12,6 @@
 // ACLE section headings based on v2025Q2 of the ACLE specification:
 //  * https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#widen
 //
-// TODO: Migrate the vmovl_high_* intrinsics, which depend on 'Vector shift left and widen' that has not yet been implemented.
-//
 //=============================================================================
 
 #include <arm_neon.h>
@@ -96,3 +94,100 @@ uint64x2_t test_vmovl_u32(uint32x2_t a) {
 // LLVM: ret <2 x i64> [[VMOVL_I]]
   return vmovl_u32(a);
 }
+// LLVM-LABEL: @test_vmovl_high_s8(
+// CIR-LABEL: @vmovl_high_s8(
+int16x8_t test_vmovl_high_s8(int8x16_t a) {
+// CIR: cir.call @vget_high_s8
+// CIR: cir.cast integral {{%.*}} : !cir.vector<8 x !s8i> -> !cir.vector<8 x !s16i>
+// CIR: cir.shift(left, %{{.*}} : !cir.vector<8 x !s16i>, %{{.*}} : !cir.vector<8 x !s16i>) -> !cir.vector<8 x !s16i>
+
+// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]])
+// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> [[A]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+// LLVM: [[VMOVL_I:%.*]] = sext <8 x i8> [[SHUFFLE_I]] to <8 x i16>
+// LLVM: ret <8 x i16> [[VMOVL_I]]
+  return vmovl_high_s8(a);
+}
+
+// LLVM-LABEL: @test_vmovl_high_s16(
+// CIR-LABEL: @vmovl_high_s16(
+int32x4_t test_vmovl_high_s16(int16x8_t a) {
+// CIR: cir.call @vget_high_s16
+// CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !s16i>
+// CIR: cir.cast integral %{{.*}} : !cir.vector<4 x !s16i> -> !cir.vector<4 x !s32i>
+// CIR: cir.shift(left, %{{.*}} : !cir.vector<4 x !s32i>, %{{.*}} : !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
+
+// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]])
+// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <8 x i16> [[A]], <8 x i16> [[A]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to <8 x i8>
+// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
+// LLVM: [[VMOVL_I:%.*]] = sext <4 x i16> [[TMP1]] to <4 x i32>
+// LLVM: ret <4 x i32> [[VMOVL_I]]
+  return vmovl_high_s16(a);
+}
+
+// LLVM-LABEL: @test_vmovl_high_s32(
+// CIR-LABEL: @vmovl_high_s32(
+int64x2_t test_vmovl_high_s32(int32x4_t a) {
+// CIR: cir.call @vget_high_s32
+// CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !s32i>
+// CIR: cir.cast integral %{{.*}} : !cir.vector<2 x !s32i> -> !cir.vector<2 x !s64i>
+// CIR: cir.shift(left, %{{.*}} : !cir.vector<2 x !s64i>, %{{.*}} : !cir.vector<2 x !s64i>) -> !cir.vector<2 x !s64i>
+
+// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
+// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <4 x i32> [[A]], <4 x i32> [[A]], <2 x i32> <i32 2, i32 3>
+// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to <8 x i8>
+// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
+// LLVM: [[VMOVL_I:%.*]] = sext <2 x i32> [[TMP1]] to <2 x i64>
+// LLVM: ret <2 x i64> [[VMOVL_I]]
+  return vmovl_high_s32(a);
+}
+
+// LLVM-LABEL: @test_vmovl_high_u8(
+// CIR-LABEL: @vmovl_high_u8(
+uint16x8_t test_vmovl_high_u8(uint8x16_t a) {
+// CIR: cir.call @vget_high_u8
+// CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<8 x !u8i>
+// CIR: cir.cast integral %{{.*}} : !cir.vector<8 x !u8i> -> !cir.vector<8 x !u16i>
+// CIR: cir.shift(left, %{{.*}} : !cir.vector<8 x !u16i>, %{{.*}} : !cir.vector<8 x !u16i>) -> !cir.vector<8 x !u16i>
+
+// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]])
+// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> [[A]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+// LLVM: [[VMOVL_I:%.*]] = zext <8 x i8> [[SHUFFLE_I]] to <8 x i16>
+// LLVM: ret <8 x i16> [[VMOVL_I]]
+  return vmovl_high_u8(a);
+}
+
+// LLVM-LABEL: @test_vmovl_high_u16(
+// CIR-LABEL: @vmovl_high_u16(
+uint32x4_t test_vmovl_high_u16(uint16x8_t a) {
+// CIR: cir.call @vget_high_u16
+// CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !u16i>
+// CIR: cir.cast integral %{{.*}} : !cir.vector<4 x !u16i> -> !cir.vector<4 x !u32i>
+// CIR: cir.shift(left, %{{.*}} : !cir.vector<4 x !u32i>, %{{.*}} : !cir.vector<4 x !u32i>) -> !cir.vector<4 x !u32i>
+
+// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]])
+// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <8 x i16> [[A]], <8 x i16> [[A]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to <8 x i8>
+// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
+// LLVM: [[VMOVL_I:%.*]] = zext <4 x i16> [[TMP1]] to <4 x i32>
+// LLVM: ret <4 x i32> [[VMOVL_I]]
+  return vmovl_high_u16(a);
+}
+
+// LLVM-LABEL: @test_vmovl_high_u32(
+// CIR-LABEL: @vmovl_high_u32(
+uint64x2_t test_vmovl_high_u32(uint32x4_t a) {
+// CIR: cir.call @vget_high_u32
+// CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !u32i>
+// CIR: cir.cast integral %{{.*}} : !cir.vector<2 x !u32i> -> !cir.vector<2 x !u64i>
+// CIR: cir.shift(left, %{{.*}} : !cir.vector<2 x !u64i>, %{{.*}} : !cir.vector<2 x !u64i>) -> !cir.vector<2 x !u64i>
+
+// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
+// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <4 x i32> [[A]], <4 x i32> [[A]], <2 x i32> <i32 2, i32 3>
+// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to <8 x i8>
+// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
+// LLVM: [[VMOVL_I:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
+// LLVM: ret <2 x i64> [[VMOVL_I]]
+  return vmovl_high_u32(a);
+}
+

Part of : llvm#185382

This is a light patch and a follow up of :
llvm#205508

All lowering logic have been implemented in this PR :
llvm#204285 , I just need to
migrate these intrinsics.

Migrate the 6 test_vmovl_high_{s,u}{8,16,32} tests from
neon-intrinsics.c to widen.c with LLVM + CIR checks, and drop the
now-stale TODO in widen.c.

This PR completed with the assistance of DeepSeek
@E00N777
E00N777 force-pushed the feat/migrate_vmovl_high_tests branch from 798fb3d to ac88955 Compare August 22, 2026 06:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant