diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2025-03-18 21:22:22 +0100 |
---|---|---|
committer | Georg-Johann Lay <avr@gjlay.de> | 2025-03-18 21:44:00 +0100 |
commit | 16065b6239aab2eecfd7a50f58d38324ee6478ba (patch) | |
tree | cb196e18010923722c800c21b4c1230a276d5980 /gcc | |
parent | 6fc1f70f0b7b50fd85aa58a0f29dd1e17f2113d1 (diff) | |
download | gcc-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.cc | 54 |
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 |