$ cat labs.c extern long int labs (long int __x) __attribute__ ((__const__)); int main() { int a,b; foo(&a, &b); if (labs(a) > b) return 1; else return 0; } is translated with $ gcc -O3 -fdump-tree-optimized -S labs.c into <bb 0>: foo (&a, &b); return (int) (ABS_EXPR <(long int) a> > (long int) b); The casts aren't necessary in this case.
A better example as on 32bit targets long and int are the same size which removes the casts: extern long long int llabs (long long int __x) __attribute__ ((__const__)); int main() { int a,b; foo(&a, &b); if (llabs(a) > b) return 1; else return 0; } Or just as good: extern int abs (int __x) __attribute__ ((__const__)); void foo(short *, short*); int main() { short a,b; foo(&a, &b); if (abs(a) > b) return 1; else return 0; } Though only the first one will have different asm and will be better optimized.
Changing the summary to be more reflect what this bug is about.
Hmm, actually this is not really valid to do except when -fwrapv is supplied as (int)ABS_EXPR<(long long) 0x80000000 > is defined to be 0 but ABS_EXPR< (int)0x80000000> is undefined.
There is ABSU now. Which we use now: a.0_1 = a; _2 = ABSU_EXPR <a.0_1>; _3 = (long int) _2; b.1_4 = b; So fixed.
Fixed with r9-1281 by the way.