[clang] [CIR] Upstream FPToFPBuiltin ACosOp (PR #156356)

Amr Hesham via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 2 10:25:13 PDT 2025


https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/156356

>From a23eb7b29d90a7afc9c02080ca9747f365a67270 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
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<string mnemonic, string llvmOpName>
   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 <class Operation>
+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<cir::ACosOp>(*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<mlir::LLVM::ACosOp>(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<cir::FAbsOp> {
                   mlir::ConversionPatternRewriter &) const override;
 };
 
+class CIRToLLVMACosOpLowering : public mlir::OpConversionPattern<cir::ACosOp> {
+public:
+  using mlir::OpConversionPattern<cir::ACosOp>::OpConversionPattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(cir::ACosOp op, OpAdaptor,
+                  mlir::ConversionPatternRewriter &) const override;
+};
+
 class CIRToLLVMInlineAsmOpLowering
     : public mlir::OpConversionPattern<cir::InlineAsmOp> {
   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 7c1d5288d5ba42e55e9832dff4984add12898688 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
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`.
   }];
 }
 



More information about the cfe-commits mailing list