[Bug target/83210] __builtin_mul_overflow() generates suboptimal code when exactly one argument is the constant 2

2017-11-30 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83210

Jakub Jelinek  changed:

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED

--- Comment #8 from Jakub Jelinek  ---
Fixed.

[Bug target/83210] __builtin_mul_overflow() generates suboptimal code when exactly one argument is the constant 2

2017-11-30 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83210

--- Comment #7 from Jakub Jelinek  ---
Author: jakub
Date: Thu Nov 30 10:29:58 2017
New Revision: 255269

URL: https://gcc.gnu.org/viewcvs?rev=255269=gcc=rev
Log:
PR target/83210
* internal-fn.c (expand_mul_overflow): Optimize unsigned
multiplication by power of 2 constant into two shifts + comparison.

* gcc.target/i386/pr83210.c: New test.

Added:
trunk/gcc/testsuite/gcc.target/i386/pr83210.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/internal-fn.c
trunk/gcc/testsuite/ChangeLog

[Bug target/83210] __builtin_mul_overflow() generates suboptimal code when exactly one argument is the constant 2

2017-11-29 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83210

Jakub Jelinek  changed:

   What|Removed |Added

 Status|UNCONFIRMED |ASSIGNED
   Last reconfirmed||2017-11-29
   Assignee|unassigned at gcc dot gnu.org  |jakub at gcc dot gnu.org
 Ever confirmed|0   |1

--- Comment #6 from Jakub Jelinek  ---
Created attachment 42745
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42745=edit
gcc8-pr83210.patch

Untested patch.

[Bug target/83210] __builtin_mul_overflow() generates suboptimal code when exactly one argument is the constant 2

2017-11-29 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83210

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek  ---
(In reply to Liu Hao from comment #4)
> (In reply to Andrew Pinski from comment #2)
> > (res >> 3) != src;
> > 
> > Why not just (src>>(sizeof (res)*8-3))!=0.
> > 
> > Seems shorter and might be faster.
> 
> What if the second operand is not a power of 2? `(res * 5 / 5 != src)` will
> always work, but bitwise shifting might not.

Division is something we need to avoid.  If any of the * 5 or / 5 ends up being
actual multiplication, it doesn't make sense either.  And otherwise it will
just be very long.  So the only thing that IMHO makes sense is unsigned
overflow multiply with constant power of two.  I can handle that.  No plans to
do anything else.

[Bug target/83210] __builtin_mul_overflow() generates suboptimal code when exactly one argument is the constant 2

2017-11-29 Thread lh_mouse at 126 dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83210

--- Comment #4 from Liu Hao  ---
(In reply to Andrew Pinski from comment #2)
> (res >> 3) != src;
> 
> Why not just (src>>(sizeof (res)*8-3))!=0.
> 
> Seems shorter and might be faster.

What if the second operand is not a power of 2? `(res * 5 / 5 != src)` will
always work, but bitwise shifting might not.

[Bug target/83210] __builtin_mul_overflow() generates suboptimal code when exactly one argument is the constant 2

2017-11-29 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83210

--- Comment #3 from Andrew Pinski  ---
(In reply to Andrew Pinski from comment #2)
> (res >> 3) != src;
> 
> Why not just (src>>(sizeof (res)*8-3))!=0.
> 
> Seems shorter and might be faster.

And for the original case
Src>>31!=0 Just becomes src>>31. :)

[Bug target/83210] __builtin_mul_overflow() generates suboptimal code when exactly one argument is the constant 2

2017-11-29 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83210

--- Comment #2 from Andrew Pinski  ---
(res >> 3) != src;

Why not just (src>>(sizeof (res)*8-3))!=0.

Seems shorter and might be faster.

[Bug target/83210] __builtin_mul_overflow() generates suboptimal code when exactly one argument is the constant 2

2017-11-29 Thread lh_mouse at 126 dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83210

--- Comment #1 from Liu Hao  ---
FWIW, it can still be improved when the constant is something other than 2.

For example:

```
bool mul_8_and_check(unsigned *dst, unsigned src){
return __builtin_mul_overflow(src, 8, dst);
}
```

can be rewritten as:

bool mul_8_and_check(unsigned *dst, unsigned src){
unsigned res = src << 3;
*dst = res;
return (res >> 3) != src; // The result will have been truncated if
  // dividing the result by 8 does not yield
  // the original value.
}
```