> While working with some splitters I noticed that the RTL optimisation
> passes do not optimise away a no-op wrapped in a cond_exec.
> 
> So for example, if my splitter generates something like:
> (cond_exec (lt:SI (reg:CC CC_REGNUM) (const_int 0))
>            (set (match_dup 1)
>                 (match_dup 2)))
> 
> and operand 1 and 2 are the same register (say r0), this persists through
> all the optimisation passes and results on ARM in a redundant
>  movlt r0, r0
> 
> I noticed that if I generate an unconditional SET it gets optimised away in
> the cases when it's a no-op.
> 
> I can work around this by introducing a peephole2 that lifts the SET out of
> the cond_exec like so:
> 
> (define_peephole2
> [(cond_exec (match_operator 0 "comparison_operator"
>               [(reg:CC CC_REGNUM) (const_int 0)])
>    (set (match_operand:SI 1 "register_operand" "")
>         (match_dup 1)))]
>   ""
> [(set (match_dup 1) (match_dup 1))])
> 
> and the optimisers will catch it and remove it but this seems like a hack.
>  What if it was a redundant ADD (with 0) or an AND (and r0, r0, r0)?
> Doesn't seem right to add peepholes for each of those cases.
> 
> Is that something the RTL optimisers should be able to remove?

Maybe, but it is hardly doable to recognize every RTL variant of a no-op, so 
I'd suggest fixing the pass that generates it instead.

-- 
Eric Botcazou

Reply via email to