jit: Add a test for compound assignment
authorDavid Malcolm <dmalcolm@redhat.com>
Tue, 16 Jun 2015 19:52:37 +0000 (19:52 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Tue, 16 Jun 2015 19:52:37 +0000 (19:52 +0000)
gcc/testsuite/ChangeLog:
* jit.dg/all-non-failing-tests.h: Add test-compound-assignment.c.
* jit.dg/test-compound-assignment.c: New testcase.

From-SVN: r224536

gcc/testsuite/ChangeLog
gcc/testsuite/jit.dg/all-non-failing-tests.h
gcc/testsuite/jit.dg/test-compound-assignment.c [new file with mode: 0644]

index 260f1a63252862925155770785e81d8c445e4ff5..918cf5283c8b547f9cdfcd7bd626b7c487a6d63b 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-16  David Malcolm  <dmalcolm@redhat.com>
+
+       * jit.dg/all-non-failing-tests.h: Add test-compound-assignment.c.
+       * jit.dg/test-compound-assignment.c: New testcase.
+
 2015-06-16  David Malcolm  <dmalcolm@redhat.com>
 
        PR jit/66539
index 2ac56f23d0104bc98ee0ceb75fb52d17a151213c..389e1c63ff0f7579831843e62e6decb6a7202b66 100644 (file)
 #undef create_code
 #undef verify_code
 
+/* test-compound-assignment.c */
+#define create_code create_code_compound_assignment
+#define verify_code verify_code_compound_assignment
+#include "test-compound-assignment.c"
+#undef create_code
+#undef verify_code
+
 /* test-constants.c */
 #define create_code create_code_constants
 #define verify_code verify_code_constants
@@ -219,6 +226,9 @@ const struct testcase testcases[] = {
   {"calling_function_ptr",
    create_code_calling_function_ptr,
    verify_code_calling_function_ptr},
+  {"compound_assignment",
+   create_code_compound_assignment,
+   verify_code_compound_assignment},
   {"constants",
    create_code_constants,
    verify_code_constants},
diff --git a/gcc/testsuite/jit.dg/test-compound-assignment.c b/gcc/testsuite/jit.dg/test-compound-assignment.c
new file mode 100644 (file)
index 0000000..8b82e09
--- /dev/null
@@ -0,0 +1,157 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+struct assignable_struct
+{
+  int a;
+  char b;
+  float c;
+};
+
+union assignable_union
+{
+  int a;
+  char b;
+  float c;
+};
+
+/* Verify that compound assignment works; let's try to inject the
+   equivalent of:
+
+     struct assignable_struct
+     test_struct_assignment (struct assignable_struct x)
+     {
+       struct assignable_struct y, z;
+       y = x;
+       z = y;
+       return z;
+     }
+
+   and the same, for "union assignable_union".  */
+
+/* Make the type "struct assignable_struct" or "union assignable_union".  */
+
+static gcc_jit_type *
+make_type (gcc_jit_context *ctxt, int make_union)
+{
+  gcc_jit_type *t_int =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+  gcc_jit_type *t_char =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR);
+  gcc_jit_type *t_float =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
+
+  gcc_jit_field *a =
+    gcc_jit_context_new_field (ctxt,
+                              NULL,
+                              t_int,
+                              "a");
+  gcc_jit_field *b =
+    gcc_jit_context_new_field (ctxt,
+                              NULL,
+                              t_char,
+                              "b");
+  gcc_jit_field *c =
+    gcc_jit_context_new_field (ctxt,
+                              NULL,
+                              t_float,
+                              "c");
+  gcc_jit_field *fields[] = {a, b, c};
+  if (make_union)
+      return gcc_jit_context_new_union_type (ctxt, NULL,
+                                            "assignable_union",
+                                            3, fields);
+  else
+    return gcc_jit_struct_as_type (
+      gcc_jit_context_new_struct_type (ctxt, NULL,
+                                      "assignable_struct",
+                                      3, fields));
+}
+
+static void
+make_function (gcc_jit_context *ctxt, int make_union, const char *funcname)
+{
+  gcc_jit_type *test_type = make_type (ctxt, make_union);
+  gcc_jit_param *x =
+    gcc_jit_context_new_param (ctxt, NULL,
+                              test_type, "x");
+  gcc_jit_function *fn =
+    gcc_jit_context_new_function (ctxt, NULL,
+                                 GCC_JIT_FUNCTION_EXPORTED,
+                                 test_type,
+                                 funcname,
+                                 1, &x,
+                                 0);
+  gcc_jit_lvalue *y =
+    gcc_jit_function_new_local (fn, NULL, test_type, "y");
+  gcc_jit_lvalue *z =
+    gcc_jit_function_new_local (fn, NULL, test_type, "z");
+  gcc_jit_block *block =
+    gcc_jit_function_new_block (fn, NULL);
+  gcc_jit_block_add_assignment (block, NULL,
+                               y, gcc_jit_param_as_rvalue (x));
+  gcc_jit_block_add_assignment (block, NULL,
+                               z, gcc_jit_lvalue_as_rvalue (y));
+  gcc_jit_block_end_with_return (block, NULL,
+                                gcc_jit_lvalue_as_rvalue (z));
+}
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  make_function (ctxt, 0, "test_struct_assignment");
+  make_function (ctxt, 1, "test_union_assignment");
+}
+
+static void
+verify_test_struct_assignment (gcc_jit_result *result)
+{
+  typedef struct assignable_struct (*fn_type) (struct assignable_struct);
+  fn_type test_struct_assignment =
+    (fn_type)gcc_jit_result_get_code (result, "test_struct_assignment");
+  CHECK_NON_NULL (test_struct_assignment);
+
+  struct assignable_struct s, t;
+  s.a = 500;
+  s.b = 'A';
+  s.c = 1.0;
+  t = test_struct_assignment (s);
+  CHECK_VALUE (t.a, 500);
+  CHECK_VALUE (t.b, 'A');
+  CHECK_VALUE (t.c, 1.0);
+}
+
+static void
+verify_test_union_assignment (gcc_jit_result *result)
+{
+  typedef union assignable_union (*fn_type) (union assignable_union);
+  fn_type test_union_assignment =
+    (fn_type)gcc_jit_result_get_code (result, "test_union_assignment");
+  CHECK_NON_NULL (test_union_assignment);
+
+  union assignable_union p, q;
+
+  p.a = 500;
+  q = test_union_assignment (p);
+  CHECK_VALUE (q.a, 500);
+
+  p.b = 'A';
+  q = test_union_assignment (p);
+  CHECK_VALUE (q.b, 'A');
+
+  p.c = 1.0;
+  q = test_union_assignment (p);
+  CHECK_VALUE (q.c, 1.0);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+  verify_test_struct_assignment (result);
+  verify_test_union_assignment (result);
+}