https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57755
--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> --- (In reply to Andrew Pinski from comment #4) > 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. Actually another way of fixing the above is we have in forwprop3: _14 = a_5(D) <= 3; _17 = (int) _14; _18 = -_17; _9 = b_6(D) <= 2; _12 = (int) _9; _1 = _12 * _18; _2 = _1 != 0; _7 = (int) _2; Well we can see (_12 * _18) != 0 is really _12 != 0 & _18 != 0 which can be done easier as _12 has a range of [0,1]. If we do that then in forwprop3 we get: _9 = b_6(D) <= 2; _3 = a_5(D) <= 3; _2 = _3 & _9; _7 = (int) _2; which what we want ... That is that transformation is what we have in bug 110992 comment #9 . the reason for the check of [0,1] is that we know there would be no overflows and can be safely done no matter what.