diff --git a/crates/compiler/builtins/bitcode/src/main.zig b/crates/compiler/builtins/bitcode/src/main.zig index 3b9d28cec5..8cd3ecc882 100644 --- a/crates/compiler/builtins/bitcode/src/main.zig +++ b/crates/compiler/builtins/bitcode/src/main.zig @@ -163,6 +163,7 @@ comptime { num.exportSin(T, ROC_BUILTINS ++ "." ++ NUM ++ ".sin."); num.exportCos(T, ROC_BUILTINS ++ "." ++ NUM ++ ".cos."); + num.exportTan(T, ROC_BUILTINS ++ "." ++ NUM ++ ".tan."); num.exportPow(T, ROC_BUILTINS ++ "." ++ NUM ++ ".pow."); num.exportLog(T, ROC_BUILTINS ++ "." ++ NUM ++ ".log."); diff --git a/crates/compiler/builtins/bitcode/src/num.zig b/crates/compiler/builtins/bitcode/src/num.zig index d034495492..30efcc0f70 100644 --- a/crates/compiler/builtins/bitcode/src/num.zig +++ b/crates/compiler/builtins/bitcode/src/num.zig @@ -168,6 +168,15 @@ pub fn exportCos(comptime T: type, comptime name: []const u8) void { @export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong }); } +pub fn exportTan(comptime T: type, comptime name: []const u8) void { + comptime var f = struct { + fn func(input: T) callconv(.C) T { + return math.tan(input); + } + }.func; + @export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong }); +} + pub fn exportLog(comptime T: type, comptime name: []const u8) void { comptime var f = struct { fn func(input: T) callconv(.C) T { diff --git a/crates/compiler/builtins/roc/Num.roc b/crates/compiler/builtins/roc/Num.roc index 32e3f48abc..67cdac6abe 100644 --- a/crates/compiler/builtins/roc/Num.roc +++ b/crates/compiler/builtins/roc/Num.roc @@ -825,11 +825,7 @@ max = \a, b -> sin : Frac a -> Frac a cos : Frac a -> Frac a - tan : Frac a -> Frac a -tan = \x -> - # `tan` is not available as an intrinsic in LLVM - Num.div (Num.sin x) (Num.cos x) asin : Frac a -> Frac a acos : Frac a -> Frac a diff --git a/crates/compiler/builtins/src/bitcode.rs b/crates/compiler/builtins/src/bitcode.rs index a47c13a13b..b80df88c65 100644 --- a/crates/compiler/builtins/src/bitcode.rs +++ b/crates/compiler/builtins/src/bitcode.rs @@ -272,6 +272,7 @@ macro_rules! int_intrinsic { pub const NUM_SIN: IntrinsicName = float_intrinsic!("roc_builtins.num.sin"); pub const NUM_COS: IntrinsicName = float_intrinsic!("roc_builtins.num.cos"); +pub const NUM_TAN: IntrinsicName = float_intrinsic!("roc_builtins.num.tan"); pub const NUM_ASIN: IntrinsicName = float_intrinsic!("roc_builtins.num.asin"); pub const NUM_ACOS: IntrinsicName = float_intrinsic!("roc_builtins.num.acos"); pub const NUM_ATAN: IntrinsicName = float_intrinsic!("roc_builtins.num.atan"); diff --git a/crates/compiler/can/src/builtins.rs b/crates/compiler/can/src/builtins.rs index bda1d64dab..168faff98d 100644 --- a/crates/compiler/can/src/builtins.rs +++ b/crates/compiler/can/src/builtins.rs @@ -186,6 +186,7 @@ map_symbol_to_lowlevel_and_arity! { NumNeg; NUM_NEG; 1, NumSin; NUM_SIN; 1, NumCos; NUM_COS; 1, + NumTan; NUM_TAN; 1, NumSqrtUnchecked; NUM_SQRT; 1, NumLogUnchecked; NUM_LOG; 1, NumRound; NUM_ROUND; 1, diff --git a/crates/compiler/gen_llvm/src/llvm/lowlevel.rs b/crates/compiler/gen_llvm/src/llvm/lowlevel.rs index f9b3548cd3..a7689d52fd 100644 --- a/crates/compiler/gen_llvm/src/llvm/lowlevel.rs +++ b/crates/compiler/gen_llvm/src/llvm/lowlevel.rs @@ -935,6 +935,7 @@ pub(crate) fn run_low_level<'a, 'ctx>( | NumLogUnchecked | NumSin | NumCos + | NumTan | NumCeiling | NumFloor | NumToFrac @@ -2655,6 +2656,7 @@ fn build_float_unary_op<'a, 'ctx>( // trigonometry NumSin => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_SIN[float_width]), NumCos => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_COS[float_width]), + NumTan => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_TAN[float_width]), NumAtan => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_ATAN[float_width]), NumAcos => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_ACOS[float_width]), diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index ce71286726..08182b84c8 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -1539,6 +1539,12 @@ impl<'a> LowLevelCall<'a> { } _ => panic_ret_type(), }, + NumTan => match self.ret_layout_raw { + LayoutRepr::Builtin(Builtin::Float(width)) => { + self.load_args_and_call_zig(backend, &bitcode::NUM_TAN[width]); + } + _ => panic_ret_type(), + }, NumSqrtUnchecked => { self.load_args(backend); match self.ret_layout_raw { diff --git a/crates/compiler/module/src/low_level.rs b/crates/compiler/module/src/low_level.rs index 8a6dfcef4c..ae81591b17 100644 --- a/crates/compiler/module/src/low_level.rs +++ b/crates/compiler/module/src/low_level.rs @@ -78,6 +78,7 @@ pub enum LowLevel { NumNeg, NumSin, NumCos, + NumTan, NumSqrtUnchecked, NumLogUnchecked, NumRound, @@ -324,6 +325,7 @@ map_symbol_to_lowlevel! { NumNeg <= NUM_NEG, NumSin <= NUM_SIN, NumCos <= NUM_COS, + NumTan <= NUM_TAN, NumSqrtUnchecked <= NUM_SQRT, NumLogUnchecked <= NUM_LOG, NumRound <= NUM_ROUND, diff --git a/crates/compiler/mono/src/drop_specialization.rs b/crates/compiler/mono/src/drop_specialization.rs index 7e2e3899fd..5bb633a0eb 100644 --- a/crates/compiler/mono/src/drop_specialization.rs +++ b/crates/compiler/mono/src/drop_specialization.rs @@ -1571,6 +1571,7 @@ fn low_level_no_rc(lowlevel: &LowLevel) -> RC { | NumNeg | NumSin | NumCos + | NumTan | NumSqrtUnchecked | NumLogUnchecked | NumRound diff --git a/crates/compiler/mono/src/inc_dec.rs b/crates/compiler/mono/src/inc_dec.rs index a28c455fe3..64a1c9a429 100644 --- a/crates/compiler/mono/src/inc_dec.rs +++ b/crates/compiler/mono/src/inc_dec.rs @@ -1327,6 +1327,7 @@ fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[Ownership] { | NumNeg | NumSin | NumCos + | NumTan | NumSqrtUnchecked | NumLogUnchecked | NumRound diff --git a/crates/compiler/mono/src/low_level.rs b/crates/compiler/mono/src/low_level.rs index 358d77d963..d0fe15a8ea 100644 --- a/crates/compiler/mono/src/low_level.rs +++ b/crates/compiler/mono/src/low_level.rs @@ -101,6 +101,7 @@ enum FirstOrder { NumNeg, NumSin, NumCos, + NumTan, NumSqrtUnchecked, NumLogUnchecked, NumRound,