https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119402
--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #7)
> _2 = zero_one * b;
> _4 = _2 & _3;
>
> I think I am going with:
> ```
> (for bop (bit_and bit_xor bit_ior)
> (simplify
> (bop:c (mult:cs zero_one_value@0 @1) @2)
> (mult @0 (bop @1 @2))
> ```
>
> Because it applies for all bitops and not just and. This is for next week.
Nope xor nor ior works here. Only and. as 0 ^ b is b rather than 0.
For xor and ior the following would be true:
```
(for bop (bit_xor bit_ior)
(simplify
(bop:c (mult:cs zero_one_value@0 @1) @2)
(cond (ne @0 { build_zero_cst (TREE_TYPE (@0)); })
(bop @1 @2) @2))))
```
But then we go back and fourth here with this match pattern:
```
/* (zero_one != 0) ? z <op> y : y -> ((typeof(y))zero_one * z) <op> y */
(for op (bit_xor bit_ior plus)
(simplify
(cond (ne zero_one_valued_p@0
integer_zerop)
(op:c @2 @1)
@1)
(if (INTEGRAL_TYPE_P (type)
&& TYPE_PRECISION (type) > 1
&& (INTEGRAL_TYPE_P (TREE_TYPE (@0))))
(op (mult (convert:type @0) @2) @1))))
```
So back to just the bit_and then.