https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67295
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org, | |kugan at gcc dot gnu.org --- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> --- It seems the difference in *.optimized dump is that newer gcc chooses short_int SSA_NAME which has underlying variable z, but older gcc chose short_int SSA_NAME with the underlying parameter x instead. But are short ints, the only difference is that the latter happens to be a parameter, thus during expansion the x_6 SSA_NAME has RTL of (subreg/s/u:HI (reg/v:SI 114 [ x ]) 0) while z_6 SSA_NAME has RTL of (subreg/s/v:HI (reg/v:SI 110 [ z ]) 0) Seems whether the subreg is promoted unsigned or signed depends on the promote_ssa_mode, which is different for PARM_DECLs and VAR_DECLs, and arm chooses to promote most of the stuff unsigned. So, either we (certainly not 6.x material) add some type promotion pass late in the GIMPLE that would decide what types in the IL that need promoting should be promoted to what and whether signed or unsigned, or some magic during expansion, and not sure if some later pass can actually do anything here, because the fact that the argument x is already sign-extended from the caller does not show up in the IL - a pseudo is set to r0 in SImode. So, even if REE wanted, I'm afraid it wouldn't know that a r0 = sext (r0) preceeded by r0 = bswap (r0); r0 = zext (r0) which can be conditionally bypassed can be safely optimized into moving the sext into the conditional block (because the argument is already sign extended) and removing there the zero extension. Therefore, I'd suggest to just adjust the builtin-bswap-1.c testcase: short swaps16_cond (short x, int y) { - short z = x; if (y) - z = __builtin_bswap16 (x); - return foos16 (z); + x = __builtin_bswap16 (x); + return foos16 (x); } so that you test the target stuff in there, and spend time on the type promotion pass for GCC 7.