* [PATCH 0/4] expansion of builtin FP predicates (isinf(), ...)
@ 2018-02-17 14:56 Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 1/4] builtin: extract eval_args() from arguments_choose() Luc Van Oostenryck
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2018-02-17 14:56 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
These patches add proper typechecking to built-in floating-point
predicates like __builtin_isinf(). They also are an excuse to put
in place a bit more infrastructure for complete handling of builtins.
This series is available in the Git repository at:
https://github.com/lucvoo/sparse-dev/tree/builtin-fp
git://github.com/lucvoo/sparse-dev.git builtin-fp
----------------------------------------------------------------
Luc Van Oostenryck (4):
builtin: extract eval_args() from arguments_choose()
builtin: add typechecking of isnan(), isinf(), ...
builtin: add testcases for expansion of special FP constants
builtin: add testcases for expansion of FP classification
builtin.c | 79 +++++++++++++++++++++-------
validation/builtin-fp-unop.c | 95 ++++++++++++++++++++++++++++++++++
validation/expand/builtin_fpclassify.c | 26 ++++++++++
validation/expand/builtin_huge_val.c | 39 ++++++++++++++
validation/expand/builtin_isinf.c | 20 +++++++
validation/expand/builtin_isnan.c | 20 +++++++
validation/expand/builtin_isnormal.c | 20 +++++++
validation/expand/builtin_nan.c | 23 ++++++++
8 files changed, 303 insertions(+), 19 deletions(-)
create mode 100644 validation/builtin-fp-unop.c
create mode 100644 validation/expand/builtin_fpclassify.c
create mode 100644 validation/expand/builtin_huge_val.c
create mode 100644 validation/expand/builtin_isinf.c
create mode 100644 validation/expand/builtin_isnan.c
create mode 100644 validation/expand/builtin_isnormal.c
create mode 100644 validation/expand/builtin_nan.c
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/4] builtin: extract eval_args() from arguments_choose()
2018-02-17 14:56 [PATCH 0/4] expansion of builtin FP predicates (isinf(), ...) Luc Van Oostenryck
@ 2018-02-17 14:56 ` Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 2/4] builtin: add typechecking of isnan(), isinf(), Luc Van Oostenryck
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2018-02-17 14:56 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
Almost the same code is needed for others builtins, only
with another function name a arguments number.
So, extract this into a generic helper.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
builtin.c | 49 ++++++++++++++++++++++++++++++-------------------
1 file changed, 30 insertions(+), 19 deletions(-)
diff --git a/builtin.c b/builtin.c
index f5ea06ab9..9aa109d15 100644
--- a/builtin.c
+++ b/builtin.c
@@ -51,6 +51,35 @@ static int evaluate_pure_unop(struct expression *expr)
return 1;
}
+/*
+ * eval_args - check the number of arguments and evaluate them.
+ */
+static int eval_args(struct expression *expr, int n)
+{
+ struct expression *arg;
+ struct symbol *sym;
+ const char *msg;
+ int rc = 1;
+
+ FOR_EACH_PTR(expr->args, arg) {
+ if (n-- == 0) {
+ msg = "too many arguments";
+ goto error;
+ }
+ if (!evaluate_expression(arg))
+ rc = 0;
+ } END_FOR_EACH_PTR(arg);
+ if (n > 0) {
+ msg = "not enough arguments";
+ goto error;
+ }
+ return rc;
+
+error:
+ sym = expr->fn->ctype;
+ expression_error(expr, "%s for %s", msg, show_ident(sym->ident));
+ return 0;
+}
static int evaluate_expect(struct expression *expr)
{
@@ -61,25 +90,7 @@ static int evaluate_expect(struct expression *expr)
static int arguments_choose(struct expression *expr)
{
- struct expression_list *arglist = expr->args;
- struct expression *arg;
- int i = 0;
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/4] builtin: add typechecking of isnan(), isinf(), ...
2018-02-17 14:56 [PATCH 0/4] expansion of builtin FP predicates (isinf(), ...) Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 1/4] builtin: extract eval_args() from arguments_choose() Luc Van Oostenryck
@ 2018-02-17 14:56 ` Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 3/4] builtin: add testcases for expansion of special FP constants Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 4/4] builtin: add testcases for expansion of FP classification Luc Van Oostenryck
3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2018-02-17 14:56 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
These builtins should accept a single argument of any
floating-point type and should not do the usual promotion
of float to double.
Add the type and argument number check in the builtin's
evaluate method.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
builtin.c | 30 ++++++++++++++
validation/builtin-fp-unop.c | 95 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 125 insertions(+)
create mode 100644 validation/builtin-fp-unop.c
diff --git a/builtin.c b/builtin.c
index 9aa109d15..dc5f4a68f 100644
--- a/builtin.c
+++ b/builtin.c
@@ -237,6 +237,27 @@ static struct symbol_op bswap_op = {
};
+static int evaluate_fp_unop(struct expression *expr)
+{
+ struct expression *arg;
+
+ if (!eval_args(expr, 1))
+ return 0;
+
+ arg = first_expression(expr->args);
+ if (!is_float_type(arg->ctype)) {
+ expression_error(expr, "non-floating-point argument in call to %s()",
+ show_ident(expr->fn->ctype->ident));
+ return 0;
+ }
+ return 1;
+}
+
+static struct symbol_op fp_unop_op = {
+ .evaluate = evaluate_fp_unop,
+};
+
+
/*
* Builtin functions
*/
@@ -255,6 +276,12 @@ static struct sym_init {
{ "__builtin_bswap16", &builtin_fn_type, MOD_TOPLEVEL, &bswap_op },
{ "__builtin_bswap32", &builtin_fn_type, MOD_TOPLEVEL, &bswap_op },
{ "__builtin_bswap64", &builtin_fn_type, MOD_TOPLEVEL, &bswap_op },
+ { "__builtin_isfinite", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op },
+ { "__builtin_isinf", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op },
+ { "__builtin_isinf_sign", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op },
+ { "__builtin_isnan", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op },
+ { "__builtin_isnormal", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op },
+ { "__builtin_signbit", &builtin_fn_type, MOD_TOPLEVEL, &fp_unop_op },
{ NULL, NULL, 0 }
};
@@ -343,11 +370,13 @@ void declare_builtins(void)
declare_builtin("__builtin_isfinite", &int_ctype, 1, NULL);
declare_builtin("__builtin_isgreater", &int_ctype, 0, &float_ctype, &float_ctype, NULL);
declare_builtin("__builtin_isgreaterequal", &int_ctype, 0, &float_ctype, &float_ctype, NULL);
+ declare_builtin("__builtin_isinf", &int_ctype, 1, NULL);
declare_builtin("__builtin_isinf_sign", &int_ctype, 1, NULL);
declare_builtin("__builtin_isless", &int_ctype, 0, &float_ctype, &float_ctype, NULL);
declare_builtin("__builtin_islessequal", &int_ctype, 0, &float_ctype, &float_ctype, NULL);
declare_builtin("__builtin_islessgreater", &int_ctype, 0, &float_ctype, &float_ctype, NULL);
declare_builtin("__builtin_isnan", &int_ctype, 1, NULL);
+ declare_builtin("__builtin_isnormal", &int_ctype, 1, NULL);
declare_builtin("__builtin_isunordered", &int_ctype, 0, &float_ctype, &float_ctype, NULL);
declare_builtin("__builtin_labs", &long_ctype, 0, &long_ctype, NULL);
declare_builtin("__builtin_llabs", &llong_ctype, 0, &llong_ctype, NULL);
@@ -374,6 +403,7 @@ void declare_builtins(void)
declare_builtin("__builtin_realloc", &ptr_ctype, 0, &ptr_ctype, size_t_ctype, NULL);
declare_builtin("__builtin_return_address", &ptr_ctype, 0, &uint_ctype, NULL);
declare_builtin("__builtin_rindex", &string_ctype, 0, &const_string_ctype, &int_ctype, NULL);
+ declare_builtin("__builtin_signbit", &int_ctype, 1, NULL);
declare_builtin("__builtin_snprintf", &int_ctype, 1, &string_ctype, size_t_ctype, &const_string_ctype, NULL);
declare_builtin("__builtin_sprintf", &int_ctype, 1, &string_ctype, &const_string_ctype, NULL);
declare_builtin("__builtin_stpcpy", &string_ctype, 0, &const_string_ctype, &const_string_ctype, NULL);
diff --git a/validation/builtin-fp-unop.c b/validation/builtin-fp-unop.c
new file mode 100644
index 000000000..f42c587b7
--- /dev/null
+++ b/validation/builtin-fp-unop.c
@@ -0,0 +1,95 @@
+static void test_not_enough_args(void)
+{
+ __builtin_isfinite();
+ __builtin_isinf();
+ __builtin_isinf_sign();
+ __builtin_isnan();
+ __builtin_isnormal();
+ __builtin_signbit();
+}
+
+static void test_too_many_args(double v)
+{
+ __builtin_isfinite(v, v);
+ __builtin_isinf(v, v);
+ __builtin_isinf_sign(v, v);
+ __builtin_isnan(v, v);
+ __builtin_isnormal(v, v);
+ __builtin_signbit(v, v);
+}
+
+static void test_non_float(int v)
+{
+ __builtin_isfinite(v);
+ __builtin_isinf(v);
+ __builtin_isinf_sign(v);
+ __builtin_isnan(v);
+ __builtin_isnormal(v);
+ __builtin_signbit(v);
+}
+
+static void test_float(float v)
+{
+ __builtin_isfinite(v);
+ __builtin_isinf(v);
+ __builtin_isinf_sign(v);
+ __builtin_isnan(v);
+ __builtin_isnormal(v);
+ __builtin_signbit(v);
+}
+
+static void test_double(double v)
+{
+ __builtin_isfinite(v);
+ __builtin_isinf(v);
+ __builtin_isinf_sign(v);
+ __builtin_isnan(v);
+ __builtin_isnormal(v);
+ __builtin_signbit(v);
+}
+
+static void test_ldouble(long double v)
+{
+ __builtin_isfinite(v);
+ __builtin_isinf(v);
+ __builtin_isinf_sign(v);
+ __builtin_isnan(v);
+ __builtin_isnormal(v);
+ __builtin_signbit(v);
+}
+
+static void test_constant(void)
+{
+ __builtin_isfinite(0.0);
+ __builtin_isinf(0.0);
+ __builtin_isinf_sign(0.0);
+ __builtin_isnan(0.0);
+ __builtin_isnormal(0.0);
+ __builtin_signbit(0.0);
+}
+
+/*
+ * check-name: builtin float-point unop
+ * check-command: sparse -Wno-decl $file
+ *
+ * check-error-start
+builtin-fp-unop.c:3:27: error: not enough arguments for __builtin_isfinite
+builtin-fp-unop.c:4:24: error: not enough arguments for __builtin_isinf
+builtin-fp-unop.c:5:29: error: not enough arguments for __builtin_isinf_sign
+builtin-fp-unop.c:6:24: error: not enough arguments for __builtin_isnan
+builtin-fp-unop.c:7:27: error: not enough arguments for __builtin_isnormal
+builtin-fp-unop.c:8:26: error: not enough arguments for __builtin_signbit
+builtin-fp-unop.c:13:27: error: too many arguments for __builtin_isfinite
+builtin-fp-unop.c:14:24: error: too many arguments for __builtin_isinf
+builtin-fp-unop.c:15:29: error: too many arguments for __builtin_isinf_sign
+builtin-fp-unop.c:16:24: error: too many arguments for __builtin_isnan
+builtin-fp-unop.c:17:27: error: too many arguments for __builtin_isnormal
+builtin-fp-unop.c:18:26: error: too many arguments for __builtin_signbit
+builtin-fp-unop.c:23:27: error: non-floating-point argument in call to __builtin_isfinite()
+builtin-fp-unop.c:24:24: error: non-floating-point argument in call to __builtin_isinf()
+builtin-fp-unop.c:25:29: error: non-floating-point argument in call to __builtin_isinf_sign()
+builtin-fp-unop.c:26:24: error: non-floating-point argument in call to __builtin_isnan()
+builtin-fp-unop.c:27:27: error: non-floating-point argument in call to __builtin_isnormal()
+builtin-fp-unop.c:28:26: error: non-floating-point argument in call to __builtin_signbit()
+ * check-error-end
+ */
--
2.16.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/4] builtin: add testcases for expansion of special FP constants
2018-02-17 14:56 [PATCH 0/4] expansion of builtin FP predicates (isinf(), ...) Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 1/4] builtin: extract eval_args() from arguments_choose() Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 2/4] builtin: add typechecking of isnan(), isinf(), Luc Van Oostenryck
@ 2018-02-17 14:56 ` Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 4/4] builtin: add testcases for expansion of FP classification Luc Van Oostenryck
3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2018-02-17 14:56 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
More specifically: for __builtin_nan(), _huge_val() & _inf()
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
validation/expand/builtin_huge_val.c | 39 ++++++++++++++++++++++++++++++++++++
validation/expand/builtin_nan.c | 23 +++++++++++++++++++++
2 files changed, 62 insertions(+)
create mode 100644 validation/expand/builtin_huge_val.c
create mode 100644 validation/expand/builtin_nan.c
diff --git a/validation/expand/builtin_huge_val.c b/validation/expand/builtin_huge_val.c
new file mode 100644
index 000000000..09ef2a6f3
--- /dev/null
+++ b/validation/expand/builtin_huge_val.c
@@ -0,0 +1,39 @@
+static float huge_valf(void)
+{
+ return __builtin_huge_valf();
+}
+
+static double huge_val(void)
+{
+ return __builtin_huge_val();
+}
+
+static long double huge_vall(void)
+{
+ return __builtin_huge_vall();
+}
+
+
+static float inff(void)
+{
+ return __builtin_inff();
+}
+
+static double inf(void)
+{
+ return __builtin_inf();
+}
+
+static long double infl(void)
+{
+ return __builtin_infl();
+}
+
+/*
+ * check-name: builtin_huge_val expand
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-ignore
+ * check-output-excludes: call
+ */
diff --git a/validation/expand/builtin_nan.c b/validation/expand/builtin_nan.c
new file mode 100644
index 000000000..20e3ae925
--- /dev/null
+++ b/validation/expand/builtin_nan.c
@@ -0,0 +1,23 @@
+static float nanf(void)
+{
+ return __builtin_nanf("0");
+}
+
+static double nan(void)
+{
+ return __builtin_nan("0");
+}
+
+static long double nanl(void)
+{
+ return __builtin_nanl("0");
+}
+
+/*
+ * check-name: builtin_nan expand
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-ignore
+ * check-output-excludes: call
+ */
--
2.16.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/4] builtin: add testcases for expansion of FP classification
2018-02-17 14:56 [PATCH 0/4] expansion of builtin FP predicates (isinf(), ...) Luc Van Oostenryck
` (2 preceding siblings ...)
2018-02-17 14:56 ` [PATCH 3/4] builtin: add testcases for expansion of special FP constants Luc Van Oostenryck
@ 2018-02-17 14:56 ` Luc Van Oostenryck
3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2018-02-17 14:56 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
__builtin_isinf(), isnan() & isnormal() are all special cases
of __builtin_fpclassify().
Add a few cases testing if those are correctly expanded if
when the argument is a constant.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
validation/expand/builtin_fpclassify.c | 26 ++++++++++++++++++++++++++
validation/expand/builtin_isinf.c | 20 ++++++++++++++++++++
validation/expand/builtin_isnan.c | 20 ++++++++++++++++++++
validation/expand/builtin_isnormal.c | 20 ++++++++++++++++++++
4 files changed, 86 insertions(+)
create mode 100644 validation/expand/builtin_fpclassify.c
create mode 100644 validation/expand/builtin_isinf.c
create mode 100644 validation/expand/builtin_isnan.c
create mode 100644 validation/expand/builtin_isnormal.c
diff --git a/validation/expand/builtin_fpclassify.c b/validation/expand/builtin_fpclassify.c
new file mode 100644
index 000000000..506927dd3
--- /dev/null
+++ b/validation/expand/builtin_fpclassify.c
@@ -0,0 +1,26 @@
+enum { FP_NAN, FP_INF, FP_NOR, FP_SUB, FP_ZERO };
+
+#define classify(X) __builtin_fpclassify(FP_NAN,FP_INF,FP_NOR,FP_SUB,FP_ZERO,X)
+
+int test(void)
+{
+ if (classify(__builtin_nan("0")) != FP_NAN)
+ return 0;
+ if (classify(__builtin_inf("0")) != FP_INF)
+ return 0;
+ if (classify(1.0) != FP_NOR)
+ return 0;
+ if (classify(0.0) != FP_ZERO)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * check-name: builtin_fpclassify
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-ignore
+ * check-output-contains: ret\\..*\\$1
+ */
diff --git a/validation/expand/builtin_isinf.c b/validation/expand/builtin_isinf.c
new file mode 100644
index 000000000..36b20a60e
--- /dev/null
+++ b/validation/expand/builtin_isinf.c
@@ -0,0 +1,20 @@
+int test(void)
+{
+ if (!__builtin_isinf(__builtin_inff()))
+ return 0;
+ if (!__builtin_isinf(__builtin_inf()))
+ return 0;
+ if (!__builtin_isinf(__builtin_infl()))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * check-name: builtin_isinf expand
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-ignore
+ * check-output-contains: ret\\..*\\$1
+ */
diff --git a/validation/expand/builtin_isnan.c b/validation/expand/builtin_isnan.c
new file mode 100644
index 000000000..07c7e5e54
--- /dev/null
+++ b/validation/expand/builtin_isnan.c
@@ -0,0 +1,20 @@
+int test(void)
+{
+ if (!__builtin_isnan(__builtin_nanf("0")))
+ return 0;
+ if (!__builtin_isnan(__builtin_nan("0")))
+ return 0;
+ if (!__builtin_isnan(__builtin_nanl("0")))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * check-name: builtin_isnan expand
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-ignore
+ * check-output-contains: ret\\..*\\$1
+ */
diff --git a/validation/expand/builtin_isnormal.c b/validation/expand/builtin_isnormal.c
new file mode 100644
index 000000000..0b69e2731
--- /dev/null
+++ b/validation/expand/builtin_isnormal.c
@@ -0,0 +1,20 @@
+int test(void)
+{
+ if (!__builtin_isnormal(1.0F))
+ return 0;
+ if (!__builtin_isnormal(1.0))
+ return 0;
+ if (!__builtin_isnormal(1.0L))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * check-name: builtin_isnormal expand
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-ignore
+ * check-output-contains: ret\\..*\\$1
+ */
--
2.16.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-02-17 14:56 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-17 14:56 [PATCH 0/4] expansion of builtin FP predicates (isinf(), ...) Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 1/4] builtin: extract eval_args() from arguments_choose() Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 2/4] builtin: add typechecking of isnan(), isinf(), Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 3/4] builtin: add testcases for expansion of special FP constants Luc Van Oostenryck
2018-02-17 14:56 ` [PATCH 4/4] builtin: add testcases for expansion of FP classification Luc Van Oostenryck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).