On Thu, Oct 6, 2022 at 4:00 PM Michael Collison <colli...@rivosinc.com> wrote:
>
> I am trying to improve code generation for coremark to match a recent
> improvement that was made in LLVM.
>
> I added the following transformation to match.pd which attempts to
> replace a branch with straight line code:
>
> /* (cond (and (x , 0x1) == 0), y, (z ^ y) ) -> (-(and (x , 0x1)) & z ) ^
> y */
> (simplify
>      (cond (eq (bit_and @0 integer_onep@1)
>                   integer_zerop)
>           @2
>           (bit_xor:c @3 @2))
>          (bit_xor (bit_and (negate (bit_and @0 @1)) @3) @2))
>

I suspect you are missing a convert as @0/@1 might be a different type
from type (@2/@3's type).
Try:
(simplify
     (cond (eq (bit_and @0 integer_onep@1)
                  integer_zerop)
          @2
          (bit_xor:c @3 @2))
         (bit_xor (bit_and (negate (convert:type (bit_and @0 @1))) @3) @2))

But I am not 100% sure that match.pd (phiopt since that is where the
transformation is really happening) is the right place for this. I
suspect a better place is rtl level inside either simplify-rtl.cc
and/or inside ifcvt.cc.
Because on some targets has conditional moves which might be better
than doing an and/neg/and/xor.
AARCH64 and MIPS are good examples of that (I know because I spent
time making sure GCC produces the conditional moves for coremarks for
those targets inside crc8).

Thanks,
Andrew Pinski

> I get a internal error, but in stepping through the debugger I can see
> the pattern matches, but fails when when it tries to further simplify
> and match another pattern in match.pd:
>
> /* x & C -> x if we know that x & ~C == 0.  */
> #if GIMPLE
> (simplify
>   (bit_and SSA_NAME@0 INTEGER_CST@1)
>   (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
>        && wi::bit_and_not (get_nonzero_bits (@0), wi::to_wide (@1)) == 0)
>    @0))
> #endif
>
> The crash occurs in wi::bit_and_not. Before digging further I want to
> ask if there is a problem with the way I wrote the transformation?
>
>
>

Reply via email to