Question on signed overflow
Andrew Haley
aph@redhat.com
Fri Jun 18 15:51:00 GMT 2010
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.
More information about the Gcc-help
mailing list