https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118342

--- Comment #9 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Jakub Jelinek from comment #8)
> Now, at the RTL level, for SImode it could certainly be
> (set (match_operand:SI 0 "register_operand "=r")
>      (if_then_else:SI (match_operand:SI 1 "register_operand "r")
>                       (ctz:SI (match_dup 1))
>                       (match_operand:SI 2 "register_operand "0")))
> (still talking about !TARGET_BMI only), but how we represent the fact that
> it can clear the upper 32 bits of the destination or might not, dunno,
> either unspec, or just rely on us setting the value there to prec all the
> time during expansion?

With the above RTX, we don't care about and we don't guarantee anything about
the value in the highpart (outside SImode lowpart). If we want to preserve bits
outside SImode lowpart, we need to use strict_low_part, effectively creating a
SImode insert.

And as said,

(set (match_operand:DI 0 "register_operand "=r")
     (if_then_else:DI (match_operand:SI 1 "register_operand "r")
                      (zero_extend:DI (ctz:SI (match_dup 1)))
                      (match_operand:DI 2 "register_operand "0")))

would be risky, because now we guarantee that the resulting highpart is
(depending of the value of operand 1) either a zero_extend of the CTZ, or is
equal to the highpart of operand 0 - which may not be true for "some older
processors". So, the "any_extend" version of the improved RTX is invalid.

BTW: the first operand of if_then_else RTX should probably read as:

(ne (match_operand:SI 1 "register_operand" "r") (const_int 0)).

Reply via email to