On 12/5/23 01:12, Fei Gao wrote:
Take the following case for example.

CFLAGS: -march=rv64gc_zbb_zicond -mabi=lp64d -O2

long
test_AND_ceqz (long x, long y, long z, long c)
{
   if (c)
     x = y & z;
   else
     x = y;
   return x;
}

Before patch:

and     a2,a1,a2
czero.eqz       a0,a2,a3
czero.nez       a3,a1,a3
or      a0,a3,a0
ret

After patch:
and     a0,a1,a2
czero.nez       a1,a1,a3
or      a0,a1,a0
FWIW I was having a conversation with Andrew W. a little while ago and his preference was to change the IOR into an ADD. We have a better chance of using a compressed variant as c.add allows the full set of registers while c.or only allows a subset of registers. Given one of the two input registers in that IOR will always have the value zero, it should be equivalent.

Given this is target independent code we have to be careful, but I'm not immediately aware of a target where using ADD would be worse than IOR here. Anyway, feel free to submit a patch for that minor change, it'll need to queue for gcc-15, but should be non-controversial at that time.

The same trick can be done in the conditional move expander within riscv.cc.





Co-authored-by: Xiao Zeng<zengx...@eswincomputing.com>

gcc/ChangeLog:

        * ifcvt.cc (noce_cond_zero_binary_op_supported): Add support for AND.
         (noce_bbs_ok_for_cond_zero_arith): Likewise.
         (noce_try_cond_zero_arith): Likewise.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/zicond_ifcvt_opt.c: add TCs for AND.
This looks fine. I'll need to adjust the matches in the test file because we're not supporting SUBREGs. I can do that easy enough.

I 3-stage bootstrapped and regression tested this on x86_64 as well as regression tested it in rv64gc.

I'll push it to the trunk shortly.

jeff

Reply via email to