[clang] [CIR][AArch64] Implement vget_lane_bf16 and vgetq_lane_bf16 builtins (PR #186866)

Jiří Filek via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 6 12:25:56 PDT 2026


https://github.com/fileho updated https://github.com/llvm/llvm-project/pull/186866

>From 7c71c6275b7bcacfcc3ca57daff222ec6f3d9dc2 Mon Sep 17 00:00:00 2001
From: Jiri Filek <jiri.filek at gmail.com>
Date: Mon, 16 Mar 2026 20:31:56 +0100
Subject: [PATCH 1/2] [CIR][AArch64] Implement vget_lane_bf16 and
 vgetq_lane_bf16 builtins

---
 .../lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp  | 19 +++++--------------
 .../CodeGen/AArch64/bf16-getset-intrinsics.c  | 18 ------------------
 clang/test/CodeGen/AArch64/neon/bf16-getset.c | 16 ++++++++++++++++
 3 files changed, 21 insertions(+), 32 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
index 3a9e7e2650500..d618ba2278f5a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
@@ -2209,26 +2209,17 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr,
   case NEON::BI__builtin_neon_vqdmlals_lane_s32:
   case NEON::BI__builtin_neon_vqdmlals_laneq_s32:
   case NEON::BI__builtin_neon_vqdmlsls_lane_s32:
-  case NEON::BI__builtin_neon_vqdmlsls_laneq_s32:
-  case NEON::BI__builtin_neon_vget_lane_bf16:
+  case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
     return mlir::Value{};
-  case NEON::BI__builtin_neon_vduph_lane_bf16: {
-    return cir::VecExtractOp::create(builder, loc, ops[0], ops[1]);
-  }
-  case NEON::BI__builtin_neon_vduph_lane_f16: {
-    return cir::VecExtractOp::create(builder, loc, ops[0], ops[1]);
   }
+  case NEON::BI__builtin_neon_vget_lane_bf16:
+  case NEON::BI__builtin_neon_vduph_lane_bf16:
+  case NEON::BI__builtin_neon_vduph_lane_f16:
   case NEON::BI__builtin_neon_vgetq_lane_bf16:
-    cgm.errorNYI(expr->getSourceRange(),
-                 std::string("unimplemented AArch64 builtin call: ") +
-                     getContext().BuiltinInfo.getName(builtinID));
-    return mlir::Value{};
-  case NEON::BI__builtin_neon_vduph_laneq_bf16: {
-    return cir::VecExtractOp::create(builder, loc, ops[0], ops[1]);
-  }
+  case NEON::BI__builtin_neon_vduph_laneq_bf16:
   case NEON::BI__builtin_neon_vduph_laneq_f16: {
     return cir::VecExtractOp::create(builder, loc, ops[0], ops[1]);
   }
diff --git a/clang/test/CodeGen/AArch64/bf16-getset-intrinsics.c b/clang/test/CodeGen/AArch64/bf16-getset-intrinsics.c
index 69171902c7e69..19819d0d6c8c8 100644
--- a/clang/test/CodeGen/AArch64/bf16-getset-intrinsics.c
+++ b/clang/test/CodeGen/AArch64/bf16-getset-intrinsics.c
@@ -41,24 +41,6 @@ bfloat16x4_t test_vget_low_bf16(bfloat16x8_t a) {
   return vget_low_bf16(a);
 }
 
-// CHECK-LABEL: @test_vget_lane_bf16(
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[VGET_LANE:%.*]] = extractelement <4 x bfloat> [[V:%.*]], i32 1
-// CHECK-NEXT:    ret bfloat [[VGET_LANE]]
-//
-bfloat16_t test_vget_lane_bf16(bfloat16x4_t v) {
-  return vget_lane_bf16(v, 1);
-}
-
-// CHECK-LABEL: @test_vgetq_lane_bf16(
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[VGETQ_LANE:%.*]] = extractelement <8 x bfloat> [[V:%.*]], i32 7
-// CHECK-NEXT:    ret bfloat [[VGETQ_LANE]]
-//
-bfloat16_t test_vgetq_lane_bf16(bfloat16x8_t v) {
-  return vgetq_lane_bf16(v, 7);
-}
-
 // CHECK-LABEL: @test_vset_lane_bf16(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[VSET_LANE:%.*]] = insertelement <4 x bfloat> [[V:%.*]], bfloat [[A:%.*]], i32 1
diff --git a/clang/test/CodeGen/AArch64/neon/bf16-getset.c b/clang/test/CodeGen/AArch64/neon/bf16-getset.c
index eeb9209fe97a5..563110c72ba21 100644
--- a/clang/test/CodeGen/AArch64/neon/bf16-getset.c
+++ b/clang/test/CodeGen/AArch64/neon/bf16-getset.c
@@ -120,3 +120,19 @@ bfloat16x8_t test_vdupq_laneq_bf16(bfloat16x8_t v) {
     // LLVM-NEXT: ret <8 x bfloat> [[VECINIT7_I]]
     return vdupq_n_bf16(v);
   }
+
+// ALL-LABEL: @test_vget_lane_bf16(
+bfloat16_t test_vget_lane_bf16(bfloat16x4_t v) {
+  // CIR: cir.vec.extract %{{.*}}[%{{.*}} : !s32i] : !cir.vector<4 x !cir.bf16>
+  // LLVM: [[VGET_LANE:%.*]] = extractelement <4 x bfloat> %{{.*}}, i32 1
+  // LLVM: ret bfloat [[VGET_LANE]]
+  return vget_lane_bf16(v, 1);
+}
+
+// ALL-LABEL: @test_vgetq_lane_bf16(
+bfloat16_t test_vgetq_lane_bf16(bfloat16x8_t v) {
+  // CIR: cir.vec.extract %{{.*}}[%{{.*}} : !s32i] : !cir.vector<8 x !cir.bf16>
+  // LLVM: [[VGETQ_LANE:%.*]] = extractelement <8 x bfloat> %{{.*}}, i32 7
+  // LLVM: ret bfloat [[VGETQ_LANE]]
+  return vgetq_lane_bf16(v, 7);
+}

>From 2379936c1272ba1b06324eed03bb6bd68add06aa Mon Sep 17 00:00:00 2001
From: Jiri Filek <jiri.filek at gmail.com>
Date: Sun, 29 Mar 2026 19:03:14 +0200
Subject: [PATCH 2/2] Add vget_high_bf16 and vget_lane_bf16 tests

---
 .../CodeGen/AArch64/bf16-getset-intrinsics.c  | 18 -----------
 clang/test/CodeGen/AArch64/neon/bf16-getset.c | 32 +++++++++++++++++--
 2 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/clang/test/CodeGen/AArch64/bf16-getset-intrinsics.c b/clang/test/CodeGen/AArch64/bf16-getset-intrinsics.c
index 19819d0d6c8c8..89b332d14d588 100644
--- a/clang/test/CodeGen/AArch64/bf16-getset-intrinsics.c
+++ b/clang/test/CodeGen/AArch64/bf16-getset-intrinsics.c
@@ -23,24 +23,6 @@ bfloat16x8_t test_vcombine_bf16(bfloat16x4_t low, bfloat16x4_t high) {
   return vcombine_bf16(low, high);
 }
 
-// CHECK-LABEL: @test_vget_high_bf16(
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[SHUFFLE_I:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> [[A]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
-// CHECK-NEXT:    ret <4 x bfloat> [[SHUFFLE_I]]
-//
-bfloat16x4_t test_vget_high_bf16(bfloat16x8_t a) {
-  return vget_high_bf16(a);
-}
-
-// CHECK-LABEL: @test_vget_low_bf16(
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[SHUFFLE_I:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> [[A]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
-// CHECK-NEXT:    ret <4 x bfloat> [[SHUFFLE_I]]
-//
-bfloat16x4_t test_vget_low_bf16(bfloat16x8_t a) {
-  return vget_low_bf16(a);
-}
-
 // CHECK-LABEL: @test_vset_lane_bf16(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[VSET_LANE:%.*]] = insertelement <4 x bfloat> [[V:%.*]], bfloat [[A:%.*]], i32 1
diff --git a/clang/test/CodeGen/AArch64/neon/bf16-getset.c b/clang/test/CodeGen/AArch64/neon/bf16-getset.c
index 563110c72ba21..f860bfb7e40aa 100644
--- a/clang/test/CodeGen/AArch64/neon/bf16-getset.c
+++ b/clang/test/CodeGen/AArch64/neon/bf16-getset.c
@@ -121,10 +121,36 @@ bfloat16x8_t test_vdupq_laneq_bf16(bfloat16x8_t v) {
     return vdupq_n_bf16(v);
   }
 
+//===------------------------------------------------------===//
+// 2.14.1.4 Split vectors
+//===------------------------------------------------------===//
+
+// ALL-LABEL: @test_vget_high_bf16(
+bfloat16x4_t test_vget_high_bf16(bfloat16x8_t a) {
+  // CIR: cir.call @vget_high_bf16({{%.*}}) : (!cir.vector<8 x !cir.bf16>
+
+  // LLVM-SAME: <8 x bfloat> {{.*}} [[A:%.*]])
+  // LLVM: [[SHUFFLE_I:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> [[A]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // LLVM: ret <4 x bfloat> [[SHUFFLE_I]]
+  return vget_high_bf16(a);
+}
+
+// ALL-LABEL: @test_vget_low_bf16(
+bfloat16x4_t test_vget_low_bf16(bfloat16x8_t a) {
+  // CIR: cir.call @vget_low_bf16({{%.*}}) : (!cir.vector<8 x !cir.bf16>
+
+  // LLVM-SAME: <8 x bfloat> {{.*}} [[A:%.*]])
+  // LLVM: [[SHUFFLE_I:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> [[A]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+  // LLVM: ret <4 x bfloat> [[SHUFFLE_I]]
+  return vget_low_bf16(a);
+}
+
 // ALL-LABEL: @test_vget_lane_bf16(
 bfloat16_t test_vget_lane_bf16(bfloat16x4_t v) {
   // CIR: cir.vec.extract %{{.*}}[%{{.*}} : !s32i] : !cir.vector<4 x !cir.bf16>
-  // LLVM: [[VGET_LANE:%.*]] = extractelement <4 x bfloat> %{{.*}}, i32 1
+
+  // LLVM-SAME: <4 x bfloat> {{.*}} [[V:%.*]])
+  // LLVM: [[VGET_LANE:%.*]] = extractelement <4 x bfloat> [[V]], i32 1
   // LLVM: ret bfloat [[VGET_LANE]]
   return vget_lane_bf16(v, 1);
 }
@@ -132,7 +158,9 @@ bfloat16_t test_vget_lane_bf16(bfloat16x4_t v) {
 // ALL-LABEL: @test_vgetq_lane_bf16(
 bfloat16_t test_vgetq_lane_bf16(bfloat16x8_t v) {
   // CIR: cir.vec.extract %{{.*}}[%{{.*}} : !s32i] : !cir.vector<8 x !cir.bf16>
-  // LLVM: [[VGETQ_LANE:%.*]] = extractelement <8 x bfloat> %{{.*}}, i32 7
+
+  // LLVM-SAME: <8 x bfloat> {{.*}} [[V:%.*]])
+  // LLVM: [[VGETQ_LANE:%.*]] = extractelement <8 x bfloat> [[V]], i32 7
   // LLVM: ret bfloat [[VGETQ_LANE]]
   return vgetq_lane_bf16(v, 7);
 }



More information about the cfe-commits mailing list