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.
  • [Bug tree-optimizati... gjl at gcc dot gnu.org via Gcc-bugs

Reply via email to