[Bug target/83210] __builtin_mul_overflow() generates suboptimal code when exactly one argument is the constant 2
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
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
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
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
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
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
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
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. } ```