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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2023-05-05
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I think we should optimize this testcases slightly different from "improving"
fold_binary_op_with_conditional_arg (I think
fold_binary_op_with_conditional_arg 
 should go away even but that is a different story).

Let's start with:
```
int f(int a,int b){
  return (((a<=3)?-1:0)&((b<=2)?-1:0))!=0;
}
```
After ccp1 we have:
  # iftmp.1_4 = PHI <-1(4), 0(5)>
  _1 = iftmp.0_3 & iftmp.1_4;

But really that should just become:
# _1 = PHI <iftmp.0_3(4), 0(5)>

PRE does that but that is way too late.

Anyways we also have another chance of doing something:
  _1 = _9 ? _14 : 0;
  _2 = _1 != 0;

We could recognize that to be:
_t = _14 != 0
_2 = _9 & _t


For the full IR we have:
  _12 = a_5(D) <= 3;
  _13 = (int) _12;
  _14 = -_13;
  _9 = b_6(D) <= 2;
  _1 = _9 ? _14 : 0;
  _2 = _1 != 0;
  _7 = (int) _2;

Which then gets translated into:
  _12 = a_5(D) <= 3;
  _13 = (int) _12; // dead
  _14 = -_13; // dead
  _9 = b_6(D) <= 2;
  _t = _14 != 0 <-- _t = _13 != 0 <-- _12 != 0 --> _12
  _2 = _9 & _t
  _7 = (int) _2;

Which gets translated into just:
  _12 = a_5(D) <= 3;
  _9 = b_6(D) <= 2;
  _2 = _9 & _12
  _7 = (int) _2;

Which is exactly as requested.

I think I will add the pattern to match:
(cmp (cond @1 @2 CST@3) CST@4) -> (bit_ior (bit_and @1 (cmp @2 @4)) (bit_and
(bit_not @1) (cmp @3 @4)))

Not (cmp @3 @4) will simplify to either true or false which allows
the whole thing to simplify to either @1 & (cmp @2 @4) or false.

Reply via email to