diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 3e08459ba..683be1e53 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -757,21 +757,28 @@ typedef enum BUILTIN_BSWAP, BUILTIN_CEIL, BUILTIN_COS, + BUILTIN_COPYSIGN, BUILTIN_CTLZ, - BUILTIN_CTPOP, BUILTIN_CTTZ, BUILTIN_EXP, + BUILTIN_EXP2, + BUILTIN_FLOOR, BUILTIN_FMA, BUILTIN_FSHL, BUILTIN_FSHR, + BUILTIN_LOG, BUILTIN_LOG2, BUILTIN_LOG10, - BUILTIN_LOG, BUILTIN_MAX, BUILTIN_MEMCOPY, BUILTIN_MEMSET, BUILTIN_MIN, + BUILTIN_NEARBYINT, + BUILTIN_CTPOP, // should be here for keeping sorting order BUILTIN_POW, + BUILTIN_RINT, + BUILTIN_ROUND, + BUILTIN_ROUNDEVEN, BUILTIN_SIN, BUILTIN_SQRT, BUILTIN_STACKTRACE, @@ -784,6 +791,12 @@ typedef enum BUILTIN_VOLATILE_STORE, BUILTIN_NONE, NUMBER_OF_BUILTINS = BUILTIN_NONE, + +// Disabled for now! + BUILTIN_LLRINT, + BUILTIN_LLROUND, + BUILTIN_LRINT, + BUILTIN_LROUND, } BuiltinFunction; typedef enum diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index d11e16fdb..55441de9f 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -605,8 +605,8 @@ void llvm_codegen_setup() intrinsic_id.ctlz = lookup_intrinsic("llvm.ctlz"); intrinsic_id.ctpop = lookup_intrinsic("llvm.ctpop"); intrinsic_id.cttz = lookup_intrinsic("llvm.cttz"); - intrinsic_id.exp2 = lookup_intrinsic("llvm.exp2"); intrinsic_id.exp = lookup_intrinsic("llvm.exp"); + intrinsic_id.exp2 = lookup_intrinsic("llvm.exp2"); intrinsic_id.fabs = lookup_intrinsic("llvm.fabs"); intrinsic_id.floor = lookup_intrinsic("llvm.floor"); intrinsic_id.fma = lookup_intrinsic("llvm.fma"); @@ -616,9 +616,9 @@ void llvm_codegen_setup() intrinsic_id.lifetime_start = lookup_intrinsic("llvm.lifetime.start"); intrinsic_id.llrint = lookup_intrinsic("llvm.llrint"); intrinsic_id.llround = lookup_intrinsic("llvm.llround"); + intrinsic_id.log = lookup_intrinsic("llvm.log"); intrinsic_id.log2 = lookup_intrinsic("llvm.log2"); intrinsic_id.log10 = lookup_intrinsic("llvm.log10"); - intrinsic_id.log = lookup_intrinsic("llvm.log"); intrinsic_id.lrint = lookup_intrinsic("llvm.lrint"); intrinsic_id.lround = lookup_intrinsic("llvm.lround"); intrinsic_id.maximum = lookup_intrinsic("llvm.maximum"); @@ -628,10 +628,11 @@ void llvm_codegen_setup() intrinsic_id.minimum = lookup_intrinsic("llvm.minimum"); intrinsic_id.minnum = lookup_intrinsic("llvm.minnum"); intrinsic_id.nearbyint = lookup_intrinsic("llvm.nearbyint"); - intrinsic_id.powi = lookup_intrinsic("llvm.powi"); intrinsic_id.pow = lookup_intrinsic("llvm.pow"); + intrinsic_id.powi = lookup_intrinsic("llvm.powi"); intrinsic_id.readcyclecounter = lookup_intrinsic("llvm.readcyclecounter"); intrinsic_id.rint = lookup_intrinsic("llvm.rint"); + intrinsic_id.round = lookup_intrinsic("llvm.round"); intrinsic_id.roundeven = lookup_intrinsic("llvm.roundeven"); intrinsic_id.sadd_overflow = lookup_intrinsic("llvm.sadd.with.overflow"); intrinsic_id.sadd_sat = lookup_intrinsic("llvm.sadd.sat"); diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index c2a1921c8..1483430fc 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -4376,6 +4376,28 @@ unsigned llvm_get_intrinsic(BuiltinFunction func) return intrinsic_id.memcpy; case BUILTIN_MEMSET: return intrinsic_id.memset; + case BUILTIN_COPYSIGN: + return intrinsic_id.copysign; + case BUILTIN_EXP2: + return intrinsic_id.exp2; + case BUILTIN_FLOOR: + return intrinsic_id.floor; + case BUILTIN_LLRINT: + return intrinsic_id.llrint; + case BUILTIN_LLROUND: + return intrinsic_id.llround; + case BUILTIN_LRINT: + return intrinsic_id.lrint; + case BUILTIN_LROUND: + return intrinsic_id.lround; + case BUILTIN_NEARBYINT: + return intrinsic_id.nearbyint; + case BUILTIN_RINT: + return intrinsic_id.rint; + case BUILTIN_ROUND: + return intrinsic_id.round; + case BUILTIN_ROUNDEVEN: + return intrinsic_id.roundeven; case BUILTIN_VOLATILE_STORE: case BUILTIN_VOLATILE_LOAD: case BUILTIN_SYSCALL: diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h index 664335d5e..ca48e059d 100644 --- a/src/compiler/llvm_codegen_internal.h +++ b/src/compiler/llvm_codegen_internal.h @@ -114,72 +114,73 @@ typedef struct typedef struct { + unsigned abs; + unsigned assume; + unsigned bitreverse; + unsigned bswap; + unsigned ceil; + unsigned convert_from_fp16; + unsigned convert_to_fp16; + unsigned copysign; + unsigned cos; + unsigned ctlz; + unsigned ctpop; + unsigned cttz; + unsigned exp; + unsigned exp2; + unsigned fabs; + unsigned floor; + unsigned fma; + unsigned fshl; + unsigned fshr; + unsigned lifetime_end; + unsigned lifetime_start; + unsigned llrint; + unsigned llround; + unsigned log; + unsigned log2; + unsigned log10; + unsigned lrint; + unsigned lround; + unsigned maximum; + unsigned maxnum; + unsigned memcpy; + unsigned memset; + unsigned minimum; + unsigned minnum; + unsigned nearbyint; + unsigned pow; + unsigned powi; + unsigned readcyclecounter; + unsigned rint; + unsigned round; + unsigned roundeven; unsigned sadd_overflow; unsigned sadd_sat; - unsigned uadd_overflow; - unsigned uadd_sat; + unsigned sin; + unsigned smax; + unsigned smin; + unsigned smul_overflow; + unsigned sqrt; + unsigned sshl_sat; unsigned ssub_overflow; unsigned ssub_sat; + unsigned trap; + unsigned trunc; + unsigned uadd_overflow; + unsigned uadd_sat; + unsigned umax; + unsigned umin; + unsigned umul_overflow; + unsigned ushl_sat; unsigned usub_overflow; unsigned usub_sat; - unsigned sshl_sat; - unsigned ushl_sat; - unsigned smul_overflow; - unsigned umul_overflow; + unsigned vector_reduce_fmax; + unsigned vector_reduce_fmin; unsigned vector_reduce_smax; unsigned vector_reduce_smin; unsigned vector_reduce_umax; unsigned vector_reduce_umin; - unsigned vector_reduce_fmax; - unsigned vector_reduce_fmin; - unsigned trap; - unsigned bswap; - unsigned assume; - unsigned rint; - unsigned trunc; - unsigned ceil; - unsigned sqrt; - unsigned nearbyint; - unsigned roundeven; - unsigned lround; - unsigned llround; - unsigned lrint; - unsigned llrint; - unsigned floor; - unsigned powi; - unsigned pow; - unsigned sin; - unsigned cos; - unsigned exp; - unsigned exp2; - unsigned log; - unsigned log2; - unsigned log10; - unsigned fabs; - unsigned fma; - unsigned copysign; - unsigned minnum; - unsigned maxnum; - unsigned minimum; - unsigned maximum; - unsigned smax; - unsigned smin; - unsigned umax; - unsigned umin; - unsigned abs; - unsigned fshl; - unsigned fshr; - unsigned bitreverse; - unsigned ctpop; - unsigned ctlz; - unsigned cttz; - unsigned convert_from_fp16; - unsigned convert_to_fp16; - unsigned lifetime_start; - unsigned lifetime_end; - unsigned memcpy; - unsigned memset; - unsigned readcyclecounter; } LLVMIntrinsics; extern LLVMIntrinsics intrinsic_id; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index f7df7a2ac..12294c693 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -2454,37 +2454,48 @@ static inline unsigned builtin_expected_args(BuiltinFunction func) { switch (func) { - case BUILTIN_UNREACHABLE: - case BUILTIN_TRAP: case BUILTIN_STACKTRACE: case BUILTIN_SYSCLOCK: + case BUILTIN_TRAP: + case BUILTIN_UNREACHABLE: return 0; - case BUILTIN_SYSCALL: + case BUILTIN_ABS: + case BUILTIN_BITREVERSE: + case BUILTIN_BSWAP: case BUILTIN_CEIL: - case BUILTIN_TRUNC: - case BUILTIN_SQRT: case BUILTIN_COS: - case BUILTIN_SIN: + case BUILTIN_CTLZ: + case BUILTIN_CTPOP: + case BUILTIN_CTTZ: case BUILTIN_EXP: + case BUILTIN_EXP2: + case BUILTIN_FLOOR: + case BUILTIN_LLRINT: + case BUILTIN_LLROUND: case BUILTIN_LOG: case BUILTIN_LOG2: case BUILTIN_LOG10: - case BUILTIN_ABS: + case BUILTIN_LRINT: + case BUILTIN_LROUND: + case BUILTIN_NEARBYINT: + case BUILTIN_RINT: + case BUILTIN_ROUND: + case BUILTIN_ROUNDEVEN: + case BUILTIN_SIN: + case BUILTIN_SQRT: + case BUILTIN_SYSCALL: + case BUILTIN_TRUNC: case BUILTIN_VOLATILE_LOAD: - case BUILTIN_CTPOP: - case BUILTIN_CTTZ: - case BUILTIN_CTLZ: - case BUILTIN_BSWAP: - case BUILTIN_BITREVERSE: return 1; - case BUILTIN_POW: + case BUILTIN_COPYSIGN: case BUILTIN_MAX: case BUILTIN_MIN: + case BUILTIN_POW: case BUILTIN_VOLATILE_STORE: return 2; case BUILTIN_FMA: - case BUILTIN_FSHR: case BUILTIN_FSHL: + case BUILTIN_FSHR: return 3; case BUILTIN_MEMSET: return 5; @@ -2638,8 +2649,8 @@ static inline bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *ex switch (func) { - case BUILTIN_UNREACHABLE: case BUILTIN_TRAP: + case BUILTIN_UNREACHABLE: rtype = type_void; break; case BUILTIN_SYSCLOCK: @@ -2684,25 +2695,36 @@ static inline bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *ex case BUILTIN_STACKTRACE: rtype = type_voidptr; break; - case BUILTIN_CTPOP: - case BUILTIN_CTTZ: - case BUILTIN_CTLZ: case BUILTIN_BITREVERSE: case BUILTIN_BSWAP: + case BUILTIN_CTLZ: + case BUILTIN_CTPOP: + case BUILTIN_CTTZ: if (!sema_check_builtin_args(args, (BuiltinArg[]) { BA_INTLIKE }, arg_count)) return false; rtype = args[0]->type; break; case BUILTIN_CEIL: - case BUILTIN_TRUNC: - case BUILTIN_SQRT: + case BUILTIN_COPYSIGN: case BUILTIN_COS: - case BUILTIN_SIN: case BUILTIN_EXP: + case BUILTIN_EXP2: + case BUILTIN_FLOOR: + case BUILTIN_LLRINT: + case BUILTIN_LLROUND: case BUILTIN_LOG: case BUILTIN_LOG2: case BUILTIN_LOG10: + case BUILTIN_LRINT: + case BUILTIN_LROUND: + case BUILTIN_NEARBYINT: + case BUILTIN_RINT: + case BUILTIN_ROUND: + case BUILTIN_ROUNDEVEN: + case BUILTIN_SIN: + case BUILTIN_SQRT: + case BUILTIN_TRUNC: if (!sema_check_builtin_args(args, (BuiltinArg[]) { BA_FLOATLIKE }, arg_count)) return false; diff --git a/src/compiler/symtab.c b/src/compiler/symtab.c index 177e51946..94ffdbfed 100644 --- a/src/compiler/symtab.c +++ b/src/compiler/symtab.c @@ -175,26 +175,34 @@ void symtab_init(uint32_t capacity) kw_type = KW_DEF("type"); kw_values = KW_DEF("values"); + builtin_list[BUILTIN_ABS] = KW_DEF("abs"); builtin_list[BUILTIN_BITREVERSE] = KW_DEF("bitreverse"); builtin_list[BUILTIN_BSWAP] = KW_DEF("bswap"); builtin_list[BUILTIN_CEIL] = KW_DEF("ceil"); + builtin_list[BUILTIN_COPYSIGN] = KW_DEF("copysign"); builtin_list[BUILTIN_COS] = KW_DEF("cos"); builtin_list[BUILTIN_CTLZ] = KW_DEF("clz"); builtin_list[BUILTIN_CTPOP] = KW_DEF("popcount"); builtin_list[BUILTIN_CTTZ] = KW_DEF("ctz"); builtin_list[BUILTIN_EXP] = KW_DEF("exp"); + builtin_list[BUILTIN_EXP2] = KW_DEF("exp2"); + builtin_list[BUILTIN_FLOOR] = KW_DEF("floor"); builtin_list[BUILTIN_FMA] = KW_DEF("fma"); builtin_list[BUILTIN_FSHL] = KW_DEF("fshl"); builtin_list[BUILTIN_FSHR] = KW_DEF("fshr"); + builtin_list[BUILTIN_LOG] = KW_DEF("log"); builtin_list[BUILTIN_LOG2] = KW_DEF("log2"); builtin_list[BUILTIN_LOG10] = KW_DEF("log10"); - builtin_list[BUILTIN_LOG] = KW_DEF("log"); builtin_list[BUILTIN_MAX] = KW_DEF("max"); builtin_list[BUILTIN_MEMCOPY] = KW_DEF("memcpy"); builtin_list[BUILTIN_MEMSET] = KW_DEF("memset"); builtin_list[BUILTIN_MIN] = KW_DEF("min"); + builtin_list[BUILTIN_NEARBYINT] = KW_DEF("nearbyint"); builtin_list[BUILTIN_POW] = KW_DEF("pow"); + builtin_list[BUILTIN_RINT] = KW_DEF("rint"); + builtin_list[BUILTIN_ROUND] = KW_DEF("round"); + builtin_list[BUILTIN_ROUNDEVEN] = KW_DEF("roundeven"); builtin_list[BUILTIN_SIN] = KW_DEF("sin"); builtin_list[BUILTIN_SQRT] = KW_DEF("sqrt"); builtin_list[BUILTIN_STACKTRACE] = KW_DEF("stacktrace"); @@ -206,6 +214,13 @@ void symtab_init(uint32_t capacity) builtin_list[BUILTIN_VOLATILE_LOAD] = KW_DEF("volatile_load"); builtin_list[BUILTIN_VOLATILE_STORE] = KW_DEF("volatile_store"); +// Disabled for now! + +// builtin_list[BUILTIN_LLRINT] = KW_DEF("llrint"); +// builtin_list[BUILTIN_LLROUND] = KW_DEF("llround"); +// builtin_list[BUILTIN_LRINT] = KW_DEF("lrint"); +// builtin_list[BUILTIN_LROUND] = KW_DEF("lround"); + for (unsigned i = 0; i < NUMBER_OF_BUILTINS; i++) { assert(builtin_list[i] && "Missing builtin"); diff --git a/test/test_suite/builtins/rounding_builtins.c3t b/test/test_suite/builtins/rounding_builtins.c3t new file mode 100644 index 000000000..593c7ec52 --- /dev/null +++ b/test/test_suite/builtins/rounding_builtins.c3t @@ -0,0 +1,48 @@ +// #target: macos-x64 +module test; + +fn void main() +{ + double d = 1.2345; + + double d1 = $$ceil(d); + double d2 = $$floor(d); +// double d3 = $$llrint(d); +// double d4 = $$llround(d); +// double d5 = $$lrint(d); +// double d6 = $$lround(d); + double d7 = $$nearbyint(d); + double d8 = $$rint(d); + double d9 = $$round(d); + double d10 = $$roundeven(d); + + double[<2>] vd = { 1.2345, 0.6789 }; + + double[<2>] vd1 = $$ceil(vd); + double[<2>] vd2 = $$floor(vd); +// double[<2>] vd3 = $$llrint(vd); +// double[<2>] vd4 = $$llround(vd); +// double[<2>] vd5 = $$lrint(vd); +// double[<2>] vd6 = $$lround(vd); + double[<2>] vd7 = $$nearbyint(vd); + double[<2>] vd8 = $$rint(vd); + double[<2>] vd9 = $$round(vd); + double[<2>] vd10 = $$roundeven(vd); + + return; +} + +// #expect: test.ll + + %1 = call double @llvm.ceil.f64(double %0) + %3 = call double @llvm.floor.f64(double %2) + %5 = call double @llvm.nearbyint.f64(double %4) + %7 = call double @llvm.rint.f64(double %6) + %9 = call double @llvm.round.f64(double %8) + %11 = call double @llvm.roundeven.f64(double %10) + %13 = call <2 x double> @llvm.ceil.v2f64(<2 x double> %12) + %15 = call <2 x double> @llvm.floor.v2f64(<2 x double> %14) + %17 = call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %16) + %19 = call <2 x double> @llvm.rint.v2f64(<2 x double> %18) + %21 = call <2 x double> @llvm.round.v2f64(<2 x double> %20) + %23 = call <2 x double> @llvm.roundeven.v2f64(<2 x double> %22) diff --git a/test/test_suite2/builtins/rounding_builtins.c3t b/test/test_suite2/builtins/rounding_builtins.c3t new file mode 100644 index 000000000..593c7ec52 --- /dev/null +++ b/test/test_suite2/builtins/rounding_builtins.c3t @@ -0,0 +1,48 @@ +// #target: macos-x64 +module test; + +fn void main() +{ + double d = 1.2345; + + double d1 = $$ceil(d); + double d2 = $$floor(d); +// double d3 = $$llrint(d); +// double d4 = $$llround(d); +// double d5 = $$lrint(d); +// double d6 = $$lround(d); + double d7 = $$nearbyint(d); + double d8 = $$rint(d); + double d9 = $$round(d); + double d10 = $$roundeven(d); + + double[<2>] vd = { 1.2345, 0.6789 }; + + double[<2>] vd1 = $$ceil(vd); + double[<2>] vd2 = $$floor(vd); +// double[<2>] vd3 = $$llrint(vd); +// double[<2>] vd4 = $$llround(vd); +// double[<2>] vd5 = $$lrint(vd); +// double[<2>] vd6 = $$lround(vd); + double[<2>] vd7 = $$nearbyint(vd); + double[<2>] vd8 = $$rint(vd); + double[<2>] vd9 = $$round(vd); + double[<2>] vd10 = $$roundeven(vd); + + return; +} + +// #expect: test.ll + + %1 = call double @llvm.ceil.f64(double %0) + %3 = call double @llvm.floor.f64(double %2) + %5 = call double @llvm.nearbyint.f64(double %4) + %7 = call double @llvm.rint.f64(double %6) + %9 = call double @llvm.round.f64(double %8) + %11 = call double @llvm.roundeven.f64(double %10) + %13 = call <2 x double> @llvm.ceil.v2f64(<2 x double> %12) + %15 = call <2 x double> @llvm.floor.v2f64(<2 x double> %14) + %17 = call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %16) + %19 = call <2 x double> @llvm.rint.v2f64(<2 x double> %18) + %21 = call <2 x double> @llvm.round.v2f64(<2 x double> %20) + %23 = call <2 x double> @llvm.roundeven.v2f64(<2 x double> %22)