cond_exec no-ops in RTL optimisations

Kyrylo Tkachov kyrylo.tkachov@arm.com
Tue Mar 26 16:53:00 GMT 2013


Hi everyone,

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?

Are there any targets where a conditional no-op may not be removed?

Thanks,
Kyrill





More information about the Gcc mailing list