From c94eb1c59e68edadaa6091a9e7ee955ad5f6c21c Mon Sep 17 00:00:00 2001 From: Letu Ren Date: Sun, 16 Feb 2025 22:48:57 +0800 Subject: [PATCH 1/3] [CIR][CIRGen] handle __builtin_elementwise_acos --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 19 +++++++++++++++-- clang/lib/CIR/CodeGen/CIRGenFunction.h | 3 +++ clang/test/CIR/CodeGen/builtins-elementwise.c | 21 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index a5f899320a86..d5d92f7e3196 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -415,6 +415,20 @@ RValue CIRGenFunction::emitRotate(const CallExpr *E, bool IsRotateRight) { return RValue::get(r); } +template +RValue CIRGenFunction::emitBuiltinWithOneOverloadedType(const CallExpr *E, + llvm::StringRef Name) { + static_assert(N, "expect non-empty argument"); + mlir::Type cirTy = convertType(E->getArg(0)->getType()); + SmallVector Args; + for (unsigned I = 0; I < N; ++I) { + Args.push_back(emitScalarExpr(E->getArg(I))); + } + const auto call = builder.create( + getLoc(E->getExprLoc()), builder.getStringAttr(Name), cirTy, Args); + return RValue::get(call->getResult(0)); +} + static bool isMemBuiltinOutOfBoundPossible(const clang::Expr *sizeArg, const clang::Expr *dstSizeArg, clang::ASTContext &astContext, @@ -1356,8 +1370,9 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, mlir::Value result = call->getResult(0); return RValue::get(result); } - case Builtin::BI__builtin_elementwise_acos: - llvm_unreachable("BI__builtin_elementwise_acos NYI"); + case Builtin::BI__builtin_elementwise_acos: { + return emitBuiltinWithOneOverloadedType<1>(E, "acos"); + } case Builtin::BI__builtin_elementwise_asin: llvm_unreachable("BI__builtin_elementwise_asin NYI"); case Builtin::BI__builtin_elementwise_atan: diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index bbf1024951db..fa5cb9c08680 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -1403,6 +1403,9 @@ class CIRGenFunction : public CIRGenTypeCache { RValue emitBuiltinExpr(const clang::GlobalDecl GD, unsigned BuiltinID, const clang::CallExpr *E, ReturnValueSlot ReturnValue); RValue emitRotate(const CallExpr *E, bool IsRotateRight); + template + RValue emitBuiltinWithOneOverloadedType(const CallExpr *E, + llvm::StringRef Name); mlir::Value emitTargetBuiltinExpr(unsigned BuiltinID, const clang::CallExpr *E, ReturnValueSlot ReturnValue); diff --git a/clang/test/CIR/CodeGen/builtins-elementwise.c b/clang/test/CIR/CodeGen/builtins-elementwise.c index b790588605f4..80e238e0c445 100644 --- a/clang/test/CIR/CodeGen/builtins-elementwise.c +++ b/clang/test/CIR/CodeGen/builtins-elementwise.c @@ -36,3 +36,24 @@ void test_builtin_elementwise_abs(vint4 vi4, int i, float f, double d, // LLVM: {{%.*}} = call <4 x double> @llvm.fabs.v4f64(<4 x double> {{%.*}}) vd4 = __builtin_elementwise_abs(vd4); } + +void test_builtin_elementwise_acos(float f, double d, vfloat4 vf4, + vdouble4 vd4) { + // CIR-LABEL: test_builtin_elementwise_acos + // LLVM-LABEL: test_builtin_elementwise_acos + // CIR: {{%.*}} = cir.llvm.intrinsic "acos" {{%.*}} : (!cir.float) -> !cir.float + // LLVM: {{%.*}} = call float @llvm.acos.f32(float {{%.*}}) + f = __builtin_elementwise_acos(f); + + // CIR: {{%.*}} = cir.llvm.intrinsic "acos" {{%.*}} : (!cir.double) -> !cir.double + // LLVM: {{%.*}} = call double @llvm.acos.f64(double {{%.*}}) + d = __builtin_elementwise_acos(d); + + // CIR: {{%.*}} = cir.llvm.intrinsic "acos" {{%.*}} : (!cir.vector) -> !cir.vector + // LLVM: {{%.*}} = call <4 x float> @llvm.acos.v4f32(<4 x float> {{%.*}}) + vf4 = __builtin_elementwise_acos(vf4); + + // CIR: {{%.*}} = cir.llvm.intrinsic "acos" {{%.*}} : (!cir.vector) -> !cir.vector + // LLVM: {{%.*}} = call <4 x double> @llvm.acos.v4f64(<4 x double> {{%.*}}) + vd4 = __builtin_elementwise_acos(vd4); +} From f273f49a5a5b794914b56890c83a8dfb2a857748 Mon Sep 17 00:00:00 2001 From: Letu Ren Date: Mon, 17 Feb 2025 19:34:14 +0800 Subject: [PATCH 2/3] implement template function in header --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 14 -------------- clang/lib/CIR/CodeGen/CIRGenFunction.h | 12 +++++++++++- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index d5d92f7e3196..572ef5d6022c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -415,20 +415,6 @@ RValue CIRGenFunction::emitRotate(const CallExpr *E, bool IsRotateRight) { return RValue::get(r); } -template -RValue CIRGenFunction::emitBuiltinWithOneOverloadedType(const CallExpr *E, - llvm::StringRef Name) { - static_assert(N, "expect non-empty argument"); - mlir::Type cirTy = convertType(E->getArg(0)->getType()); - SmallVector Args; - for (unsigned I = 0; I < N; ++I) { - Args.push_back(emitScalarExpr(E->getArg(I))); - } - const auto call = builder.create( - getLoc(E->getExprLoc()), builder.getStringAttr(Name), cirTy, Args); - return RValue::get(call->getResult(0)); -} - static bool isMemBuiltinOutOfBoundPossible(const clang::Expr *sizeArg, const clang::Expr *dstSizeArg, clang::ASTContext &astContext, diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index fa5cb9c08680..61e6d120c306 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -1405,7 +1405,17 @@ class CIRGenFunction : public CIRGenTypeCache { RValue emitRotate(const CallExpr *E, bool IsRotateRight); template RValue emitBuiltinWithOneOverloadedType(const CallExpr *E, - llvm::StringRef Name); + llvm::StringRef Name) { + static_assert(N, "expect non-empty argument"); + mlir::Type cirTy = convertType(E->getArg(0)->getType()); + SmallVector Args; + for (unsigned I = 0; I < N; ++I) { + Args.push_back(emitScalarExpr(E->getArg(I))); + } + const auto call = builder.create( + getLoc(E->getExprLoc()), builder.getStringAttr(Name), cirTy, Args); + return RValue::get(call->getResult(0)); + } mlir::Value emitTargetBuiltinExpr(unsigned BuiltinID, const clang::CallExpr *E, ReturnValueSlot ReturnValue); From 1d3e12ec8c75fb8ee3d6f2831113f6675ef8af5b Mon Sep 17 00:00:00 2001 From: Letu Ren Date: Mon, 17 Feb 2025 21:50:04 +0800 Subject: [PATCH 3/3] fix style --- clang/lib/CIR/CodeGen/CIRGenFunction.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 61e6d120c306..44484bcd2fe3 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -1403,17 +1403,17 @@ class CIRGenFunction : public CIRGenTypeCache { RValue emitBuiltinExpr(const clang::GlobalDecl GD, unsigned BuiltinID, const clang::CallExpr *E, ReturnValueSlot ReturnValue); RValue emitRotate(const CallExpr *E, bool IsRotateRight); - template + template RValue emitBuiltinWithOneOverloadedType(const CallExpr *E, llvm::StringRef Name) { static_assert(N, "expect non-empty argument"); mlir::Type cirTy = convertType(E->getArg(0)->getType()); - SmallVector Args; - for (unsigned I = 0; I < N; ++I) { - Args.push_back(emitScalarExpr(E->getArg(I))); + SmallVector args; + for (uint32_t i = 0; i < N; ++i) { + args.push_back(emitScalarExpr(E->getArg(i))); } const auto call = builder.create( - getLoc(E->getExprLoc()), builder.getStringAttr(Name), cirTy, Args); + getLoc(E->getExprLoc()), builder.getStringAttr(Name), cirTy, args); return RValue::get(call->getResult(0)); } mlir::Value emitTargetBuiltinExpr(unsigned BuiltinID,