Fix libm regression.

This commit is contained in:
Christoffer Lerno
2025-08-02 13:22:48 +02:00
parent f0142e3b1a
commit bdbe81fedd
5 changed files with 73 additions and 22 deletions

View File

@@ -7,7 +7,6 @@ import std::math::matrix;
import std::math::quaternion;
attrdef @MathLibc(name) = @extern(name), @link(env::POSIX, "m");
attrdef @LinkMath = @link(env::POSIX, "m");
const E = 2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466;
const LOG2E = 1.44269504088896340735992468100189214; // log2(e)
@@ -235,14 +234,14 @@ macro asinh(x)
<*
@require values::@is_floatlike(x) : `The input must be a floating point value or float vector`
*>
macro ceil(x) @LinkMath => $$ceil(x);
macro ceil(x) => $$ceil(x);
<*
Ceil for compile time evaluation.
@require @typeis($input, double) || @typeis($input, float) : "Only float and double may be used"
*>
macro @ceil($input) @const @LinkMath => $$ceil($input);
macro @ceil($input) @const => $$ceil($input);
<*
Constrain the value to lie within the given interval.
@@ -256,18 +255,18 @@ macro @ceil($input) @const @LinkMath => $$ceil($input);
@require values::@assign_to(lower, x) : `The lower bound must be convertable to the value type.`
@require values::@assign_to(upper, x) : `The upper bound must be convertable to the value type.`
*>
macro clamp(x, lower, upper) @LinkMath => $$max(($typeof(x))lower, $$min(x, ($typeof(x))upper));
macro clamp(x, lower, upper) => $$max(($typeof(x))lower, $$min(x, ($typeof(x))upper));
<*
@require values::@is_promotable_to_floatlike(mag) : `The input must be a number value or float vector`
@require $defined(($typeof(values::promote_int(mag)))mag) : `It's not possible to cast the sign to the type of the magnitude`
*>
macro copysign(mag, sgn) @LinkMath => $$copysign(values::promote_int_same(mag, sgn), ($typeof(values::promote_int_same(mag, sgn)))sgn);
macro copysign(mag, sgn) => $$copysign(values::promote_int_same(mag, sgn), ($typeof(values::promote_int_same(mag, sgn)))sgn);
<*
@require values::@is_promotable_to_floatlike(x) : `The input must be a number value or float vector`
*>
macro cos(x) @LinkMath => $$cos(values::promote_int(x));
macro cos(x) => $$cos(values::promote_int(x));
<*
@require values::@is_promotable_to_floatlike(x) : `The input must be a number value or float vector`
@@ -297,17 +296,17 @@ macro cotanh(x) => (exp(2.0 * x) + 1.0) / (exp(2.0 * x) - 1.0);
<*
@require values::@is_promotable_to_floatlike(x) : `The input must be a number value or float vector`
*>
macro exp(x) @LinkMath => $$exp(values::promote_int(x));
macro exp(x) => $$exp(values::promote_int(x));
<*
@require values::@is_promotable_to_floatlike(x) : `The input must be a number value or float vector`
*>
macro exp2(x) @LinkMath => $$exp2(values::promote_int(x));
macro exp2(x) => $$exp2(values::promote_int(x));
<*
@require values::@is_promotable_to_floatlike(x) : `The input must be a number value or float vector`
*>
macro floor(x) @LinkMath => $$floor(values::promote_int(x));
macro floor(x) => $$floor(values::promote_int(x));
<*
@require values::@is_promotable_to_floatlike(a) : `The input must be a number or float vector`
@@ -316,7 +315,7 @@ macro floor(x) @LinkMath => $$floor(values::promote_int(x));
@require values::@is_same_vector_type(a, b) : `The input types must be equal`
@require values::@is_same_vector_type(a, c) : `The input types must match`
*>
macro fma(a, b, c) @LinkMath => $$fma(a, b, c);
macro fma(a, b, c) => $$fma(a, b, c);
<*
@@ -329,13 +328,13 @@ macro hypot(x, y) => sqrt(sqr(x) + sqr(y));
<*
@require values::@is_promotable_to_floatlike(x) : `The input must be a number or a float vector`
*>
macro ln(x) @LinkMath => $$log(values::promote_int(x));
macro ln(x) => $$log(values::promote_int(x));
<*
@require values::@is_promotable_to_floatlike(x) : `The input must be a number or a float vector`
@require values::@is_promotable_to_floatlike(base) : `The base must be a number or a float vector`
*>
macro log(x, base) @LinkMath
macro log(x, base)
{
return $$log(values::promote_int_same(x, base)) / $$log(values::promote_int_same(base, x));
}
@@ -343,12 +342,12 @@ macro log(x, base) @LinkMath
<*
@require values::@is_promotable_to_floatlike(x) : `The input must be a number or a float vector`
*>
macro log2(x) @LinkMath => $$log2(values::promote_int(x));
macro log2(x) => $$log2(values::promote_int(x));
<*
@require values::@is_promotable_to_floatlike(x) : `The input must be a number or a float vector`
*>
macro log10(x) @LinkMath => $$log10(values::promote_int(x));
macro log10(x) => $$log10(values::promote_int(x));
<*
@require types::is_numerical($typeof(x)) : `The input must be a floating point value or float vector`
@@ -1095,21 +1094,21 @@ fn float _frexpf(float x, int* e)
}
}
macro overflow_add_helper(x, y) @local @LinkMath
macro overflow_add_helper(x, y) @local
{
$typeof(x) res @noinit;
if ($$overflow_add(x, y, &res)) return OVERFLOW?;
return res;
}
macro overflow_sub_helper(x, y) @local @LinkMath
macro overflow_sub_helper(x, y) @local
{
$typeof(x) res @noinit;
if ($$overflow_sub(x, y, &res)) return OVERFLOW?;
return res;
}
macro overflow_mul_helper(x, y) @local @LinkMath
macro overflow_mul_helper(x, y) @local
{
$typeof(x) res @noinit;
if ($$overflow_mul(x, y, &res)) return OVERFLOW?;
@@ -1123,7 +1122,7 @@ macro overflow_mul_helper(x, y) @local @LinkMath
@require values::@is_flat_intlike(a) &&& values::@is_flat_intlike(b) : "a and b must both be integer or integer vector based"
@require $defined(*out) &&& values::@is_same_type(*out, a) : "out must be a pointer of the same type as a and b"
*>
macro bool overflow_add(a, b, out) @LinkMath => $$overflow_add(a, b, out);
macro bool overflow_add(a, b, out) => $$overflow_add(a, b, out);
<*
@param [&out] out : "Where the result of the subtraction is stored"
@@ -1132,7 +1131,7 @@ macro bool overflow_add(a, b, out) @LinkMath => $$overflow_add(a, b, out);
@require values::@is_flat_intlike(a) &&& values::@is_flat_intlike(b) : "a and b must both be integer or integer vector based"
@require $defined(*out) &&& values::@is_same_type(*out, a) : "out must be a pointer of the same type as a and b"
*>
macro bool overflow_sub(a, b, out) @LinkMath => $$overflow_sub(a, b, out);
macro bool overflow_sub(a, b, out) => $$overflow_sub(a, b, out);
<*
@param [&out] out : "Where the result of the multiplication is stored"
@@ -1141,7 +1140,7 @@ macro bool overflow_sub(a, b, out) @LinkMath => $$overflow_sub(a, b, out);
@require values::@is_flat_intlike(a) &&& values::@is_flat_intlike(b) : "a and b must both be integer or integer vector based"
@require $defined(*out) &&& values::@is_same_type(*out, a) : "out must be a pointer of the same type as a and b"
*>
macro bool overflow_mul(a, b, out) @LinkMath => $$overflow_mul(a, b, out);
macro bool overflow_mul(a, b, out) => $$overflow_mul(a, b, out);
<*
@require types::is_vector($Type) || ($Type.kindof == ARRAY &&& types::is_numerical($typefrom($Type.inner)))

View File

@@ -1362,7 +1362,7 @@ static void parse_option(BuildOptions *options)
break;
}
FAIL_WITH_ERR("Cannot process the unknown option \"%s\".", current_arg);
FAIL_WITH_ERR_LONG("Cannot process the unknown option \"%s\".", current_arg);
}
BuildOptions parse_arguments(int argc, const char *argv[])

View File

@@ -1877,6 +1877,7 @@ typedef struct CopyStruct_
typedef struct
{
const char **links;
bool link_math;
} Linking;
typedef struct

View File

@@ -268,6 +268,7 @@ static void linker_setup_macos(const char ***args_ref, Linker linker_type)
error_exit("Cannot crosslink MacOS without providing --macossdk.");
}
linking_add_link(&compiler.linking, "System");
if (compiler.linking.link_math) linking_add_link(&compiler.linking, "m");
add_plain_arg("-syslibroot");
add_quote_arg(compiler.build.macos.sysroot);
if (is_no_pie(compiler.platform.reloc_model)) add_plain_arg("-no_pie");
@@ -406,6 +407,7 @@ static void linker_setup_linux(const char ***args_ref, Linker linker_type, bool
add_plain_arg("-nostdlib");
return;
}
if (compiler.linking.link_math) linking_add_link(&compiler.linking, "m");
if (compiler.build.debug_info == DEBUG_INFO_FULL)
{
add_plain_arg("-rdynamic");
@@ -450,6 +452,7 @@ static void linker_setup_linux(const char ***args_ref, Linker linker_type, bool
add_concat_file_arg(crt_dir, "crtn.o");
add_concat_quote_arg("-L", crt_dir);
add_plain_arg("--dynamic-linker=/lib64/ld-linux-x86-64.so.2");
if (compiler.linking.link_math) linking_add_link(&compiler.linking, "m");
linking_add_link(&compiler.linking, "pthread");
linking_add_link(&compiler.linking, "c");
add_plain_arg("-L/usr/lib/");
@@ -525,12 +528,15 @@ static void linker_setup_android(const char ***args_ref, Linker linker_type, boo
add_plain_arg(scratch_buffer_copy());
add_plain_arg("-ldl");
if (compiler.linking.link_math) add_plain_arg("-lm");
add_plain_arg("-lc");
}
static void linker_setup_freebsd(const char ***args_ref, Linker linker_type, bool is_dylib)
{
if (linker_type == LINKER_CC) {
if (linker_type == LINKER_CC)
{
if (compiler.linking.link_math) linking_add_link(&compiler.linking, "m");
linking_add_link(&compiler.linking, "pthread");
linking_add_link(&compiler.linking, "execinfo"); // for backtrace
if (compiler.build.debug_info == DEBUG_INFO_FULL)
@@ -573,6 +579,7 @@ static void linker_setup_freebsd(const char ***args_ref, Linker linker_type, boo
add_concat_quote_arg("-L", crt_dir);
add_plain_arg("--dynamic-linker=/libexec/ld-elf.so.1");
linking_add_link(&compiler.linking, "c");
if (compiler.linking.link_math) linking_add_link(&compiler.linking, "m");
linking_add_link(&compiler.linking, "gcc");
linking_add_link(&compiler.linking, "gcc_s");

View File

@@ -829,6 +829,7 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
llvm_emit_matrix_multiply(c, result_value, expr);
return;
case BUILTIN_MATRIX_TRANSPOSE:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.matrix_transpose);
return;
case BUILTIN_SYSCLOCK:
@@ -844,30 +845,39 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
llvm_emit_prefetch(c, result_value, expr);
return;
case BUILTIN_REDUCE_AND:
compiler.linking.link_math = true;
llvm_emit_reduce_int_builtin(c, intrinsic_id.vector_reduce_and, result_value, expr);
return;
case BUILTIN_REDUCE_OR:
compiler.linking.link_math = true;
llvm_emit_reduce_int_builtin(c, intrinsic_id.vector_reduce_or, result_value, expr);
return;
case BUILTIN_REDUCE_MIN:
compiler.linking.link_math = true;
llvm_emit_3_variant_builtin(c, result_value, expr, intrinsic_id.vector_reduce_smin, intrinsic_id.vector_reduce_umin, intrinsic_id.vector_reduce_fmin);
return;
case BUILTIN_REDUCE_MAX:
compiler.linking.link_math = true;
llvm_emit_3_variant_builtin(c, result_value, expr, intrinsic_id.vector_reduce_smax, intrinsic_id.vector_reduce_umax, intrinsic_id.vector_reduce_fmax);
return;
case BUILTIN_REDUCE_XOR:
compiler.linking.link_math = true;
llvm_emit_reduce_int_builtin(c, intrinsic_id.vector_reduce_xor, result_value, expr);
return;
case BUILTIN_REDUCE_ADD:
compiler.linking.link_math = true;
llvm_emit_reduce_int_builtin(c, intrinsic_id.vector_reduce_add, result_value, expr);
return;
case BUILTIN_REDUCE_MUL:
compiler.linking.link_math = true;
llvm_emit_reduce_int_builtin(c, intrinsic_id.vector_reduce_mul, result_value, expr);
return;
case BUILTIN_REDUCE_FADD:
compiler.linking.link_math = true;
llvm_emit_reduce_float_builtin(c, intrinsic_id.vector_reduce_fadd, result_value, expr);
return;
case BUILTIN_REDUCE_FMUL:
compiler.linking.link_math = true;
llvm_emit_reduce_float_builtin(c, intrinsic_id.vector_reduce_fmul, result_value, expr);
return;
case BUILTIN_EXACT_DIV:
@@ -876,15 +886,19 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
case BUILTIN_EXACT_SUB:
case BUILTIN_EXACT_MOD:
case BUILTIN_EXACT_NEG:
compiler.linking.link_math = true;
llvm_emit_wrap_builtin(c, result_value, expr, func);
return;
case BUILTIN_OVERFLOW_ADD:
compiler.linking.link_math = true;
llvm_emit_overflow_builtin(c, result_value, expr, intrinsic_id.sadd_overflow, intrinsic_id.uadd_overflow);
return;
case BUILTIN_OVERFLOW_SUB:
compiler.linking.link_math = true;
llvm_emit_overflow_builtin(c, result_value, expr, intrinsic_id.ssub_overflow, intrinsic_id.usub_overflow);
return;
case BUILTIN_OVERFLOW_MUL:
compiler.linking.link_math = true;
llvm_emit_overflow_builtin(c, result_value, expr, intrinsic_id.smul_overflow, intrinsic_id.umul_overflow);
return;
case BUILTIN_CTTZ:
@@ -926,21 +940,27 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
llvm_emit_3_variant_builtin(c, result_value, expr, intrinsic_id.smin, intrinsic_id.umin, intrinsic_id.minnum);
return;
case BUILTIN_SAT_SHL:
compiler.linking.link_math = true;
llvm_emit_3_variant_builtin(c, result_value, expr, intrinsic_id.sshl_sat, intrinsic_id.ushl_sat, 0);
return;
case BUILTIN_SAT_ADD:
compiler.linking.link_math = true;
llvm_emit_3_variant_builtin(c, result_value, expr, intrinsic_id.sadd_sat, intrinsic_id.uadd_sat, 0);
return;
case BUILTIN_SAT_SUB:
compiler.linking.link_math = true;
llvm_emit_3_variant_builtin(c, result_value, expr, intrinsic_id.ssub_sat, intrinsic_id.usub_sat, 0);
return;
case BUILTIN_SAT_MUL:
compiler.linking.link_math = true;
llvm_emit_3_variant_builtin(c, result_value, expr, intrinsic_id.smul_fixed_sat, intrinsic_id.umul_fixed_sat, 0);
return;
case BUILTIN_ABS:
compiler.linking.link_math = true;
llvm_emit_abs_builtin(c, result_value, expr);
return;
case BUILTIN_POW_INT:
compiler.linking.link_math = true;
llvm_emit_pow_int_builtin(c, result_value, expr);
return;
case BUILTIN_BITREVERSE:
@@ -953,24 +973,31 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.ceil);
return;
case BUILTIN_COS:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.cos);
return;
case BUILTIN_COPYSIGN:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.copysign);
return;
case BUILTIN_FLOOR:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.floor);
return;
case BUILTIN_EXP:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.exp);
return;
case BUILTIN_EXP2:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.exp2);
return;
case BUILTIN_FMA:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.fma);
return;
case BUILTIN_FMULADD:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.fmuladd);
return;
case BUILTIN_FSHL:
@@ -980,37 +1007,47 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.fshr);
return;
case BUILTIN_GET_ROUNDING_MODE:
compiler.linking.link_math = true;
llvm_value_set(result_value, llvm_emit_call_intrinsic(c, intrinsic_id.get_rounding, NULL, 0, NULL, 0), expr->type);
return;
case BUILTIN_LOG:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.log);
return;
case BUILTIN_LOG2:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.log2);
return;
case BUILTIN_LOG10:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.log10);
return;
case BUILTIN_POW:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.pow);
return;
case BUILTIN_NEARBYINT:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.nearbyint);
return;
case BUILTIN_POPCOUNT:
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.ctpop);
return;
case BUILTIN_RINT:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.rint);
return;
case BUILTIN_ROUND:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.round);
return;
case BUILTIN_ROUNDEVEN:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.roundeven);
return;
case BUILTIN_SET_ROUNDING_MODE:
{
compiler.linking.link_math = true;
Expr **args = expr->call_expr.arguments;
LLVMValueRef arg_slots[1];
llvm_emit_intrinsic_args(c, args, arg_slots, 1);
@@ -1036,23 +1073,30 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
llvm_emit_builtin_args_types3(c, result_value, expr, intrinsic_id.wasm_memory_size, expr->type, NULL, NULL);
return;
case BUILTIN_SIN:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.sin);
return;
case BUILTIN_SQRT:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.sqrt);
return;
case BUILTIN_TRUNC:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.trunc);
return;
case BUILTIN_LRINT:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.lrint);
return;
case BUILTIN_LROUND:
compiler.linking.link_math = true;
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.lround);
return;
case BUILTIN_LLRINT:
compiler.linking.link_math = true;
TODO
case BUILTIN_LLROUND:
compiler.linking.link_math = true;
TODO
case BUILTIN_STR_HASH:
case BUILTIN_STR_LOWER: