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. > Cheers, > Kai >