On Wed, Feb 13, 2019 at 12:51:26AM +0100, Eric Botcazou wrote: > > The following hunk of code results in UB on the recently added testcase, > > because if cmp_mode is SImode or DImode, then 1 << 32 or 1 << 64 is > > undefined. Fixed by using GET_MODE_MASK, plus UINTVAL because size is > > really unsigned (code later on uses unsignedp=1 too). > > Doesn't the current check make sure that the RTL constant is valid for the > mode though (since RTL constants are sign-extended for their mode)? See > emit_block_move_via_movmem for an equivalent check with GET_MODE_MASK >> 1.
The code will do: size = convert_to_mode (cmp_mode, size, 1); i.e. convert size from whatever mode it had before to cmp_mode and the test is whether it can do so without changing the behavior. If size is non-constant, then that can be obviously (without using range info etc.) done only if the original mode is narrower or at most as wide as cmp_mode. We could do the same for CONST_INT_P too, but as we know the constant, it wants to make sure that the size can be expressed in cmp_mode. As it is unsigned quantity, that can be checked by checking if the value is <= GET_MODE_MASK. Jakub