On Mon, Oct 10, 2011 at 12:47 PM, Kai Tietz <ktiet...@googlemail.com> wrote:
> 2011/10/10 Richard Guenther <richard.guent...@gmail.com>:
>> On Mon, Oct 10, 2011 at 12:35 PM, Kai Tietz <ktiet...@googlemail.com> wrote:
>>> 2011/10/7 Kai Tietz <ktiet...@googlemail.com>:
>>>> Hello,
>>>>
>>>> this is the updated version with the suggestion
>>>>
>>>> 2011/10/7 Richard Guenther <richard.guent...@gmail.com>:
>>>>> On Thu, Oct 6, 2011 at 4:25 PM, Kai Tietz <kti...@redhat.com> wrote:
>>>>>> +      && ((TREE_CODE_CLASS (TREE_CODE (arg1)) != tcc_comparison
>>>>>> +           && TREE_CODE (arg1) != TRUTH_NOT_EXPR
>>>>>> +           && simple_operand_p (arg1))
>>>>>
>>>>> As I said previously simple_operand_p already rejects covers
>>>>> comparisons and TRUTH_NOT_EXPR.  Also arg1 had better
>>>>> TREE_SIDE_EFFECTS set if the comparison might trap, as
>>>>> it might just be hidden in something more complicated - so
>>>>> the simple check isn't enough anyway (and if simple_operand_p
>>>>> would cover it, the check would be better placed there).
>>>>
>>>> I reworked simple_operand_p so that it does this special-casing and 
>>>> additionally
>>>> also checks for trapping.
>>>>
>>>>>> +      if (TREE_CODE (arg0) == code
>>>>>> +          && !TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1))
>>>>>> +          && simple_operand_p (TREE_OPERAND (arg0, 1)))
>>>>>> +       {
>>>>>> +         tem = build2_loc (loc,
>>>>>> +                           (code == TRUTH_ANDIF_EXPR ? TRUTH_AND_EXPR
>>>>>> +                                                     : TRUTH_OR_EXPR),
>>>>>> +                           type, TREE_OPERAND (arg0, 1), arg1);
>>>>>> +         return build2_loc (loc, code, type, TREE_OPERAND (arg0, 0),
>>>>>> +                            tem);
>>>>>
>>>>> All trees should be folded, don't use plain build without a good reason.
>>>>
>>>> Ok, done
>>>>
>>>>>> +       }
>>>>>> +      /* Convert X TRUTH-ANDORIF Y to X TRUTH-ANDOR Y, if X and Y
>>>>>> +        are simple operands and have no side-effects.  */
>>>>>> +      if (simple_operand_p (arg0)
>>>>>> +          && !TREE_SIDE_EFFECTS (arg0))
>>>>>
>>>>> Again, the checks you do for arg0 do not match those for arg1.  OTOH
>>>>> it doesn't matter whether arg0 is simple or not or has side-effects or
>>>>> not for this transformation, so why check it at all?
>>>>
>>>> It is required.  For left-hand operand, if it isn't a logical
>>>> and/or/xor, we need to check for side-effects (and for trapping).  I
>>>> see that calling of simple_operand_p is wrong here, as it rejects too
>>>> much.  Nevertheless the check for side-effects is necessary for having
>>>> valid sequence-points.  Without that checking a simple test
>>>
>>> So said, it is even required to use for right-hand and left-hand side
>>> of arguments, if one of them have side-effects or isn't simple.  Means
>>> the check in my patch should use for
>>>
>>>> +     else if (TREE_CODE (arg0) != TRUTH_AND_EXPR
>>>> +             && TREE_CODE (arg0) != TRUTH_OR_EXPR
>>>> +             && TREE_CODE (arg0) != TRUTH_ANDIF_EXPR
>>>> +             && TREE_CODE (arg0) != TRUTH_ORIF_EXPR
>>>> +             && TREE_CODE (arg0) != TRUTH_XOR_EXPR
>>>> +             /* Needed for sequence points and trappings, or 
>>>> side-effects.  */
>>>> +             && !TREE_SIDE_EFFECTS (arg0)
>>>> +             && !tree_could_trap_p (arg0))
>>>> +       return fold_build2_loc (loc, ncode, type, arg0, arg1);
>>>
>>> instead if (!TREE_SIDE_EFFECTS (arg0) && simple_operand_p (arg0)) ....
>>> instead.
>>>
>>> The cause for this are the consitancies of sequences in tree.  I
>>> noticed that by tests in gcc.dg/tree-ssa about builitin_expect.
>>>
>>> for example we have
>>>
>>> extern int foo (void); /* foo modifies gbl1 */
>>> int gbl1 = 0;
>>>
>>> int foo (int ns1)
>>> {
>>>  if (ns1 && foo () && gbl1)
>>>    return 1;
>>>  return 0;
>>> }
>>>
>>> so chain of trees has to look like this:
>>> (ANDIF (ns1 (ANDIF foo () gbl1))
>>>
>>> but if we don't check here for side-effects for left-hand chaining
>>> operand, then we end up with
>>> (AND ns1 (ANDIF foo () gbl1))
>>
>> No we don't, as the right-hand (ANDIF foo () glbl1) has side-effects.
>>
>>> As AND and has associative property, tree says that right-hand and
>>> left-hand are exchangable, which is obviously wrong.
>>
>> The poitn is that if the right-hand does not have side-effects it doesn't
>> matter if we execute it before the left-hand (independent on whether
>> that has side-effects or not).
>>
>> Richard.
>
> thats just true as long as we don't make use of associative law for
> AND expressions.
> Otherwise we would fail for much simpler cases like
> entern int doo ();
> int foo ()
> {
>  int c, r = 0;
>  if ((c = foo ()) != 0 && c < 20)
>    r = 1;
>  return 0;
> }
>
> as for this left-hand operand has side-effects, but as it is the first
> one, we would chain it as AND.  So we get wrong sequence.

Well, then the predicates checking for simplicity and side-effects
should better match.

Richard.

> Kai
>

Reply via email to