aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ipa-strub.cc7
-rw-r--r--gcc/testsuite/g++.dg/strub-internal-pr112938.cc12
2 files changed, 19 insertions, 0 deletions
diff --git a/gcc/ipa-strub.cc b/gcc/ipa-strub.cc
index dff9422..8fa7bdf 100644
--- a/gcc/ipa-strub.cc
+++ b/gcc/ipa-strub.cc
@@ -1940,6 +1940,9 @@ maybe_make_indirect (indirect_parms_t &indirect_parms, tree op, int *rec)
TREE_TYPE (TREE_TYPE (op)),
op,
build_int_cst (TREE_TYPE (op), 0));
+ if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (op)))
+ && !TREE_THIS_VOLATILE (ret))
+ TREE_SIDE_EFFECTS (ret) = TREE_THIS_VOLATILE (ret) = 1;
return ret;
}
}
@@ -2894,6 +2897,10 @@ pass_ipa_strub::execute (function *)
probably drop the TREE_ADDRESSABLE and keep the TRUE. */
tree ref_type = build_ref_type_for (nparm);
+ if (TREE_THIS_VOLATILE (nparm)
+ && TYPE_VOLATILE (TREE_TYPE (nparm))
+ && !TYPE_VOLATILE (ref_type))
+ TREE_SIDE_EFFECTS (nparm) = TREE_THIS_VOLATILE (nparm) = 0;
DECL_ARG_TYPE (nparm) = TREE_TYPE (nparm) = ref_type;
relayout_decl (nparm);
TREE_ADDRESSABLE (nparm) = 0;
diff --git a/gcc/testsuite/g++.dg/strub-internal-pr112938.cc b/gcc/testsuite/g++.dg/strub-internal-pr112938.cc
new file mode 100644
index 0000000..5a74bec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/strub-internal-pr112938.cc
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-optimized -O2" } */
+/* { dg-require-effective-target strub } */
+
+bool __attribute__ ((__strub__ ("internal")))
+f(bool i, volatile bool j)
+{
+ return (i ^ j) == j;
+}
+
+/* Check for two dereferences of the indirected volatile j parm. */
+/* { dg-final { scan-tree-dump-times {={v} \*j_[0-9][0-9]*(D)} 2 "optimized" } } */