https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116133

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Actually I am trying to understand the original reason for the extra checks
that was added in r14-992 when dealing with highpart:
    The reason for testing the presence of the optab
    handler is to make sure the generated code for it is short to ensure
    we don't actually pessimize code instead of optimizing it.
...

    So, the following patch matches what we do in internal-fn.cc and
    also pattern matches __builtin_mul_overflow_p if
    1) we only need the flag whether it overflowed (i.e. !use_seen)
    2) it is unsigned (i.e. !cast_stmt)
    3) umul_highpart is supported for the mode

But the code in optab handles this just fine.

In the case of can_mult_highpart_p == 1 (direct), it just generates 2
instructions (lower mult and upper mult) and one comparison. which is better
than a division. This will never be worse.

For can_mult_highpart_p == 2 (aka indirect), we will either use a widening
multiply (good) and then a comparison or 2 widening instructions and a multiply
(also decent). and then a comparison with a shift.


Note the multover internal function uses can_widen_mult_without_libcall to see
if we can do the widdening (which can handle more cases than
can_mult_highpart_p == 2 really due to using expand_mult).

So I think the real answer is just remove the extra checks and test that
!can_mult_highpart_p .

But then we still miss (due to the above mentioning that
can_widen_mult_without_libcall handles more than can_mult_highpart_p ):
```
int
f1 (unsigned char x, unsigned char y, unsigned char *res)
{
  *res = x * y;
  return x && (*res / x) != y;
}
```

Note I don't think we can make can_mult_highpart_p depedent on
can_widen_mult_without_libcall either is that a recusive dependency.


So maybe:
      || (code == MULT_EXPR
          && optab_handler (cast_stmt ? mulv4_optab : umulv4_optab,
                            TYPE_MODE (type)) == CODE_FOR_nothing
          /* The target has widdening (via high part or otherwise)
             multiply for this mode. */
          && !can_mult_highpart_p (TYPE_MODE (type), true))
          /* Or if the the mode is smaller than the word size. */
          && GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type)) >= BITS_PER_WORD)

The main target where this could be an issue is avr I think. IU have t o think
this more.

Reply via email to