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

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
I can see

/* (X ^ Y) ^ (X ^ Z) -> Y ^ Z  */
(simplify
 (bit_xor (convert1? (bit_xor:c @0 @1)) (convert2? (bit_xor:c @0 @2)))
 (if (tree_nop_conversion_p (type, TREE_TYPE (@1))
      && tree_nop_conversion_p (type, TREE_TYPE (@2)))
  (bit_xor (convert @1) (convert @2))))

plus

(for bitop (bit_and bit_ior bit_xor)
 (simplify
  (bitop (convert@2 @0) (convert?@3 @1))
...
   (convert (bitop @0 (convert @1)))))


simplify a deeply nested XOR chain.  Even the first pattern on its own.

But I also note we do

gimple_simplified to _1816 = _9 ^ p_17$f1_52;
_1817 = (signed char) _1816;
_1818 = (signed char) _1816;
_1819 = (signed char) _1816;
_1809 = _1816;

so we create a lot of garbage that we'll re-fold.  In particular the
loop over stmts in forwprop doesn't seem to ignore trivial zero-use
stmts?

So the above seem to happen when we create (convert ..) of something
that's already a conversion.  We code-generate

2113            if (type != res_op->type
2114                && !useless_type_conversion_p (type, res_op->type))
2115              {
2116                if (!(res_op->ops[0] = maybe_push_res_to_seq (res_op,
lseq))) goto next_after_fail651;
2117                res_op->set_op (NOP_EXPR, type, 1);
2118                res_op->resimplify (lseq, valueize);

but if the two conversions combine we've already pushed garbage to seq.
So what we'd instead want here is check if res_op can be converted
in-place.

Reply via email to