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" } } */