Applied as 7916a70aa4ab. Thanks! --Philipp. On Mon, 24 Aug 2026 at 16:09, Konstantinos Eleftheriou < [email protected]> wrote:
> From: Philipp Tomsich <[email protected]> > > synth_mult accepts a sub-algorithm of up to MAX_BITS_PER_WORD > operations from its recursive call and appends the current operation > at index ops before the too-long check discards the result. That > index is one past both arrays. The write to op[MAX_BITS_PER_WORD] > aliases log[0..3] and overwrites the shift counts of the algorithm > being built, and the write to log[MAX_BITS_PER_WORD] falls outside > the struct. The cache update just above the check reads op[] at the > same index. > > AVR reaches this at -O1/-O2, where MAX_BITS_PER_WORD is 8 and a > SImode multiply by a dense constant needs more operations than that: > > uint32_t f (uint32_t x) { return x * 0xaaab; } > > Size the arrays for the transient state. > > PR middle-end/127031 > > gcc/ChangeLog: > > * expmed.h (struct algorithm): Add one slot to the op and log > arrays for the operation synth_mult appends to a full > sub-algorithm before discarding it. > > gcc/testsuite/ChangeLog: > > * gcc.target/avr/pr127031.c: New test. > --- > gcc/expmed.h | 9 ++++++--- > gcc/testsuite/gcc.target/avr/pr127031.c | 9 +++++++++ > 2 files changed, 15 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/avr/pr127031.c > > diff --git a/gcc/expmed.h b/gcc/expmed.h > index 78f3f36e6615..4a2c60e055e5 100644 > --- a/gcc/expmed.h > +++ b/gcc/expmed.h > @@ -101,9 +101,12 @@ struct algorithm > word size, but the worst-case algorithms will be if we have few > consecutive ones or zeros, i.e., a multiplicand like 10101010101... > In that case we will generate shift-by-2, add, shift-by-2, add,..., > - in total wordsize operations. */ > - enum alg_code op[MAX_BITS_PER_WORD]; > - char log[MAX_BITS_PER_WORD]; > + in total wordsize operations. OPS never exceeds MAX_BITS_PER_WORD, > + and the final entry is scratch: the algorithm search appends an > + operation there before checking whether the sequence has grown too > + long. */ > + enum alg_code op[MAX_BITS_PER_WORD + 1]; > + char log[MAX_BITS_PER_WORD + 1]; > }; > > /* The entry for our multiplication cache/hash table. */ > diff --git a/gcc/testsuite/gcc.target/avr/pr127031.c > b/gcc/testsuite/gcc.target/avr/pr127031.c > new file mode 100644 > index 000000000000..12d978af17eb > --- /dev/null > +++ b/gcc/testsuite/gcc.target/avr/pr127031.c > @@ -0,0 +1,9 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > + > +typedef __UINT32_TYPE__ uint32_t; > + > +uint32_t f (uint32_t x) > +{ > + return x * 0xaaab; > +} > -- > 2.55.0 > >
