diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index b3c435cc59140..38c4a87f69d6d 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -3847,6 +3847,16 @@ def CIR_ATanOp : CIR_UnaryFPToFPBuiltinOp<"atan", "ATanOp"> { }]; } +def CIR_CosOp : CIR_UnaryFPToFPBuiltinOp<"cos", "CosOp"> { + let summary = "Computes the floating-point cosine value"; + let description = [{ + `cir.cos` computes the cosine of a floating-point operand and returns + a result of the same type. + + Floating-point exceptions are ignored, and 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 8892e62accb74..cf17de144f4d9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -200,6 +200,17 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, builder.createBitcast(allocaAddr, builder.getVoidPtrTy())); } + case Builtin::BIcos: + case Builtin::BIcosf: + case Builtin::BIcosl: + case Builtin::BI__builtin_cos: + case Builtin::BI__builtin_cosf: + case Builtin::BI__builtin_cosf16: + case Builtin::BI__builtin_cosl: + case Builtin::BI__builtin_cosf128: + assert(!cir::MissingFeatures::fastMathFlags()); + return emitUnaryMaybeConstrainedFPBuiltin(*this, *e); + case Builtin::BIfabs: case Builtin::BIfabsf: case Builtin::BIfabsl: @@ -415,6 +426,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, return emitUnaryFPBuiltin(*this, *e); case Builtin::BI__builtin_elementwise_atan: return emitUnaryFPBuiltin(*this, *e); + case Builtin::BI__builtin_elementwise_cos: + 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 d9097b0b9e03d..1d7e3df1430ac 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -185,6 +185,14 @@ mlir::LogicalResult CIRToLLVMCopyOpLowering::matchAndRewrite( return mlir::success(); } +mlir::LogicalResult CIRToLLVMCosOpLowering::matchAndRewrite( + cir::CosOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + mlir::Type resTy = typeConverter->convertType(op.getType()); + rewriter.replaceOpWithNewOp(op, resTy, adaptor.getSrc()); + return mlir::success(); +} + static mlir::Value getLLVMIntCast(mlir::ConversionPatternRewriter &rewriter, mlir::Value llvmSrc, mlir::Type llvmDstIntTy, bool isUnsigned, uint64_t cirSrcWidth, @@ -2498,6 +2506,7 @@ void ConvertCIRToLLVMPass::runOnOperation() { CIRToLLVMComplexRealPtrOpLowering, CIRToLLVMComplexSubOpLowering, CIRToLLVMCopyOpLowering, + CIRToLLVMCosOpLowering, CIRToLLVMConstantOpLowering, CIRToLLVMExpectOpLowering, CIRToLLVMFAbsOpLowering, diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index dd1dd0aaec7d8..09ff7a0901c69 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -189,6 +189,15 @@ class CIRToLLVMCopyOpLowering : public mlir::OpConversionPattern { mlir::ConversionPatternRewriter &) const override; }; +class CIRToLLVMCosOpLowering : public mlir::OpConversionPattern { +public: + using mlir::OpConversionPattern::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(cir::CosOp op, OpAdaptor, + mlir::ConversionPatternRewriter &) const override; +}; + class CIRToLLVMExpectOpLowering : public mlir::OpConversionPattern { public: diff --git a/clang/test/CIR/CodeGen/builtins-elementwise.c b/clang/test/CIR/CodeGen/builtins-elementwise.c index e3460f06d166a..f64080b829bdf 100644 --- a/clang/test/CIR/CodeGen/builtins-elementwise.c +++ b/clang/test/CIR/CodeGen/builtins-elementwise.c @@ -89,3 +89,30 @@ void test_builtin_elementwise_atan(float f, double d, vfloat4 vf4, // OGCG: %{{.*}} = call <4 x double> @llvm.atan.v4f64(<4 x double> %{{.*}}) vd4 = __builtin_elementwise_atan(vd4); } + +void test_builtin_elementwise_cos(float f, double d, vfloat4 vf4, + vdouble4 vd4) { + // CIR-LABEL: test_builtin_elementwise_cos + // LLVM-LABEL: test_builtin_elementwise_cos + // OGCG-LABEL: test_builtin_elementwise_cos + + // CIR: {{%.*}} = cir.cos {{%.*}} : !cir.float + // LLVM: {{%.*}} = call float @llvm.cos.f32(float {{%.*}}) + // OGCG: {{%.*}} = call float @llvm.cos.f32(float {{%.*}}) + f = __builtin_elementwise_cos(f); + + // CIR: {{%.*}} = cir.cos {{%.*}} : !cir.double + // LLVM: {{%.*}} = call double @llvm.cos.f64(double {{%.*}}) + // OGCG: {{%.*}} = call double @llvm.cos.f64(double {{%.*}}) + d = __builtin_elementwise_cos(d); + + // CIR: {{%.*}} = cir.cos {{%.*}} : !cir.vector<4 x !cir.float> + // LLVM: {{%.*}} = call <4 x float> @llvm.cos.v4f32(<4 x float> {{%.*}}) + // OGCG: {{%.*}} = call <4 x float> @llvm.cos.v4f32(<4 x float> {{%.*}}) + vf4 = __builtin_elementwise_cos(vf4); + + // CIR: {{%.*}} = cir.cos {{%.*}} : !cir.vector<4 x !cir.double> + // LLVM: {{%.*}} = call <4 x double> @llvm.cos.v4f64(<4 x double> {{%.*}}) + // OGCG: {{%.*}} = call <4 x double> @llvm.cos.v4f64(<4 x double> {{%.*}}) + vd4 = __builtin_elementwise_cos(vd4); +} diff --git a/clang/test/CIR/CodeGen/builtins-floating-point.c b/clang/test/CIR/CodeGen/builtins-floating-point.c new file mode 100644 index 0000000000000..193cc172d37d2 --- /dev/null +++ b/clang/test/CIR/CodeGen/builtins-floating-point.c @@ -0,0 +1,20 @@ +// 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 + +float cosf(float f) { + return __builtin_cosf(f); + // CHECK: %{{.*}} = cir.cos {{.*}} : !cir.float + // LLVM: %{{.*}} = call float @llvm.cos.f32(float %{{.*}}) + // OGCG: %{{.*}} = call float @llvm.cos.f32(float %{{.*}}) +} + +double cos(double f) { + return __builtin_cos(f); + // CIR: {{.+}} = cir.cos {{.+}} : !cir.double + // LLVM: %{{.*}} = call double @llvm.cos.f64(double %{{.*}}) + // OGCG: %{{.*}} = call double @llvm.cos.f64(double %{{.*}}) +}