https://github.com/rafe-murray created https://github.com/llvm/llvm-project/pull/190310
This PR upstreams the following fp16 intrinsics as part of #185382: - vaddh_f16, - vsubh_f16, - vmulh_f16, - vdivh_f16 This is my first PR to LLVM, so any feedback is greatly appreciated! >From 878e98c1a5887e1d8ef0c0b552aff5e5a245bce2 Mon Sep 17 00:00:00 2001 From: Rafe Murray <[email protected]> Date: Thu, 12 Mar 2026 17:19:27 -0700 Subject: [PATCH] [CIR][Aarch64] upstream scalar & vector intrinsics (FP16) --- .../lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp | 16 ++++-- .../CodeGen/AArch64/neon/fp16_intrinsics.c | 57 +++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 clang/test/CodeGen/AArch64/neon/fp16_intrinsics.c diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index d9d303cd07b92..ce7b3fa9f9877 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -2122,14 +2122,22 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr, case NEON::BI__builtin_neon_vdups_laneq_f32: case NEON::BI__builtin_neon_vgetq_lane_f64: case NEON::BI__builtin_neon_vdupd_laneq_f64: - case NEON::BI__builtin_neon_vaddh_f16: - case NEON::BI__builtin_neon_vsubh_f16: - case NEON::BI__builtin_neon_vmulh_f16: - case NEON::BI__builtin_neon_vdivh_f16: cgm.errorNYI(expr->getSourceRange(), std::string("unimplemented AArch64 builtin call: ") + getContext().BuiltinInfo.getName(builtinID)); return mlir::Value{}; + case NEON::BI__builtin_neon_vaddh_f16: + ops.push_back(emitScalarExpr(expr->getArg(1))); + return builder.createFAdd(loc, ops[0], ops[1]); + case NEON::BI__builtin_neon_vsubh_f16: + ops.push_back(emitScalarExpr(expr->getArg(1))); + return builder.createFSub(loc, ops[0], ops[1]); + case NEON::BI__builtin_neon_vmulh_f16: + ops.push_back(emitScalarExpr(expr->getArg(1))); + return builder.createFMul(loc, ops[0], ops[1]); + case NEON::BI__builtin_neon_vdivh_f16: + ops.push_back(emitScalarExpr(expr->getArg(1))); + return builder.createFDiv(loc, ops[0], ops[1]); case NEON::BI__builtin_neon_vfmah_f16: // NEON intrinsic puts accumulator first, unlike the LLVM fma. std::rotate(ops.begin(), ops.begin() + 1, ops.end()); diff --git a/clang/test/CodeGen/AArch64/neon/fp16_intrinsics.c b/clang/test/CodeGen/AArch64/neon/fp16_intrinsics.c new file mode 100644 index 0000000000000..8077d914cce81 --- /dev/null +++ b/clang/test/CodeGen/AArch64/neon/fp16_intrinsics.c @@ -0,0 +1,57 @@ +#include <arm_fp16.h> +// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +fullfp16 \ +// RUN: -fclangir -disable-O0-optnone \ +// RUN: -flax-vector-conversions=none -emit-cir -o %t.cir %s +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s + +// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +fullfp16 \ +// RUN: -fclangir -disable-O0-optnone \ +// RUN: -flax-vector-conversions=none -emit-llvm -o - %s \ +// RUN: | opt -S -passes=mem2reg,simplifycfg -o %t.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s + +// REQUIRES: aarch64-registered-target || arm-registered-target + +// LLVM-LABEL: @test_vaddh_f16( +// CIR-LABEL: @test_vaddh_f16( +float16_t test_vaddh_f16(float16_t a, float16_t b) { +// CIR: {{%.*}} = cir.add {{%.*}}, {{%.*}} : !cir.f16 + +// LLVM-SAME: half {{.*}} [[A:%.*]], half{{.*}} [[B:%.*]]) #[[ATTR0:[0-9]+]] { +// LLVM: [[ADD:%.*]] = fadd half [[A]], [[B]] +// LLVM: ret half [[ADD]] + return vaddh_f16(a, b); +} + +// LLVM-LABEL: @test_vsubh_f16( +// CIR-LABEL: @test_vsubh_f16( +float16_t test_vsubh_f16(float16_t a, float16_t b) { +// CIR: {{%.*}} = cir.sub {{%.*}}, {{%.*}} : !cir.f16 + +// LLVM-SAME: half {{.*}} [[A:%.]], half {{.*}} [[B:%.]]) #[[ATTR0:[0-9]+]] { +// LLVM: [[SUB:%.*]] = fsub half [[A]], [[B]] +// LLVM: ret half [[SUB]] + return vsubh_f16(a, b); +} + +// LLVM-LABEL: @test_vmulh_f16( +// CIR-LABEL: @test_vmulh_f16( +float16_t test_vmulh_f16(float16_t a, float16_t b) { +// CIR: {{%.*}} = cir.mul {{%.*}}, {{%.*}} : !cir.f16 + +// LLVM-SAME: half {{.*}} [[A:%.]], half {{.*}} [[B:%.]]) #[[ATTR0:[0-9]+]] { +// LLVM: [[MUL:%.*]] = fmul half [[A]], [[B]] +// LLVM: ret half [[MUL]] + return vmulh_f16(a, b); +} + +// LLVM-LABEL: @test_vdivh_f16( +// CIR-LABEL: @test_vdivh_f16( +float16_t test_vdivh_f16(float16_t a, float16_t b) { +// CIR: {{%.*}} = cir.div {{%.*}}, {{%.*}} : !cir.f16 + +// LLVM-SAME: half {{.*}} [[A:%.]], half {{.*}} [[B:%.]]) #[[ATTR0:[0-9]+]] { +// LLVM: [[DIV:%.*]] = fdiv half [[A]], [[B]] +// LLVM: ret half [[DIV]] + return vdivh_f16(a, b); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
