From 44d0ce4e4b7a3c1ca95cd07e899dbc15cc272608 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Sun, 31 Aug 2025 18:55:45 +0200 Subject: [PATCH 1/2] [CIR] Upstream builtin ACos op --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 9 +++++ clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 11 ++++++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 10 +++++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h | 9 +++++ clang/test/CIR/CodeGen/builtins-elementwise.c | 38 +++++++++++++++++++ 5 files changed, 77 insertions(+) create mode 100644 clang/test/CIR/CodeGen/builtins-elementwise.c diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 982533f5e3b84..0f6c7332cd9ba 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -3732,6 +3732,15 @@ class CIR_UnaryFPToFPBuiltinOp let llvmOp = llvmOpName; } +def CIR_ACosOp : CIR_UnaryFPToFPBuiltinOp<"acos", "ACosOp"> { + let summary = "Computes the arcus cosine of the specified value"; + let description = [{ + `cir.acos`computes the arcus cosine of a given value and + returns a result of the same type. ignoring floating-point + exceptions. It does not set `errno`. + }]; +} + def CIR_FAbsOp : CIR_UnaryFPToFPBuiltinOp<"fabs", "FAbsOp"> { let summary = "Computes the floating-point absolute value"; let description = [{ diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index b6a6299667308..b68e91f64dc84 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -85,6 +85,14 @@ static RValue emitUnaryMaybeConstrainedFPBuiltin(CIRGenFunction &cgf, return RValue::get(call->getResult(0)); } +template +static RValue emitUnaryFPBuiltin(CIRGenFunction &cgf, const CallExpr &e) { + mlir::Value arg = cgf.emitScalarExpr(e.getArg(0)); + auto call = + Operation::create(cgf.getBuilder(), arg.getLoc(), arg.getType(), arg); + return RValue::get(call->getResult(0)); +} + RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, const CallExpr *e, ReturnValueSlot returnValue) { @@ -349,6 +357,9 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, case Builtin::BI__builtin_unreachable: emitUnreachable(e->getExprLoc(), /*createNewBlock=*/true); return RValue::get(nullptr); + + case Builtin::BI__builtin_elementwise_acos: + return emitUnaryFPBuiltin(*this, *e); } // If this is an alias for a lib function (e.g. __builtin_sin), emit diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index f1fdfed166bbc..ede10c5d1e6c0 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -577,6 +577,15 @@ struct ConvertCIRToLLVMPass StringRef getArgument() const override { return "cir-flat-to-llvm"; } }; +mlir::LogicalResult CIRToLLVMACosOpLowering::matchAndRewrite( + cir::ACosOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + mlir::Type resTy = typeConverter->convertType(op.getType()); + rewriter.replaceOpWithNewOp(op, resTy, + adaptor.getOperands()[0]); + return mlir::success(); +} + mlir::LogicalResult CIRToLLVMAssumeOpLowering::matchAndRewrite( cir::AssumeOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { @@ -2395,6 +2404,7 @@ void ConvertCIRToLLVMPass::runOnOperation() { dl); patterns.add< // clang-format off + CIRToLLVMACosOpLowering, CIRToLLVMAssumeOpLowering, CIRToLLVMAssumeAlignedOpLowering, CIRToLLVMAssumeSepStorageOpLowering, diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index da7df8982d34c..656a776035885 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -718,6 +718,15 @@ class CIRToLLVMFAbsOpLowering : public mlir::OpConversionPattern { mlir::ConversionPatternRewriter &) const override; }; +class CIRToLLVMACosOpLowering : public mlir::OpConversionPattern { +public: + using mlir::OpConversionPattern::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(cir::ACosOp op, OpAdaptor, + mlir::ConversionPatternRewriter &) const override; +}; + class CIRToLLVMInlineAsmOpLowering : public mlir::OpConversionPattern { mlir::DataLayout const &dataLayout; diff --git a/clang/test/CIR/CodeGen/builtins-elementwise.c b/clang/test/CIR/CodeGen/builtins-elementwise.c new file mode 100644 index 0000000000000..1898f56a33628 --- /dev/null +++ b/clang/test/CIR/CodeGen/builtins-elementwise.c @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-android24 -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple aarch64-none-linux-android24 -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -triple aarch64-none-linux-android24 -Wno-unused-value -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +typedef int vint4 __attribute__((ext_vector_type(4))); +typedef float vfloat4 __attribute__((ext_vector_type(4))); +typedef double vdouble4 __attribute__((ext_vector_type(4))); + +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 + // OGCG-LABEL: test_builtin_elementwise_acos + + // CIR: %{{.*}} = cir.acos %{{.*}} : !cir.float + // LLVM: %{{.*}} = call float @llvm.acos.f32(float %{{.*}}) + // OGCG: %{{.*}} = call float @llvm.acos.f32(float %{{.*}}) + f = __builtin_elementwise_acos(f); + + // CIR: %{{.*}} = cir.acos %{{.*}} : !cir.double + // LLVM: %{{.*}} = call double @llvm.acos.f64(double %{{.*}}) + // OGCG: %{{.*}} = call double @llvm.acos.f64(double %{{.*}}) + d = __builtin_elementwise_acos(d); + + // CIR: %{{.*}} = cir.acos %{{.*}} : !cir.vector<4 x !cir.float> + // LLVM: %{{.*}} = call <4 x float> @llvm.acos.v4f32(<4 x float> %{{.*}}) + // OGCG: %{{.*}} = call <4 x float> @llvm.acos.v4f32(<4 x float> %{{.*}}) + vf4 = __builtin_elementwise_acos(vf4); + + // CIR: %{{.*}} = cir.acos %{{.*}} : !cir.vector<4 x !cir.double> + // LLVM: %{{.*}} = call <4 x double> @llvm.acos.v4f64(<4 x double> %{{.*}}) + // OGCG: %{{.*}} = call <4 x double> @llvm.acos.v4f64(<4 x double> %{{.*}}) + vd4 = __builtin_elementwise_acos(vd4); +} + From 596f57039b32839bf9ad78a0e00437a0ccc4e3c0 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Tue, 2 Sep 2025 18:45:59 +0200 Subject: [PATCH 2/2] Address code review comments --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 0f6c7332cd9ba..1ed3e43cb617f 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -3736,8 +3736,9 @@ def CIR_ACosOp : CIR_UnaryFPToFPBuiltinOp<"acos", "ACosOp"> { let summary = "Computes the arcus cosine of the specified value"; let description = [{ `cir.acos`computes the arcus cosine of a given value and - returns a result of the same type. ignoring floating-point - exceptions. It does not set `errno`. + returns a result of the same type. + + Floating-point exceptions are ignored, and it does not set `errno`. }]; } @@ -3745,8 +3746,9 @@ def CIR_FAbsOp : CIR_UnaryFPToFPBuiltinOp<"fabs", "FAbsOp"> { let summary = "Computes the floating-point absolute value"; let description = [{ `cir.fabs` computes the absolute value of a floating-point operand - and returns a result of the same type, ignoring floating-point - exceptions. It does not set `errno`. + and returns a result of the same type. + + Floating-point exceptions are ignored, and it does not set `errno`. }]; }