aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2023-12-24 00:10:32 +0100
committerHans-Peter Nilsson <hp@bitrange.com>2023-12-24 01:40:58 +0100
commit3d03630b123411340e52d05124cb0cacfa1fc8b0 (patch)
tree1abacfddf0b38c46c4311c2835eb8b9c43395c17 /gcc
parentd2ae7cb2ef9067f91e751b9914665d6b59f23478 (diff)
downloadgcc-3d03630b123411340e52d05124cb0cacfa1fc8b0.zip
gcc-3d03630b123411340e52d05124cb0cacfa1fc8b0.tar.gz
gcc-3d03630b123411340e52d05124cb0cacfa1fc8b0.tar.bz2
CRIS: Fix PR middle-end/113109; "throw" failing
TL;DR: the "dse1" pass removed the eh-return-address store. The PA also marks its EH_RETURN_HANDLER_RTX as volatile, for the same reason, as does visum. See PR32769 - it's the same thing on PA. Conceptually, it's logical that stores to incoming args are optimized out on the return path or if no loads are seen - at least before epilogue expansion, when the subsequent load isn't seen in the RTL, as is the case for the "dse1" pass. I haven't looked into why this problem, that appeared for the PA already in 2007, was seen for CRIS only recently (with r14-6674-g4759383245ac97). PR middle-end/113109 * config/cris/cris.cc (cris_eh_return_handler_rtx): New function. * config/cris/cris-protos.h (cris_eh_return_handler_rtx): Prototype. * config/cris/cris.h (EH_RETURN_HANDLER_RTX): Redefine to call cris_eh_return_handler_rtx.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/cris/cris-protos.h1
-rw-r--r--gcc/config/cris/cris.cc16
-rw-r--r--gcc/config/cris/cris.h3
3 files changed, 18 insertions, 2 deletions
diff --git a/gcc/config/cris/cris-protos.h b/gcc/config/cris/cris-protos.h
index 666e04f..06678c7 100644
--- a/gcc/config/cris/cris-protos.h
+++ b/gcc/config/cris/cris-protos.h
@@ -28,6 +28,7 @@ extern bool cris_reload_address_legitimized (rtx, machine_mode, int, int, int);
extern int cris_side_effect_mode_ok (enum rtx_code, rtx *, int, int,
int, int, int);
extern rtx cris_return_addr_rtx (int, rtx);
+extern rtx cris_eh_return_handler_rtx ();
extern rtx cris_split_movdx (rtx *);
extern bool cris_base_p (const_rtx, bool);
extern bool cris_base_or_autoincr_p (const_rtx, bool);
diff --git a/gcc/config/cris/cris.cc b/gcc/config/cris/cris.cc
index 7705c25..38a4dd2 100644
--- a/gcc/config/cris/cris.cc
+++ b/gcc/config/cris/cris.cc
@@ -1382,6 +1382,22 @@ cris_return_addr_rtx (int count, rtx frameaddr ATTRIBUTE_UNUSED)
: NULL_RTX;
}
+/* Setting the EH return return address is done by a *store* to a memory
+ address expressed as relative to "*incoming* args". That store will
+ be optimized away, unless the MEM is marked as volatile. N.B.: no
+ optimization opportunities are expected to be lost due to this hack;
+ __builtin_eh_return isn't called from elsewhere than the EH machinery
+ in libgcc. */
+
+rtx
+cris_eh_return_handler_rtx ()
+{
+ rtx ret = cris_return_addr_rtx (0, NULL_RTX);
+ gcc_assert (MEM_P (ret));
+ MEM_VOLATILE_P (ret) = true;
+ return ret;
+}
+
/* Accessor used in cris.md:return because cfun->machine isn't available
there. */
diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
index 087b226..ced3560 100644
--- a/gcc/config/cris/cris.h
+++ b/gcc/config/cris/cris.h
@@ -551,8 +551,7 @@ enum reg_class
#define CRIS_STACKADJ_REG CRIS_STRUCT_VALUE_REGNUM
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (SImode, CRIS_STACKADJ_REG)
-#define EH_RETURN_HANDLER_RTX \
- cris_return_addr_rtx (0, NULL)
+#define EH_RETURN_HANDLER_RTX cris_eh_return_handler_rtx ()
#define INIT_EXPANDERS cris_init_expanders ()