https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127042
Bug ID: 127042
Summary: [avr] widening mul synthesis generates arithmetic even
though the result is known at compile time
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: gjl at gcc dot gnu.org
Target Milestone: ---
typedef __UINT16_TYPE__ uint16_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __UINT64_TYPE__ uint64_t;
uint16_t wmul16 (uint16_t x)
{
return ((uint64_t) x * 0xaaaaaaab) >> 32;
}
$ avr-gcc x.c -S -Os -fdump-rtl-expand-details
generates code that evaluates a multiplication at run time, even though the
result is known at compile time:
$ cat x.c.274r.expand
;; Function wmul16 (wmul16, funcdef_no=0, decl_uid=2027, cgraph_uid=1,
symbol_order=0)
uint16_t wmul16 (uint16_t x)
{
uint16_t _5;
unsigned long _7;
unsigned long _8;
unsigned long _9;
unsigned long _10;
unsigned long _11;
unsigned long _12;
unsigned long _13;
unsigned long _14;
bool _15;
unsigned long _16;
unsigned long _17;
unsigned long _18;
unsigned long _19;
unsigned long _20;
unsigned long _21;
unsigned long _22;
unsigned long _23;
unsigned long _24;
unsigned long _25;
;; basic block 2, loop depth 0
;; pred: ENTRY
_7 = (unsigned long) x_4(D);
_8 = _7 >> 16;
_9 = (unsigned long) x_4(D);
_10 = _9 * 43691;
_11 = _8 * 43691;
_12 = _9 * 43690;
_13 = _8 * 43690;
_14 = _11 + _12;
...
So x is uint16_t -> _8 = 0 -> _11 = _8 * const = 0 etc.
As it seems there is no pass after expand that folds this constant expression,
which leads to a run-time multiplication for an expression with a known
outcome.
Note that on avr, there is a post-reload pass -mfuse-move that cleans up some
of the mess, however:
* Targets other than avr don't have such a pass, so they are running arithmetic
with known outcome.
* The avr pass runs after reload, so it doesn't help against high register
pressure, spilled values, extra frame size needed, etc.
As it seems, widen mult synthesis as of r17-3443 runs too late. It should run
prior to some constant folding and propagation pass. Obviously no
target-independent RTL pass is doing such folding / propagation.