[clang] [CIR][AArch64] Implement vqshrun_n NEON builtin (PR #195080)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 30 06:12:37 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: IAmCheese1231
<details>
<summary>Changes</summary>
This patch adds CIR lowering support for the AArch64 NEON builtin vqsrhun. Carries over most changes from original PR, plus addresses the feedback. The builtin is lowers to the corresponding LLVM intrinsic using emitNeonCall.
Important tests:
- correctly constructs the wide input vector type
- handles vector width
- it bitcasts CIR values to match intrinsic expectations
- uses the proper argument types
Changes:
- added vqshrun.c in clang/test/CodeGen/AArch64/neon/
- verified IR and CIR lowering matches
- updated with existing test patterns (target guards, run lines, filecheck usage)
---
Full diff: https://github.com/llvm/llvm-project/pull/195080.diff
2 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp (+26-1)
- (added) clang/test/CodeGen/AArch64/neon/vqshrun.c (+40)
``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
index 834f66586833b..9717843c223b3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
@@ -2594,7 +2594,32 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr,
case NEON::BI__builtin_neon_vrecpss_f32:
case NEON::BI__builtin_neon_vrecpsd_f64:
case NEON::BI__builtin_neon_vrecpsh_f16:
- case NEON::BI__builtin_neon_vqshrun_n_v:
+ case NEON::BI__builtin_neon_vqshrun_n_v: {
+ mlir::Type inputTy;
+
+ switch (type.getEltType()) {
+ case NeonTypeFlags::Int8:
+ inputTy = getNeonType(
+ this, NeonTypeFlags(NeonTypeFlags::Int16, false, true), loc);
+ break;
+ case NeonTypeFlags::Int16:
+ inputTy = getNeonType(
+ this, NeonTypeFlags(NeonTypeFlags::Int32, false, true), loc);
+ break;
+ case NeonTypeFlags::Int32:
+ inputTy = getNeonType(
+ this, NeonTypeFlags(NeonTypeFlags::Int64, false, true), loc);
+ break;
+ default:
+ llvm_unreachable("unexpected vqshrun element type");
+ }
+
+ auto shiftTy = ops[1].getType();
+ ops[0] = builder.createBitcast(loc, ops[0], inputTy);
+
+ intrName = "aarch64.neon.sqshrun";
+ return emitNeonCall(cgm, builder, {inputTy, shiftTy}, ops, intrName, ty, loc);
+ }
case NEON::BI__builtin_neon_vqrshrun_n_v:
case NEON::BI__builtin_neon_vqshrn_n_v:
case NEON::BI__builtin_neon_vrshrn_n_v:
diff --git a/clang/test/CodeGen/AArch64/neon/vqshrun.c b/clang/test/CodeGen/AArch64/neon/vqshrun.c
new file mode 100644
index 0000000000000..04cb61df1987e
--- /dev/null
+++ b/clang/test/CodeGen/AArch64/neon/vqshrun.c
@@ -0,0 +1,40 @@
+// REQUIRES: aarch64-registered-target || arm-registered-target
+
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -disable-O0-optnone -flax-vector-conversions=none -emit-llvm -o - %s | opt -S -passes=mem2reg,sroa,simplifycfg | FileCheck %s --check-prefixes=LLVM
+// RUN: %if cir-enabled %{%clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -disable-O0-optnone -flax-vector-conversions=none -fclangir -emit-llvm -o - %s | opt -S -passes=mem2reg,sroa,simplifycfg | FileCheck %s --check-prefixes=LLVM %}
+// RUN: %if cir-enabled %{%clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -disable-O0-optnone -flax-vector-conversions=none -fclangir -emit-cir -o - %s | FileCheck %s --check-prefixes=CIR %}
+
+#include <arm_neon.h>
+
+// LLVM-LABEL: @test_vqshrun_n_s16(
+// CIR-LABEL: @test_vqshrun_n_s16(
+uint8x8_t test_vqshrun_n_s16(int16x8_t a) {
+// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqshrun" {{.*}} : (!cir.vector<8 x !s16i>, !s32i) -> !cir.vector<8 x !u8i>
+
+// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]]) {{.*}} {
+// LLVM: [[R:%.*]] = call <8 x i8> @llvm.aarch64.neon.sqshrun.v8i8(<8 x i16> {{.*}}, i32 3)
+// LLVM-NEXT: ret <8 x i8> [[R]]
+ return vqshrun_n_s16(a, 3);
+}
+
+// LLVM-LABEL: @test_vqshrun_n_s32(
+// CIR-LABEL: @test_vqshrun_n_s32(
+uint16x4_t test_vqshrun_n_s32(int32x4_t a) {
+// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqshrun" {{.*}} : (!cir.vector<4 x !s32i>, !s32i) -> !cir.vector<4 x !u16i>
+
+// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]]) {{.*}} {
+// LLVM: [[R:%.*]] = call <4 x i16> @llvm.aarch64.neon.sqshrun.v4i16(<4 x i32> {{.*}}, i32 9)
+// LLVM-NEXT: ret <4 x i16> [[R]]
+ return vqshrun_n_s32(a, 9);
+}
+
+// LLVM-LABEL: @test_vqshrun_n_s64(
+// CIR-LABEL: @test_vqshrun_n_s64(
+uint32x2_t test_vqshrun_n_s64(int64x2_t a) {
+// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqshrun" {{.*}} : (!cir.vector<2 x !s64i>, !s32i) -> !cir.vector<2 x !u32i>
+
+// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]]) {{.*}} {
+// LLVM: [[R:%.*]] = call <2 x i32> @llvm.aarch64.neon.sqshrun.v2i32(<2 x i64> {{.*}}, i32 19)
+// LLVM-NEXT: ret <2 x i32> [[R]]
+ return vqshrun_n_s64(a, 19);
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/195080
More information about the cfe-commits
mailing list