On Mon, Feb 27, 2023 at 07:51:21PM +0000, Richard Sandiford wrote: > I think RTL and gimple are different in that respect. > SHIFT_COUNT_TRUNCATED's effect on shifts is IMO a bit like > CTZ_DEFINED_VALUE_AT_ZERO's effect on CTZ: it enumerates common > target-specific behaviour, but doesn't turn invalid/should-not-be-evaluated > values into valid values. Not defining SHIFT_COUNT_TRUNCATED is like > defining CTZ_DEFINED_VALUE_AT_ZERO to 0. > > The docs say: > > Note that regardless of this macro the ``definedness'' of @code{clz} > and @code{ctz} at zero do @emph{not} extend to the builtin functions > visible to the user. Thus one may be free to adjust the value at will > to match the target expansion of these operations without fear of > breaking the API@. > > So for CTZ this really is an RTL thing, which can leak into gimple > through ifns. I'd argue that the same is true for SHIFT_COUNT_TRUNCATED > and conditional shifts like COND_SHL: normal gimple shifts aren't guaranteed > to honour SHIFT_COUNT_TRUNCATED, but COND_SHL should be.
I understand that if SHIFT_COUNT_TRUNCATED 1 is defined, then formerly out of bounds shift is well defined on RTL. after all, for SHIFT_COUNT_TRUNCATED the generic code removes shift count masking as redundant, so code without UB in the source could otherwise appear to have UB on RTL. The question is what happens with SHIFT_COUNT_TRUNCATED 0 or C?Z_DEFINED_VALUE_AT_ZERO 0, if encountering the RTL with invalid operand(s) is undefined behavior, or simply undefined value but no other side-effects. There are many RTL expressions which invoke on invalid values really undefined behavior, it can crash the program etc. The question is if out of bounds shifts are like that too or not. Ditto for CLZ/CTZ. Jakub