On 06/18/2010 01:44 PM, Georg Lay wrote: > Andrew Haley schrieb: >> On 06/18/2010 12:00 PM, Georg Lay wrote: >>> Andrew Haley schrieb: >>>> On 06/18/2010 10:11 AM, Georg Lay wrote: >>>> What does -fdump-tree-optimized look like? >>> It looks almost as yours: >>> >>> ;; Function abssat2 (abssat2) >>> >>> Analyzing Edge Insertions. >>> abssat2 (int x) >>> { >>> unsigned int y; >>> >>> <bb 2>: >>> y = (unsigned int) x; >>> if (x < 0) >>> goto <bb 3>; >>> else >>> goto <bb 4>; >>> >>> <bb 3>: >>> y = -y; >>> >>> <bb 4>: >> >> Here may be a bug. That's an integer overflow on unsigned-signed conversion: >> >>> if ((int) y < 0) >>> goto <bb 5>; >>> else >>> goto <bb 6>; >>> >>> <bb 5>: >>> y = y + 0x0ffffffff; >>> >>> <bb 6>: >>> return (int) y; >>> >>> } > > I am not familiar with the subtle differences of SSA > representation/semantics like yours: > >> <bb 4>: >> prephitmp.15 = (int) y; >> if (prephitmp.15 < 0) > > and mine: > >> <bb 4>: >> if ((int) y < 0) > >> I still think that the fact that you get an incorrect overflow warning >> but I don't is really important. If we can find out why, I think that >> may point to the real problem. > > I think the major difference is that the stuff is very target dependent. > The warning and the optimisation are performed at the same time in the > same place, namely simplify-rtx.c: > > /* Optimize comparison of ABS with zero. */ > if (trueop1 == CONST0_RTX (mode) > && (GET_CODE (trueop0) == ABS > || (GET_CODE (trueop0) == FLOAT_EXTEND > && GET_CODE (XEXP (trueop0, 0)) == ABS))) > { > switch (code) > { > case LT: > /* Optimize abs(x) < 0.0. */ > if (!HONOR_SNANS (mode) > && (!INTEGRAL_MODE_P (mode) > || (!flag_wrapv && !flag_trapv && flag_strict_overflow))) > { > if (INTEGRAL_MODE_P (mode) > && (issue_strict_overflow_warning > (WARN_STRICT_OVERFLOW_CONDITIONAL))) > warning (OPT_Wstrict_overflow, > ("assuming signed overflow does not occur when " > "assuming abs (x) < 0 is false")); > return const0_rtx; > } > break; > > case GE: > /* Optimize abs(x) >= 0.0. */ > if (!HONOR_NANS (mode) > && (!INTEGRAL_MODE_P (mode) > || (!flag_wrapv && !flag_trapv && flag_strict_overflow))) > { > if (INTEGRAL_MODE_P (mode) > && (issue_strict_overflow_warning > (WARN_STRICT_OVERFLOW_CONDITIONAL))) > warning (OPT_Wstrict_overflow, > ("assuming signed overflow does not occur when " > "assuming abs (x) >= 0 is true")); > return const_true_rtx; > } > break; > > As i386 doesn' define an abs insn, you won't see this warning on i386 > simply because ABS rtx is never generated. I see the second warning for > ABS >= 0 on ARM. However, for ARM there is no ABS rtx genereited either, > even though arm BE defines abs insn. The bug, then, is that this abs should never have been generated. > I think the evil thing is that RTL optimizers do transformations whose > correctness depend on the signedness/qualifiers of the operand(s) > without even knowing anything about signedness/qualifiers. I don't think so: abs() is not defined on unsigned operands. Andrew.