On Wed, Sep 11, 2019 at 12:39:51PM +0200, Eric Botcazou wrote: > This fixes a wrong code generation on the ARM in very peculiar circumstances > ( > -O2 -fno-dce -fno-forward-propagate -fno-sched-pressure) present on all > active > branches in the form of a missing zero-extension. It turns out that not all > parts of the RTL middle-end agree on the assumptions valid on RISC machines > as > encoded by WORD_REGISTER_OPERATIONS, so the nonzero_bits machinery needs to > be > more conservative with them. As witnessed by the added XFAIL, this will add > back some redundant zero-extensions on WORD_REGISTER_OPERATIONS targets. > > Tested on SPARC/Solaris and SPARC64/Linux, applied on all active branches.
Thanks. I've added testcase for the various PRs that are fixed by this change, verified on armv4 and riscv64 on the first and last testcases that the rtlanal.c change makes the desired change in the assembly, plus tested on x86_64-linux -m32/-m64, committed to trunk as obvious. 2019-09-11 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/89435 PR rtl-optimization/89795 PR rtl-optimization/91720 * gcc.dg/pr89435.c: New test. * gcc.dg/pr89795.c: New test. * gcc.dg/pr91720.c: New test. --- gcc/testsuite/gcc.dg/pr89435.c.jj 2019-09-11 13:34:09.630165981 +0200 +++ gcc/testsuite/gcc.dg/pr89435.c 2019-09-11 13:33:37.038664072 +0200 @@ -0,0 +1,21 @@ +/* PR rtl-optimization/89435 */ +/* { dg-do run } */ +/* { dg-options "-O1 -fno-forward-propagate -fno-tree-forwprop -fno-tree-ccp" } */ + +unsigned short a; +unsigned int b, c, d, e, f; + +int +main () +{ +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 + unsigned char g = e = __builtin_mul_overflow_p (5, 542624702, 0); + d = __builtin_bswap64 (a); + b = __builtin_sub_overflow ((unsigned char) -e, (unsigned int) d, &g); + e = __builtin_mul_overflow (b, c, &a); + f = g + e; + if (f != 0xff) + __builtin_abort (); +#endif + return 0; +} --- gcc/testsuite/gcc.dg/pr89795.c.jj 2019-09-11 13:05:58.405033868 +0200 +++ gcc/testsuite/gcc.dg/pr89795.c 2019-09-11 13:04:52.508042619 +0200 @@ -0,0 +1,25 @@ +/* PR rtl-optimization/89795 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-dce -fno-forward-propagate -fno-sched-pressure" } */ + +unsigned char a; +unsigned b, c, d; + +int +main () +{ +#if __CHAR_BIT__ == 8 + unsigned x; + int e, f; + unsigned char g; + e = __builtin_bswap32 (a); + f = __builtin_ffs (~(unsigned short) e); + a = __builtin_mul_overflow ((unsigned char) 0xf7, f, &g); + a |= __builtin_sub_overflow_p (c, 0, (unsigned char) 0); + d = g + b; + x = d; + if (x != 0xf7) + __builtin_abort (); +#endif + return 0; +} --- gcc/testsuite/gcc.dg/pr91720.c.jj 2019-09-11 13:06:08.909873060 +0200 +++ gcc/testsuite/gcc.dg/pr91720.c 2019-09-11 13:00:50.070754162 +0200 @@ -0,0 +1,22 @@ +/* PR rtl-optimization/91720 */ +/* { dg-do run } */ +/* { dg-options "-Og -fno-forward-propagate -frerun-cse-after-loop -fno-tree-fre" } */ + +unsigned a, b; + +int +main () +{ +#if __CHAR_BIT__ == 8 + unsigned c = 1; + unsigned long long d = 0; + unsigned char e = 0; + e = __builtin_sub_overflow (d, e, &a) ? 0 : 0x80; + e = e << 7 | e >> c; + __builtin_memmove (&d, &a, 2); + b = e; + if (b != 0x40) + __builtin_abort (); +#endif + return 0; +} Jakub