Question on signed overflow
Georg Lay
avr@gjlay.de
Fri Jun 18 14:08:00 GMT 2010
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.
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.
Georg
More information about the Gcc-help
mailing list