From: Martin Rodriguez Reboredo <[email protected]>

Related to PR d/110516 but for libgccjit.

2024-01-03  Martin Rodriguez Reboredo  <[email protected]>

gcc/jit/ChangeLog:

        * jit-playback.cc: Append TREE_THIS_VOLATILE and TREE_SIDE_EFFECTS
        if underlying type is volatile.

gcc/testsuite/ChangeLog:

        * jit.dg/all-non-failing-tests.h: Mention new tests.
        * jit.dg/test-volatile1.c: New test.
        * jit.dg/test-volatile2.c: New test.
        * jit.dg/test-volatile3.c: New test.
        * jit.dg/test-volatile4.c: New test.
        * jit.dg/test-volatile5.c: New test.

Co-authored-by: Antoni Boucher <[email protected]>
Signed-off-by: Martin Rodriguez Reboredo <[email protected]>
---
 gcc/jit/jit-playback.cc                      | 28 ++++++-
 gcc/testsuite/jit.dg/all-non-failing-tests.h | 35 ++++++++
 gcc/testsuite/jit.dg/test-volatile1.c        | 58 +++++++++++++
 gcc/testsuite/jit.dg/test-volatile2.c        | 82 +++++++++++++++++++
 gcc/testsuite/jit.dg/test-volatile3.c        | 85 ++++++++++++++++++++
 gcc/testsuite/jit.dg/test-volatile4.c        | 70 ++++++++++++++++
 gcc/testsuite/jit.dg/test-volatile5.c        | 60 ++++++++++++++
 7 files changed, 417 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/jit.dg/test-volatile1.c
 create mode 100644 gcc/testsuite/jit.dg/test-volatile2.c
 create mode 100644 gcc/testsuite/jit.dg/test-volatile3.c
 create mode 100644 gcc/testsuite/jit.dg/test-volatile4.c
 create mode 100644 gcc/testsuite/jit.dg/test-volatile5.c

diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index 291ddeb2cca..64f4c4d9557 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -786,6 +786,13 @@ global_new_decl (location *loc,
   if (TYPE_READONLY (type_tree) || readonly)
     TREE_READONLY (inner) = 1;
 
+  if (TYPE_VOLATILE (type_tree))
+  {
+    TREE_THIS_VOLATILE (inner) = 1;
+    TREE_SIDE_EFFECTS (inner) = 1;
+  }
+
+
   if (loc)
     set_tree_location (inner, loc);
 
@@ -1904,8 +1911,16 @@ new_field_access (location *loc,
   gcc_assert (TREE_CODE (type) != POINTER_TYPE);
 
  tree t_field = field->as_tree ();
- tree ref = build3 (COMPONENT_REF, TREE_TYPE (t_field), datum,
+ tree field_type = TREE_TYPE (t_field);
+ tree ref = build3 (COMPONENT_REF, field_type, datum,
 		     t_field, NULL_TREE);
+
+  if (TYPE_VOLATILE (field_type))
+  {
+    TREE_THIS_VOLATILE (datum) = 1;
+    TREE_SIDE_EFFECTS (datum) = 1;
+  }
+
   if (loc)
     set_tree_location (ref, loc);
   return ref;
@@ -1924,6 +1939,11 @@ new_dereference (tree ptr,
   tree datum = fold_build1 (INDIRECT_REF, type, ptr);
   if (loc)
     set_tree_location (datum, loc);
+  if (TYPE_VOLATILE (type))
+  {
+    TREE_THIS_VOLATILE (datum) = 1;
+    TREE_SIDE_EFFECTS (datum) = 1;
+  }
   return datum;
 }
 
@@ -2192,6 +2212,12 @@ new_local (location *loc,
   }
   DECL_CONTEXT (inner) = this->m_inner_fndecl;
 
+  if (TYPE_VOLATILE (type->as_tree ()))
+  {
+    TREE_THIS_VOLATILE (inner) = 1;
+    TREE_SIDE_EFFECTS (inner) = 1;
+  }
+
   /* Prepend to BIND_EXPR_VARS: */
   DECL_CHAIN (inner) = BIND_EXPR_VARS (m_inner_bind_expr);
   BIND_EXPR_VARS (m_inner_bind_expr) = inner;
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 4aa18e3b767..72ff8dff0ff 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -481,6 +481,41 @@
 #undef create_code
 #undef verify_code
 
+/* test-volatile1.c */
+#define create_code create_code_volatile1
+#define verify_code verify_code_volatile1
+#include "test-volatile1.c"
+#undef create_code
+#undef verify_code
+
+/* test-volatile2.c */
+#define create_code create_code_volatile2
+#define verify_code verify_code_volatile2
+#include "test-volatile2.c"
+#undef create_code
+#undef verify_code
+
+/* test-volatile3.c */
+#define create_code create_code_volatile3
+#define verify_code verify_code_volatile3
+#include "test-volatile3.c"
+#undef create_code
+#undef verify_code
+
+/* test-volatile4.c */
+#define create_code create_code_volatile4
+#define verify_code verify_code_volatile4
+#include "test-volatile4.c"
+#undef create_code
+#undef verify_code
+
+/* test-volatile5.c */
+#define create_code create_code_volatile5
+#define verify_code verify_code_volatile5
+#include "test-volatile5.c"
+#undef create_code
+#undef verify_code
+
 /* Now expose the individual testcases as instances of this struct.  */
 
 struct testcase
diff --git a/gcc/testsuite/jit.dg/test-volatile1.c b/gcc/testsuite/jit.dg/test-volatile1.c
new file mode 100644
index 00000000000..3abfeb9ef3d
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-volatile1.c
@@ -0,0 +1,58 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "libgccjit.h"
+
+#define TEST_COMPILING_TO_FILE
+#define OUTPUT_KIND      GCC_JIT_OUTPUT_KIND_ASSEMBLER
+#define OUTPUT_FILENAME  "output-of-test-volatile1.c.s"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  /* Let's try to inject the equivalent of:
+int
+one ()
+{
+   volatile int my_var = 1;
+   return my_var;
+}
+   */
+  gcc_jit_type *int_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+  gcc_jit_type *volatile_type =
+    gcc_jit_type_get_volatile (int_type);
+
+  gcc_jit_function *func =
+    gcc_jit_context_new_function (ctxt,
+				  NULL,
+				  GCC_JIT_FUNCTION_EXPORTED,
+				  int_type,
+				  "one",
+				  0, NULL, 0);
+
+  gcc_jit_block *initial =
+    gcc_jit_function_new_block (func, "initial");
+
+  gcc_jit_lvalue *var =
+    gcc_jit_function_new_local (func, NULL, volatile_type, "my_var");
+
+  gcc_jit_rvalue *one =
+    gcc_jit_context_one (ctxt, int_type);
+  gcc_jit_block_add_assignment (initial, NULL, var, one);
+
+  gcc_jit_block_end_with_return(initial, NULL,
+    gcc_jit_lvalue_as_rvalue (var));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+}
+
+/* { dg-final { jit-verify-output-file-was-created "" } } */
+/* { dg-final { jit-verify-assembler-output-not "movl\\s+\\\$1,\\s+%eax" } } */
diff --git a/gcc/testsuite/jit.dg/test-volatile2.c b/gcc/testsuite/jit.dg/test-volatile2.c
new file mode 100644
index 00000000000..0385b2060c9
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-volatile2.c
@@ -0,0 +1,82 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "libgccjit.h"
+
+#define TEST_COMPILING_TO_FILE
+#define OUTPUT_KIND      GCC_JIT_OUTPUT_KIND_ASSEMBLER
+#define OUTPUT_FILENAME  "output-of-test-volatile2.c.s"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  /* Let's try to inject the equivalent of:
+struct my_struct
+{
+  volatile int my_field;
+};
+
+int
+two ()
+{
+  struct my_struct my_var;
+  my_var.my_field = 1;
+  return my_var.my_field;
+}
+   */
+  gcc_jit_type *int_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+  gcc_jit_type *volatile_type =
+    gcc_jit_type_get_volatile (int_type);
+
+  gcc_jit_field *field =
+    gcc_jit_context_new_field (ctxt, NULL, volatile_type, "my_field");
+
+  gcc_jit_field *fields[] = {
+      field
+  };
+
+  gcc_jit_struct *struct_type =
+    gcc_jit_context_new_struct_type (
+      ctxt,
+      NULL,
+      "my_struct",
+      1, fields);
+
+  gcc_jit_function *func =
+    gcc_jit_context_new_function (ctxt,
+				  NULL,
+				  GCC_JIT_FUNCTION_EXPORTED,
+				  int_type,
+				  "two",
+				  0, NULL, 0);
+
+  gcc_jit_block *initial =
+    gcc_jit_function_new_block (func, "initial");
+
+  gcc_jit_lvalue *var =
+    gcc_jit_function_new_local (func, NULL,
+      gcc_jit_struct_as_type (struct_type), "my_var");
+
+  gcc_jit_rvalue *one =
+    gcc_jit_context_one (ctxt, int_type);
+
+  gcc_jit_lvalue *field_val =
+    gcc_jit_lvalue_access_field (var, NULL, field);
+  gcc_jit_block_add_assignment (initial, NULL, field_val, one);
+
+  gcc_jit_block_end_with_return(initial, NULL,
+    gcc_jit_lvalue_as_rvalue (field_val));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+}
+
+/* { dg-final { jit-verify-output-file-was-created "" } } */
+/* { dg-final { jit-verify-assembler-output-not "movl\\s+\\\$1,\\s+%eax" } } */
diff --git a/gcc/testsuite/jit.dg/test-volatile3.c b/gcc/testsuite/jit.dg/test-volatile3.c
new file mode 100644
index 00000000000..4248b22fb58
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-volatile3.c
@@ -0,0 +1,85 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "libgccjit.h"
+
+#define TEST_COMPILING_TO_FILE
+#define OUTPUT_KIND      GCC_JIT_OUTPUT_KIND_ASSEMBLER
+#define OUTPUT_FILENAME  "output-of-test-volatile3.c.s"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  /* Let's try to inject the equivalent of:
+struct my_struct
+{
+  volatile int my_field;
+};
+
+int
+three ()
+{
+  struct my_struct my_var;
+  struct my_struct * addr = &my_var;
+  addr->my_field = 1;
+  return addr->my_field;
+}
+   */
+  gcc_jit_type *int_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+  gcc_jit_type *volatile_type =
+    gcc_jit_type_get_volatile (int_type);
+
+  gcc_jit_field *field =
+    gcc_jit_context_new_field (ctxt, NULL, volatile_type, "my_field");
+
+  gcc_jit_field *fields[] = {
+      field
+  };
+
+  gcc_jit_struct *struct_type =
+    gcc_jit_context_new_struct_type (
+      ctxt,
+      NULL,
+      "my_struct",
+      1, fields);
+
+  gcc_jit_function *func =
+    gcc_jit_context_new_function (ctxt,
+				  NULL,
+				  GCC_JIT_FUNCTION_EXPORTED,
+				  int_type,
+				  "three",
+				  0, NULL, 0);
+
+  gcc_jit_block *initial =
+    gcc_jit_function_new_block (func, "initial");
+
+  gcc_jit_lvalue *var =
+    gcc_jit_function_new_local (func, NULL,
+      gcc_jit_struct_as_type (struct_type), "my_var");
+
+  gcc_jit_rvalue *addr = gcc_jit_lvalue_get_address (var, NULL);
+
+  gcc_jit_rvalue *one =
+    gcc_jit_context_one (ctxt, int_type);
+
+  gcc_jit_lvalue *field_val =
+    gcc_jit_rvalue_dereference_field (addr, NULL, field);
+  gcc_jit_block_add_assignment (initial, NULL, field_val, one);
+
+  gcc_jit_block_end_with_return(initial, NULL,
+    gcc_jit_lvalue_as_rvalue (field_val));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+}
+
+/* { dg-final { jit-verify-output-file-was-created "" } } */
+/* { dg-final { jit-verify-assembler-output-not "movl\\s+\\\$1,\\s+%eax" } } */
diff --git a/gcc/testsuite/jit.dg/test-volatile4.c b/gcc/testsuite/jit.dg/test-volatile4.c
new file mode 100644
index 00000000000..f835515da02
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-volatile4.c
@@ -0,0 +1,70 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "libgccjit.h"
+
+#define TEST_COMPILING_TO_FILE
+#define OUTPUT_KIND      GCC_JIT_OUTPUT_KIND_ASSEMBLER
+#define OUTPUT_FILENAME  "output-of-test-volatile4.c.s"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  /* Let's try to inject the equivalent of:
+int
+four ()
+{
+   int my_var;
+   volatile int *addr = (volatile int*) &my_var;
+   *addr = 1;
+   return *addr;
+}
+   */
+  gcc_jit_type *int_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+  gcc_jit_type *volatile_ptr_type =
+    gcc_jit_type_get_pointer (
+      gcc_jit_type_get_volatile (int_type));
+
+  gcc_jit_function *func =
+    gcc_jit_context_new_function (ctxt,
+				  NULL,
+				  GCC_JIT_FUNCTION_EXPORTED,
+				  int_type,
+				  "four",
+				  0, NULL, 0);
+
+  gcc_jit_block *initial =
+    gcc_jit_function_new_block (func, "initial");
+
+  gcc_jit_lvalue *var =
+    gcc_jit_function_new_local (func, NULL, int_type, "my_var");
+
+  gcc_jit_rvalue *addr =
+    gcc_jit_lvalue_get_address (var, NULL);
+
+  gcc_jit_rvalue *casted_addr =
+    gcc_jit_context_new_cast (ctxt, NULL, addr, volatile_ptr_type);
+
+  gcc_jit_lvalue *val =
+    gcc_jit_rvalue_dereference (casted_addr, NULL);
+
+  gcc_jit_rvalue *one =
+    gcc_jit_context_one (ctxt, int_type);
+  gcc_jit_block_add_assignment (initial, NULL, val, one);
+
+  gcc_jit_block_end_with_return(initial, NULL,
+    gcc_jit_lvalue_as_rvalue (val));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+}
+
+/* { dg-final { jit-verify-output-file-was-created "" } } */
+/* { dg-final { jit-verify-assembler-output-not "movl\\s+\\\$1,\\s+%eax" } } */
diff --git a/gcc/testsuite/jit.dg/test-volatile5.c b/gcc/testsuite/jit.dg/test-volatile5.c
new file mode 100644
index 00000000000..b46749c7f45
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-volatile5.c
@@ -0,0 +1,60 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "libgccjit.h"
+
+#define TEST_COMPILING_TO_FILE
+#define OUTPUT_KIND      GCC_JIT_OUTPUT_KIND_ASSEMBLER
+#define OUTPUT_FILENAME  "output-of-test-volatile5.c.s"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  /* Let's try to inject the equivalent of:
+volatile int my_var = 1;
+
+int
+five ()
+{
+   return my_var;
+}
+   */
+  gcc_jit_type *int_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+  gcc_jit_type *volatile_type =
+    gcc_jit_type_get_volatile (int_type);
+
+  gcc_jit_function *func =
+    gcc_jit_context_new_function (ctxt,
+				  NULL,
+				  GCC_JIT_FUNCTION_EXPORTED,
+				  int_type,
+				  "five",
+				  0, NULL, 0);
+
+  gcc_jit_block *initial =
+    gcc_jit_function_new_block (func, "initial");
+
+  gcc_jit_lvalue *var =
+    gcc_jit_context_new_global (ctxt, NULL, GCC_JIT_GLOBAL_INTERNAL,
+      volatile_type, "my_var");
+
+  gcc_jit_rvalue *one =
+    gcc_jit_context_one (ctxt, int_type);
+  gcc_jit_block_add_assignment (initial, NULL, var, one);
+
+  gcc_jit_block_end_with_return(initial, NULL,
+    gcc_jit_lvalue_as_rvalue (var));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+}
+
+/* { dg-final { jit-verify-output-file-was-created "" } } */
+/* { dg-final { jit-verify-assembler-output-not "movl\\s+\\\$1,\\s+%eax" } } */

Reply via email to