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