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 75b51e5c9ad8..a28c2c760dd0 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -851,6 +851,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); @@ -1969,8 +1976,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; @@ -1989,6 +2004,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; } @@ -2257,6 +2277,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 aa9d34346527..7ce987d9be8b 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -498,6 +498,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 000000000000..3abfeb9ef3d8 --- /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 000000000000..0385b2060c96 --- /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 000000000000..4248b22fb588 --- /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 000000000000..f835515da02d --- /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 000000000000..b46749c7f450 --- /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" } } */ -- 2.54.0
