Hi Jeff,
This is a patch to get correct code out of 64-bit
loads from address-space __memx.
The AVR address-spaces may require that move insns issue
calls to library support functions, a fact that -ftree-ter
doesn't account for. tree-ssa-ter.cc then replaces an
expression across such a library call, resulting in wrong code.
This patch disables that pass per default on avr, as there is no
more fine grained way to avoid malicious optimizations.
The pass can still be re-enabled by means of explicit -ftree-ter.
Ok to apply?
As an alternative, the option could be disabled permanently in
avr.cc::avr_option_override().
Johann
--
AVR: middle-end/87376 - Use -fno-tree-ter per default.
Temporary expression replacement might replace expressions across
library calls, for example with move insn from address-space __memx
like in PR87376. -ftree-ter has no way where the backend could hook
in to avoid only problematic replacements, thus kick it out altogether.
PR middle-end/87376
gcc/
* common/config/avr/avr-common.cc (avr_option_optimization_table)
<OPT_ftree_ter>: Set to 0.
gcc/testsuite/
* gcc.target/avr/torture/pr87376-memx.c: New test.
diff --git a/gcc/common/config/avr/avr-common.cc b/gcc/common/config/avr/avr-common.cc
index fdf130f1e1a..2300d602cfe 100644
--- a/gcc/common/config/avr/avr-common.cc
+++ b/gcc/common/config/avr/avr-common.cc
@@ -32,6 +32,11 @@ static const struct default_options avr_option_optimization_table[] =
// The only effect of -fcaller-saves might be that it triggers
// a frame without need when it tries to be smart around calls.
{ OPT_LEVELS_ALL, OPT_fcaller_saves, NULL, 0 },
+ // Temporary expression replacement might replace expressions across
+ // library calls, for example with move insn from address-space __memx
+ // like in PR87376. -ftree-ter has no way where the backend could hook
+ // in to avoid only problematic replacements, thus kick it out altogether.
+ { OPT_LEVELS_ALL, OPT_ftree_ter, NULL, 0 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_mgas_isr_prologues, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_mmain_is_OS_task, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_mfuse_add_, NULL, 1 },
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr87376-memx.c b/gcc/testsuite/gcc.target/avr/torture/pr87376-memx.c
new file mode 100644
index 00000000000..e8373854ac8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/torture/pr87376-memx.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { ! avr_tiny } } } */
+/* { dg-additional-options "-std=gnu99" } */
+
+typedef __UINT64_TYPE__ uint64_t;
+
+extern const __memx uint64_t aa __asm ("real_aa");
+extern const uint64_t bb __asm ("real_bb");
+
+const __memx uint64_t real_aa = 0x1122334455667788;
+const uint64_t real_bb = 0x0908070605040302;
+
+__attribute__((noinline,noclone))
+uint64_t add1 (void)
+{
+ return aa + bb;
+}
+
+__attribute__((noinline,noclone))
+uint64_t add2 (void)
+{
+ return bb + aa;
+}
+
+int main (void)
+{
+ if (add1() != 0x1a2a3a4a5a6a7a8a)
+ __builtin_exit (__LINE__);
+
+ if (add2() != 0x1a2a3a4a5a6a7a8a)
+ __builtin_exit (__LINE__);
+
+ return 0;
+}