This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Type conversion and addition


Hi,

We have a problem with Kazu's following patch:

2005-12-26  Kazu Hirata  <kazu@codesourcery.com>

        PR tree-optimization/25125
        * convert.c (convert_to_integer): Don't narrow the type of a
        PLUX_EXPR or MINUS_EXPR if !flag_wrapv and the unwidened type
        is signed.

that introduced regressions in Ada (for example PR middle-end/26635).

Note that the ChangeLog entry is misleading, it should have been

        PR tree-optimization/25125
        * convert.c (convert_to_integer): Use an intermediate unsigned
	type to narrow the type of a PLUS_EXPR or MINUS_EXPR if !flag_wrapv
	and the unwidened type is signed.

The change was made in order not to "introduce signed-overflow undefinedness".


The typical expression is (int)(long int)j + o) where j is int, o long int and 
int and long int don't have the same size.  Before Kazu's change, it was 
simplified to j + (int)o.  Now take j=1 and o=INT_MIN-1.  There is indeed no 
signed-overflow undefinedness in the first expression while there is in the 
second when INT_MIN-1 is cast to int.

After the change it is simplified to (int)((unsigned int)j + (unsigned int)o).
Now take j=0 and o=-1.  There is signed-overflow undefinedness neither in the 
original expression nor in the original simplified expression while there is 
in the new simplified expression when UINT_MAX is cast to int.

So we have traded signed-overflow undefinedness in relatively rare cases for 
signed-overflow undefinedness is much more frequent cases, which hurts in 
particular Ada a lot.


Now the change installed by Kazu was not his original proposal either, the 
latter being to really disable the transformation, hence the misleading 
ChangeLog entry.  So you'd assume that reverting to the original proposal 
would be the way to go.

Then GOMP comes into play: if you disable the simplification, the following 
testcase (extracted from gcc.dg/gomp/for-17.c) fails to compile on AMD64:

void
foo (void)
{
  int j, k = 1, l = 30;
  long int o = 4;

#pragma omp for
  for (j = k; j <= l; j = j + o)
    ;
}

eric@linux:~/build/gcc/native> gcc/xgcc -Bgcc for-17.c -fopenmp
for-17.c: In function 'foo':
for-17.c:11: error: invalid increment expression

The GOMP parser chokes on the CONVERT_EXPR that has not been simplified.


How do we get away from that?  By enhancing the GOMP parser to handle 
CONVERT_EXPR like NOP_EXPR (in check_omp_for_incr_expr)?  Would other parts 
of the compiler not be silently affected by similar problems that could 
disable optimizations?  By building a NOP_EXPR in convert.c instead of a 
CONVERT_EXPR for the long int to int conversion?

Thanks in advance.

-- 
Eric Botcazou


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]