This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[jit] Support floating-point division; add test-quadratic.c


Committed to branch dmalcolm/jit:

Add testcase test-quadratic.c, written to achieve test coverage of
gcc_jit_rvalue_access_field - with this commit, the test suite has at
least one call to every public symbol in the API.

In the process, I found that GCC_JIT_BINARY_OP_DIVIDE on
floating-point types would lead to a crash when expanding gimple to RTL,
since the use of TRUNC_DIV_EXPR requires integer args.  (Violating this
assumption led to a crash when the division by 2 was turned into a shift,
which the RTL expander assumes is on an integer).

Hence we update GCC_JIT_BINARY_OP_DIVIDE to internally pick either
RDIV_EXPR (floating point division) or TRUNC_DIV_EXPR (truncation towards
zero) based on the result-type of the binary op (my intent being to be
least-surprising to a C programmer).

gcc/jit/
	* libgccjit.h (enum gcc_jit_binary_op): We will use the result
	type to determine if GCC_JIT_BINARY_OP_DIVIDE should
	truncate towards zero, or be floating-point division.

	* internal-api.c (gcc::jit::context::new_binary_op): Likewise.

gcc/testsuite/
	* jit.dg/test-quadratic.c: New test case, written to achieve test
	coverage of gcc_jit_rvalue_access_field, but also exercising
	division of doubles.

	* jit.dg/test-combination.c: Add test-quadratic.c

	* jit.dg/test-expressions.c: Add TODOs.
---
 gcc/jit/ChangeLog.jit                   |   8 +
 gcc/jit/internal-api.c                  |   8 +-
 gcc/jit/libgccjit.h                     |  12 +-
 gcc/testsuite/ChangeLog.jit             |  10 +
 gcc/testsuite/jit.dg/test-combination.c |   7 +
 gcc/testsuite/jit.dg/test-expressions.c |   3 +
 gcc/testsuite/jit.dg/test-quadratic.c   | 488 ++++++++++++++++++++++++++++++++
 7 files changed, 532 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/jit.dg/test-quadratic.c

diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index cdf9ddb..f13d0c5 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,5 +1,13 @@
 2014-01-24  David Malcolm  <dmalcolm@redhat.com>
 
+	* libgccjit.h (enum gcc_jit_binary_op): We will use the result
+	type to determine if GCC_JIT_BINARY_OP_DIVIDE should
+	truncate towards zero, or be floating-point division.
+
+	* internal-api.c (gcc::jit::context::new_binary_op): Likewise.
+
+2014-01-24  David Malcolm  <dmalcolm@redhat.com>
+
 	* internal-api.h (gcc::jit::context::get_str_option): New access
 	method.
 	(gcc::jit::context::get_int_option): Likewise.
diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c
index 32af625..f95c09f 100644
--- a/gcc/jit/internal-api.c
+++ b/gcc/jit/internal-api.c
@@ -479,9 +479,13 @@ new_binary_op (location *loc,
       break;
 
     case GCC_JIT_BINARY_OP_DIVIDE:
-      inner_op = TRUNC_DIV_EXPR;
+      if (FLOAT_TYPE_P (result_type->as_tree ()))
+	/* Floating-point division: */
+	inner_op = RDIV_EXPR;
+      else
+	/* Truncating to zero: */
+	inner_op = TRUNC_DIV_EXPR;
       break;
-      /* do we want separate floor divide vs frac divide? */
 
     case GCC_JIT_BINARY_OP_MODULO:
       inner_op = TRUNC_MOD_EXPR;
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index baf1541..dd287e8 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -497,9 +497,17 @@ enum gcc_jit_binary_op
 
   /* Quotient of division of arithmetic values; analogous to:
        (EXPR_A) / (EXPR_B)
-     in C.  */
+     in C.
+     The result type affects the kind of division: if the result type is
+     integer-based, then the result is truncated towards zero, whereas
+     a floating-point result type indicates floating-point division.  */
   GCC_JIT_BINARY_OP_DIVIDE,
-  /* do we want separate floor divide vs frac divide? */
+
+  /* Quotient of division of floating-point values, without rounding;
+     analogous to:
+       (EXPR_A) / (EXPR_B)
+     in C.  */
+  GCC_JIT_BINARY_OP_FLOATING_DIVIDE,
 
   /* Remainder of division of arithmetic values; analogous to:
        (EXPR_A) / (EXPR_B)
diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit
index 5cd4a63..02e73c7 100644
--- a/gcc/testsuite/ChangeLog.jit
+++ b/gcc/testsuite/ChangeLog.jit
@@ -1,5 +1,15 @@
 2014-01-23  David Malcolm  <dmalcolm@redhat.com>
 
+	* jit.dg/test-quadratic.c: New test case, written to achieve test
+	coverage of gcc_jit_rvalue_access_field, but also exercising
+	division of doubles.
+
+	* jit.dg/test-combination.c: Add test-quadratic.c
+
+	* jit.dg/test-expressions.c: Add TODOs.
+
+2014-01-23  David Malcolm  <dmalcolm@redhat.com>
+
 	* jit.dg/test-reading-struct.c: New test, to provide test coverage
 	of gcc_jit_type_get_const and gcc_jit_lvalue_access_field, in the
 	process uncovering bugs in how locals were handled.
diff --git a/gcc/testsuite/jit.dg/test-combination.c b/gcc/testsuite/jit.dg/test-combination.c
index 6a2372f..562f031 100644
--- a/gcc/testsuite/jit.dg/test-combination.c
+++ b/gcc/testsuite/jit.dg/test-combination.c
@@ -59,6 +59,13 @@
 #undef code_making_callback
 #undef verify_code
 
+/* test-quadratic.c */
+#define code_making_callback code_making_callback_quadratic
+#define verify_code verify_code_quadratic
+#include "test-quadratic.c"
+#undef code_making_callback
+#undef verify_code
+
 /* test-reading-struct.c */
 #define code_making_callback code_making_callback_reading_struct
 #define verify_code verify_code_reading_struct
diff --git a/gcc/testsuite/jit.dg/test-expressions.c b/gcc/testsuite/jit.dg/test-expressions.c
index c270082..b224347 100644
--- a/gcc/testsuite/jit.dg/test-expressions.c
+++ b/gcc/testsuite/jit.dg/test-expressions.c
@@ -158,6 +158,7 @@ make_tests_of_binary_ops (gcc_jit_context *ctxt)
 			  int_type,
 			  GCC_JIT_BINARY_OP_DIVIDE,
 			  "test_BINARY_OP_DIVIDE_on_int");
+  /* TODO: test for DIVIDE on float or double */
   make_test_of_binary_op (ctxt,
 			  int_type,
 			  GCC_JIT_BINARY_OP_MODULO,
@@ -226,6 +227,8 @@ verify_binary_ops (gcc_jit_result *result)
   CHECK_VALUE (test_BINARY_OP_DIVIDE_on_int (-1, -4), (-1 / -4));
   CHECK_VALUE (test_BINARY_OP_DIVIDE_on_int (60, 5), 12);
 
+  /* TODO: test for DIVIDE on float or double */
+
   test_fn test_BINARY_OP_MODULO_on_int =
     (test_fn)gcc_jit_result_get_code (result,
 				      "test_BINARY_OP_MODULO_on_int");
diff --git a/gcc/testsuite/jit.dg/test-quadratic.c b/gcc/testsuite/jit.dg/test-quadratic.c
new file mode 100644
index 0000000..7b154fe
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-quadratic.c
@@ -0,0 +1,488 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+struct quadratic
+{
+  double a;
+  double b;
+  double c;
+  double discriminant;
+};
+
+/* Let's try to inject the equivalent of:
+
+     extern double sqrt (double);
+
+     void
+     calc_discriminant (struct quadratic *q)
+     {
+       // (b^2 - 4ac)
+       q->discriminant = (q->b * q->b) - (4 * q->a * q->c);
+     }
+
+     int
+     test_quadratic (double a, double b, double c, double *r1, double *r2)
+     {
+       struct quadratic q;
+       q.a = a;
+       q.b = b;
+       q.c = c;
+       calc_discriminant (&q);
+       if (q.discriminant > 0)
+	 {
+	    double s = sqrt (q.discriminant);
+	    *r1 = (-b + s) / (2 * a);
+	    *r2 = (-b - s) / (2 * a);
+	    return 2;
+	 }
+       else if (q.discriminant == 0)
+	 {
+	    *r1 = -b / (2 * a);
+	    return 1;
+	 }
+	 else return 0;
+     }
+*/
+
+struct quadratic_test
+{
+  gcc_jit_context *ctxt;
+
+  /* "double" and "(double *)".  */
+  gcc_jit_type *numeric_type;
+  gcc_jit_type *numeric_type_ptr;
+
+  /* The value (double)0.  */
+  gcc_jit_rvalue *zero;
+
+  gcc_jit_type *int_type;
+
+  /* "struct quadratic" */
+  gcc_jit_type *quadratic;
+  gcc_jit_field *a;
+  gcc_jit_field *b;
+  gcc_jit_field *c;
+  gcc_jit_field *discriminant;
+
+  /* "(struct quadratic *)" */
+  gcc_jit_type *quadratic_ptr;
+
+  gcc_jit_function *calc_discriminant;
+
+  gcc_jit_function *sqrt;
+
+};
+
+static void
+make_types (struct quadratic_test *testcase)
+{
+  testcase->numeric_type =
+    gcc_jit_context_get_type (testcase->ctxt, GCC_JIT_TYPE_DOUBLE);
+  testcase->numeric_type_ptr =
+    gcc_jit_type_get_pointer (testcase->numeric_type);
+  testcase->zero =
+    gcc_jit_context_zero (testcase->ctxt, testcase->numeric_type);
+
+  testcase->int_type =
+    gcc_jit_context_get_type (testcase->ctxt, GCC_JIT_TYPE_INT);
+
+  testcase->a =
+    gcc_jit_context_new_field (testcase->ctxt,
+			       NULL,
+			       testcase->numeric_type,
+			       "a");
+  testcase->b =
+    gcc_jit_context_new_field (testcase->ctxt,
+			       NULL,
+			       testcase->numeric_type,
+			       "b");
+  testcase->c =
+    gcc_jit_context_new_field (testcase->ctxt,
+			       NULL,
+			       testcase->numeric_type,
+			       "c");
+  testcase->discriminant =
+    gcc_jit_context_new_field (testcase->ctxt,
+			       NULL,
+			       testcase->numeric_type,
+			       "discriminant");
+  gcc_jit_field *fields[] = {testcase->a,
+			     testcase->b,
+			     testcase->c,
+			     testcase->discriminant};
+  testcase->quadratic =
+    gcc_jit_context_new_struct_type (testcase->ctxt, NULL,
+				     "quadratic", 4, fields);
+  testcase->quadratic_ptr = gcc_jit_type_get_pointer (testcase->quadratic);
+}
+
+static void
+make_sqrt (struct quadratic_test *testcase)
+{
+  gcc_jit_param *param_x =
+    gcc_jit_context_new_param (testcase->ctxt, NULL,
+			       testcase->numeric_type, "x");
+  testcase->sqrt =
+    gcc_jit_context_new_function (testcase->ctxt, NULL,
+				  GCC_JIT_FUNCTION_IMPORTED,
+				  testcase->numeric_type,
+				  "sqrt",
+				  1, &param_x,
+				  0);
+}
+
+static void
+make_calc_discriminant (struct quadratic_test *testcase)
+{
+  /* Build "calc_discriminant".  */
+  gcc_jit_param *param_q =
+    gcc_jit_context_new_param (testcase->ctxt, NULL,
+			       testcase->quadratic_ptr, "q");
+  testcase->calc_discriminant =
+    gcc_jit_context_new_function (testcase->ctxt, NULL,
+				  GCC_JIT_FUNCTION_EXPORTED,
+				  testcase->numeric_type,
+				  "calc_discriminant",
+				  1, &param_q,
+				  0);
+  gcc_jit_function_add_comment (
+    testcase->calc_discriminant, NULL,
+    "(b^2 - 4ac)");
+
+  gcc_jit_rvalue *q_a =
+    gcc_jit_lvalue_as_rvalue (
+	gcc_jit_rvalue_dereference_field (
+	  gcc_jit_param_as_rvalue (param_q),
+	  NULL, "a"));
+  gcc_jit_rvalue *q_b =
+    gcc_jit_lvalue_as_rvalue (
+	gcc_jit_rvalue_dereference_field (
+	  gcc_jit_param_as_rvalue (param_q),
+	  NULL, "b"));
+  gcc_jit_rvalue *q_c =
+    gcc_jit_lvalue_as_rvalue (
+	gcc_jit_rvalue_dereference_field (
+	  gcc_jit_param_as_rvalue (param_q),
+	  NULL, "c"));
+
+  gcc_jit_function_add_assignment (
+    testcase->calc_discriminant, NULL,
+
+    /* q->discriminant =...  */
+    gcc_jit_rvalue_dereference_field (
+      gcc_jit_param_as_rvalue (param_q),
+      NULL,
+      "discriminant"),
+
+    /* (q->b * q->b) - (4 * q->a * q->c) */
+    gcc_jit_context_new_binary_op (
+      testcase->ctxt, NULL,
+      GCC_JIT_BINARY_OP_MINUS,
+      testcase->numeric_type,
+
+      /* (q->b * q->b) */
+      gcc_jit_context_new_binary_op (
+	testcase->ctxt, NULL,
+	GCC_JIT_BINARY_OP_MULT,
+	testcase->numeric_type,
+	q_b, q_b),
+
+      /* (4 * (q->a * q->c)) */
+      gcc_jit_context_new_binary_op (
+	testcase->ctxt, NULL,
+	GCC_JIT_BINARY_OP_MULT,
+	testcase->numeric_type,
+	/* 4.0 */
+	gcc_jit_context_new_rvalue_from_int (
+	  testcase->ctxt,
+	  testcase->numeric_type,
+	  4),
+	/* (q->a * q->c) */
+	gcc_jit_context_new_binary_op (
+	  testcase->ctxt, NULL,
+	  GCC_JIT_BINARY_OP_MULT,
+	  testcase->numeric_type,
+	  q_a, q_c)))); /* end of gcc_jit_function_add_assignment call.  */
+}
+
+static void
+make_test_quadratic (struct quadratic_test *testcase)
+{
+  gcc_jit_param *a =
+    gcc_jit_context_new_param (testcase->ctxt, NULL,
+			       testcase->numeric_type, "a");
+  gcc_jit_param *b =
+    gcc_jit_context_new_param (testcase->ctxt, NULL,
+			       testcase->numeric_type, "b");
+  gcc_jit_param *c =
+    gcc_jit_context_new_param (testcase->ctxt, NULL,
+			       testcase->numeric_type, "c");
+  gcc_jit_param *r1 =
+    gcc_jit_context_new_param (testcase->ctxt, NULL,
+			       testcase->numeric_type_ptr, "r1");
+  gcc_jit_param *r2 =
+    gcc_jit_context_new_param (testcase->ctxt, NULL,
+			       testcase->numeric_type_ptr, "r2");
+  gcc_jit_param *params[] = {a, b, c, r1, r2};
+  gcc_jit_function *test_quadratic =
+    gcc_jit_context_new_function (testcase->ctxt, NULL,
+				  GCC_JIT_FUNCTION_EXPORTED,
+				  testcase->int_type,
+				  "test_quadratic",
+				  5, params,
+				  0);
+
+  /* struct quadratic q; */
+  gcc_jit_lvalue *q =
+    gcc_jit_function_new_local (
+      test_quadratic, NULL,
+      testcase->quadratic,
+      "q");
+  /* q.a = a; */
+  gcc_jit_function_add_assignment (
+    test_quadratic, NULL,
+    gcc_jit_lvalue_access_field (q, NULL, "a"),
+    gcc_jit_param_as_rvalue (a));
+  /* q.b = b; */
+  gcc_jit_function_add_assignment (
+    test_quadratic, NULL,
+    gcc_jit_lvalue_access_field (q, NULL, "b"),
+    gcc_jit_param_as_rvalue (b));
+  /* q.c = c; */
+  gcc_jit_function_add_assignment (
+    test_quadratic, NULL,
+    gcc_jit_lvalue_access_field (q, NULL, "c"),
+    gcc_jit_param_as_rvalue (c));
+  /* calc_discriminant (&q); */
+  gcc_jit_rvalue *address_of_q = gcc_jit_lvalue_get_address (q, NULL);
+  gcc_jit_function_add_eval (
+    test_quadratic, NULL,
+    gcc_jit_context_new_call (
+      testcase->ctxt, NULL,
+      testcase->calc_discriminant,
+      1, &address_of_q));
+
+  gcc_jit_label *on_positive_discriminant
+    = gcc_jit_function_new_forward_label (test_quadratic,
+					  "positive_discriminant");
+
+  gcc_jit_label *on_nonpositive_discriminant
+    = gcc_jit_function_new_forward_label (test_quadratic,
+					  "nonpositive_discriminant");
+
+  gcc_jit_label *on_zero_discriminant
+    = gcc_jit_function_new_forward_label (test_quadratic,
+					  "zero_discriminant");
+
+  gcc_jit_label *on_negative_discriminant
+    = gcc_jit_function_new_forward_label (test_quadratic,
+					  "negative_discriminant");
+
+  gcc_jit_function_add_comment (
+    test_quadratic, NULL,
+    "if (q.discriminant > 0)");
+  gcc_jit_function_add_conditional (
+    test_quadratic, NULL,
+    gcc_jit_context_new_comparison (
+      testcase->ctxt, NULL,
+      GCC_JIT_COMPARISON_GT,
+      gcc_jit_rvalue_access_field (
+	gcc_jit_lvalue_as_rvalue (q),
+	NULL,
+	"discriminant"),
+      testcase->zero),
+    on_positive_discriminant,
+    on_nonpositive_discriminant);
+
+  gcc_jit_function_place_forward_label (
+    test_quadratic, NULL,
+    on_positive_discriminant);
+  /* double s = sqrt (q.discriminant); */
+  gcc_jit_lvalue *s = gcc_jit_function_new_local (
+    test_quadratic, NULL,
+    testcase->numeric_type,
+    "s");
+  gcc_jit_rvalue *discriminant_of_q =
+    gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (q),
+				 NULL,
+				 "discriminant");
+  gcc_jit_function_add_assignment (
+    test_quadratic, NULL,
+    s,
+    gcc_jit_context_new_call (
+      testcase->ctxt, NULL,
+      testcase->sqrt,
+      1, &discriminant_of_q));
+
+  gcc_jit_rvalue *minus_b =
+    gcc_jit_context_new_unary_op (
+      testcase->ctxt, NULL,
+      GCC_JIT_UNARY_OP_MINUS,
+      testcase->numeric_type,
+      gcc_jit_param_as_rvalue (b));
+  gcc_jit_rvalue *two_a =
+    gcc_jit_context_new_binary_op (
+      testcase->ctxt, NULL,
+      GCC_JIT_BINARY_OP_MULT,
+      testcase->numeric_type,
+      gcc_jit_context_new_rvalue_from_int (
+	testcase->ctxt,
+	testcase->numeric_type,
+	2),
+      gcc_jit_param_as_rvalue (a));
+
+  gcc_jit_function_add_comment (
+    test_quadratic, NULL,
+    "*r1 = (-b + s) / (2 * a);");
+  gcc_jit_function_add_assignment (
+    test_quadratic, NULL,
+
+    /* "*r1 = ..." */
+    gcc_jit_rvalue_dereference (
+      gcc_jit_param_as_rvalue (r1), NULL),
+
+    /* (-b + s) / (2 * a) */
+    gcc_jit_context_new_binary_op (
+      testcase->ctxt, NULL,
+      GCC_JIT_BINARY_OP_DIVIDE,
+      testcase->numeric_type,
+      gcc_jit_context_new_binary_op (
+	testcase->ctxt, NULL,
+	GCC_JIT_BINARY_OP_PLUS,
+	testcase->numeric_type,
+	minus_b,
+	gcc_jit_lvalue_as_rvalue (s)),
+      two_a));
+
+  gcc_jit_function_add_comment (
+    test_quadratic, NULL,
+    "*r2 = (-b - s) / (2 * a)");
+  gcc_jit_function_add_assignment (
+    test_quadratic, NULL,
+
+    /* "*r2 = ..." */
+    gcc_jit_rvalue_dereference (
+      gcc_jit_param_as_rvalue (r2), NULL),
+
+    /* (-b - s) / (2 * a) */
+    gcc_jit_context_new_binary_op (
+      testcase->ctxt, NULL,
+      GCC_JIT_BINARY_OP_DIVIDE,
+      testcase->numeric_type,
+      gcc_jit_context_new_binary_op (
+	testcase->ctxt, NULL,
+	GCC_JIT_BINARY_OP_MINUS,
+	testcase->numeric_type,
+	minus_b,
+	gcc_jit_lvalue_as_rvalue (s)),
+      two_a));
+
+  /* "return 2;" */
+  gcc_jit_function_add_return (
+    test_quadratic, NULL,
+    gcc_jit_context_new_rvalue_from_int (
+      testcase->ctxt,
+      testcase->int_type,
+      2));
+
+  /* "else if (q.discriminant == 0)" */
+  gcc_jit_function_place_forward_label (
+    test_quadratic, NULL,
+    on_nonpositive_discriminant);
+  gcc_jit_function_add_comment (
+    test_quadratic, NULL,
+    "else if (q.discriminant == 0)");
+  gcc_jit_function_add_conditional (
+    test_quadratic, NULL,
+    gcc_jit_context_new_comparison (
+      testcase->ctxt, NULL,
+      GCC_JIT_COMPARISON_EQ,
+      gcc_jit_rvalue_access_field (
+	gcc_jit_lvalue_as_rvalue (q),
+	NULL,
+	"discriminant"),
+      testcase->zero),
+    on_zero_discriminant,
+    on_negative_discriminant);
+
+  /* if (q.discriminant == 0) */
+  gcc_jit_function_place_forward_label (
+    test_quadratic, NULL,
+    on_zero_discriminant);
+
+  gcc_jit_function_add_comment (
+    test_quadratic, NULL,
+    "*r1 = -b / (2 * a);");
+  gcc_jit_function_add_assignment (
+    test_quadratic, NULL,
+
+    /* "*r1 = ..." */
+    gcc_jit_rvalue_dereference (
+      gcc_jit_param_as_rvalue (r1), NULL),
+
+    /* -b / (2 * a) */
+    gcc_jit_context_new_binary_op (
+      testcase->ctxt, NULL,
+      GCC_JIT_BINARY_OP_DIVIDE,
+      testcase->numeric_type,
+      minus_b,
+      two_a));
+
+  /* "return 1;" */
+  gcc_jit_function_add_return (
+    test_quadratic, NULL,
+      gcc_jit_context_one (testcase->ctxt, testcase->int_type));
+
+  /* else return 0; */
+  gcc_jit_function_place_forward_label (
+    test_quadratic, NULL,
+    on_negative_discriminant);
+  gcc_jit_function_add_return (
+    test_quadratic, NULL,
+    gcc_jit_context_zero (testcase->ctxt, testcase->int_type));
+}
+
+int
+code_making_callback (gcc_jit_context *ctxt, void *user_data)
+{
+  struct quadratic_test testcase;
+  memset (&testcase, 0, sizeof (testcase));
+  testcase.ctxt = ctxt;
+  make_types (&testcase);
+  make_sqrt (&testcase);
+  make_calc_discriminant (&testcase);
+  make_test_quadratic (&testcase);
+  return 0;
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  typedef int (*fn_type) (double a, double b, double c,
+			  double *r1, double *r2);
+
+  CHECK_NON_NULL (result);
+
+  fn_type test_quadratic =
+    (fn_type)gcc_jit_result_get_code (result, "test_quadratic");
+  CHECK_NON_NULL (test_quadratic);
+
+  /* Verify that the code correctly solves quadratic equations.  */
+  double r1, r2;
+
+  /* This one has two solutions: */
+  CHECK_VALUE (test_quadratic (1, 3, -4, &r1, &r2), 2);
+  CHECK_VALUE (r1, 1);
+  CHECK_VALUE (r2, -4);
+
+  /* This one has one solution: */
+  CHECK_VALUE (test_quadratic (4, 4, 1, &r1, &r2), 1);
+  CHECK_VALUE (r1, -0.5);
+
+  /* This one has no real solutions: */
+  CHECK_VALUE (test_quadratic (4, 1, 1, &r1, &r2), 0);
+}
-- 
1.7.11.7


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]