aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2025-03-18 21:22:22 +0100
committerGeorg-Johann Lay <avr@gjlay.de>2025-03-18 21:44:00 +0100
commit16065b6239aab2eecfd7a50f58d38324ee6478ba (patch)
treecb196e18010923722c800c21b4c1230a276d5980 /gcc
parent6fc1f70f0b7b50fd85aa58a0f29dd1e17f2113d1 (diff)
downloadgcc-16065b6239aab2eecfd7a50f58d38324ee6478ba.zip
gcc-16065b6239aab2eecfd7a50f58d38324ee6478ba.tar.gz
gcc-16065b6239aab2eecfd7a50f58d38324ee6478ba.tar.bz2
AVR: target/119355 - Fix ICE in pass avr-fuse-move / -mfuse-move.
This ICE only occurred when the compiler is built with, say CXXFLAGS='-Wp,-D_GLIBCXX_ASSERTIONS'. The problem was that a value from an illegal REGNO was read. The value was not used in these cases, but the access triggered an assertion due to reading past std::array. gcc/ PR target/119355 * config/avr/avr-passes.cc (memento_t::apply): Only read values[p.arg] when it is actually used.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/avr/avr-passes.cc54
1 files changed, 32 insertions, 22 deletions
diff --git a/gcc/config/avr/avr-passes.cc b/gcc/config/avr/avr-passes.cc
index e32c467..184619a 100644
--- a/gcc/config/avr/avr-passes.cc
+++ b/gcc/config/avr/avr-passes.cc
@@ -2205,9 +2205,6 @@ memento_t::apply (const ply_t &p)
}
else if (p.size == 1)
{
- int x = values[p.regno];
- int y = values[p.arg];
-
switch (p.code)
{
default:
@@ -2234,29 +2231,42 @@ memento_t::apply (const ply_t &p)
gcc_unreachable ();
break;
-#define DO_ARITH(n_args, code, expr) \
+#define DO_ARITH1(code, expr) \
+ case code: \
+ gcc_assert (knows (p.regno)); \
+ { \
+ const int x = values[p.regno]; \
+ set_value (p.regno, expr); \
+ } \
+ break
+
+#define DO_ARITH2(code, expr) \
case code: \
gcc_assert (knows (p.regno)); \
- if (n_args == 2) \
- gcc_assert (knows (p.arg)); \
- set_value (p.regno, expr); \
+ gcc_assert (knows (p.arg)); \
+ { \
+ const int x = values[p.regno]; \
+ const int y = values[p.arg]; \
+ set_value (p.regno, expr); \
+ } \
break
- DO_ARITH (1, NEG, -x);
- DO_ARITH (1, NOT, ~x);
- DO_ARITH (1, PRE_INC, x + 1);
- DO_ARITH (1, PRE_DEC, x - 1);
- DO_ARITH (1, ROTATE, (x << 4) | (x >> 4));
- DO_ARITH (1, ASHIFT, x << 1);
- DO_ARITH (1, LSHIFTRT, x >> 1);
- DO_ARITH (1, ASHIFTRT, (x >> 1) | (x & 0x80));
-
- DO_ARITH (2, AND, x & y);
- DO_ARITH (2, IOR, x | y);
- DO_ARITH (2, XOR, x ^ y);
- DO_ARITH (2, PLUS, x + y);
- DO_ARITH (2, MINUS, x - y);
-#undef DO_ARITH
+ DO_ARITH1 (NEG, -x);
+ DO_ARITH1 (NOT, ~x);
+ DO_ARITH1 (PRE_INC, x + 1);
+ DO_ARITH1 (PRE_DEC, x - 1);
+ DO_ARITH1 (ROTATE, (x << 4) | (x >> 4));
+ DO_ARITH1 (ASHIFT, x << 1);
+ DO_ARITH1 (LSHIFTRT, x >> 1);
+ DO_ARITH1 (ASHIFTRT, (x >> 1) | (x & 0x80));
+
+ DO_ARITH2 (AND, x & y);
+ DO_ARITH2 (IOR, x | y);
+ DO_ARITH2 (XOR, x ^ y);
+ DO_ARITH2 (PLUS, x + y);
+ DO_ARITH2 (MINUS, x - y);
+#undef DO_ARITH1
+#undef DO_ARITH2
}
} // size == 1
else