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