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

--- Comment #11 from Jeffrey A. Law <law at gcc dot gnu.org> ---
Hmm, I think we got side-tracked on the conditional move representation.  For
this BZ I think a simple match.pd pattern may be sufficient.

x * ((x || y) != 0) -> x
x * ((x || y) == 0) -> 0

There's simplifications for the "&&" case as well, though they don't show up in
gimple as we've missed the necessary if-conversions.

(simplify
 (mult:c (convert? (ne (bit_ior:c @0 @1) integer_zerop@2)) @0)
 @0)

(simplify
 (mult:c (convert? (eq (bit_ior:c @0 @1) integer_zerop@2)) @0)
  { build_zero_cst (type); })

So given this source:

int a,b;
void func_0(int x){
    a=x*(x||b);
}
void func_1(int x){
    a=x*!(x||b);
}

We can compile that down to this code on riscv:

func_0:
        lui     a5,%hi(a)
        sw      a0,%lo(a)(a5)
        ret

func_1:
        lui     a5,%hi(a)
        sw      zero,%lo(a)(a5)
        ret

Am I missing something here?

Reply via email to