aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@adacore.com>2023-12-14 10:41:13 -0300
committerAlexandre Oliva <oliva@gnu.org>2023-12-14 10:41:13 -0300
commit37afeec8a635153ccd4e91bd686c93217706894d (patch)
tree485ceee06bdc4f0b16bd5e90db9d27a396d443a5 /gcc
parent679adb2396a911b5999591f7a4f27a88064e91ff (diff)
downloadgcc-37afeec8a635153ccd4e91bd686c93217706894d.zip
gcc-37afeec8a635153ccd4e91bd686c93217706894d.tar.gz
gcc-37afeec8a635153ccd4e91bd686c93217706894d.tar.bz2
strub: handle volatile promoted args in internal strub [PR112938]
When generating code for an internal strub wrapper, don't clear the DECL_NOT_GIMPLE_REG_P flag of volatile args, and gimplify them both before and after any conversion. While at that, move variable TMP into narrower scopes so that it's more trivial to track where ARG lives. for gcc/ChangeLog PR middle-end/112938 * ipa-strub.cc (pass_ipa_strub::execute): Handle promoted volatile args in internal strub. Simplify. for gcc/testsuite/ChangeLog PR middle-end/112938 * gcc.dg/strub-internal-volatile.c: New.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ipa-strub.cc29
-rw-r--r--gcc/testsuite/gcc.dg/strub-internal-volatile.c10
2 files changed, 31 insertions, 8 deletions
diff --git a/gcc/ipa-strub.cc b/gcc/ipa-strub.cc
index 8ec6824..45294b0 100644
--- a/gcc/ipa-strub.cc
+++ b/gcc/ipa-strub.cc
@@ -3203,7 +3203,6 @@ pass_ipa_strub::execute (function *)
i++, arg = DECL_CHAIN (arg), nparm = DECL_CHAIN (nparm))
{
tree save_arg = arg;
- tree tmp = arg;
/* Arrange to pass indirectly the parms, if we decided to do
so, and revert its type in the wrapper. */
@@ -3211,10 +3210,9 @@ pass_ipa_strub::execute (function *)
{
tree ref_type = TREE_TYPE (nparm);
TREE_ADDRESSABLE (arg) = true;
- tree addr = build1 (ADDR_EXPR, ref_type, arg);
- tmp = arg = addr;
+ arg = build1 (ADDR_EXPR, ref_type, arg);
}
- else
+ else if (!TREE_THIS_VOLATILE (arg))
DECL_NOT_GIMPLE_REG_P (arg) = 0;
/* Convert the argument back to the type used by the calling
@@ -3223,16 +3221,31 @@ pass_ipa_strub::execute (function *)
double to be passed on unchanged to the wrapped
function. */
if (TREE_TYPE (nparm) != DECL_ARG_TYPE (nparm))
- arg = fold_convert (DECL_ARG_TYPE (nparm), arg);
+ {
+ tree tmp = arg;
+ /* If ARG is e.g. volatile, we must copy and
+ convert in separate statements. ??? Should
+ we drop volatile from the wrapper
+ instead? */
+ if (!is_gimple_val (arg))
+ {
+ tmp = create_tmp_reg (TYPE_MAIN_VARIANT
+ (TREE_TYPE (arg)), "arg");
+ gimple *stmt = gimple_build_assign (tmp, arg);
+ gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
+ }
+ arg = fold_convert (DECL_ARG_TYPE (nparm), tmp);
+ }
if (!is_gimple_val (arg))
{
- tmp = create_tmp_reg (TYPE_MAIN_VARIANT
- (TREE_TYPE (arg)), "arg");
+ tree tmp = create_tmp_reg (TYPE_MAIN_VARIANT
+ (TREE_TYPE (arg)), "arg");
gimple *stmt = gimple_build_assign (tmp, arg);
gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
+ arg = tmp;
}
- vargs.quick_push (tmp);
+ vargs.quick_push (arg);
arg = save_arg;
}
/* These strub arguments are adjusted later. */
diff --git a/gcc/testsuite/gcc.dg/strub-internal-volatile.c b/gcc/testsuite/gcc.dg/strub-internal-volatile.c
new file mode 100644
index 0000000..34d4ec8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strub-internal-volatile.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target strub } */
+
+void __attribute__ ((strub("internal")))
+f(volatile short s) {
+}
+
+void g(void) {
+ f(0);
+}