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]

Re: GCC optimizes integer overflow: bug or feature?


On Friday 22 December 2006 03:03, Paul Brook wrote:
> On Friday 22 December 2006 00:58, Denis Vlasenko wrote:
> > On Tuesday 19 December 2006 23:39, Denis Vlasenko wrote:
> > > There are a lot of 100.00% safe optimizations which gcc
> > > can do. Value range propagation for bitwise operations, for one
> >
> > Or this, absolutely typical C code. i386 arch can compare
> > 16 bits at a time here (luckily, no alighment worries on this arch):
> >
> > int f(char *p)
> > {
> > ? ? if (p[0] == 1 && p[1] == 2) return 1;
> > ? ? return 0;
> > }
> 
> Definitely not 100% safe. p may point to memory that is sensitive to the 
> access width and/or number of accesses. (ie. memory mapped IO).

Take a look what Linux does when you need to touch a MMIO
or PIO areas. In short: it wraps it in macros/inlines
which do all required magic (which may be rather different
on different architectures. For i386, they amount to
*(volatile char*)p).

"Simple" access to such areas with *p will never work
safely across all spectrum of hardware.


Ok, next example of real-world code I recently saw.
i >= N comparisons are completely superfluous -
programmer probably overlooked that fact.

But gcc didn't notice that either and generated 16 bytes extra
for first function:

# cat t3.c
int i64c(int i) {
        if (i <= 0) return '.';
        if (i == 1) return '/';
        if (i >= 2 && i < 12) return ('0' - 2 + i);
        if (i >= 12 && i < 38) return ('A' - 12 + i);
        if (i >= 38 && i < 63) return ('a' - 38 + i);
        return 'z';
}

int i64c_2(int i) {
        if (i <= 0) return '.';
        if (i == 1) return '/';
        if (i < 12) return ('0' - 2 + i);
        if (i < 38) return ('A' - 12 + i);
        if (i < 63) return ('a' - 38 + i);
        return 'z';
}
# gcc -O2 -c -fomit-frame-pointer t3.c
# nm --size-sort t3.o
00000038 T i64c_2
00000048 T i64c
# gcc -O2 -S -fomit-frame-pointer t3.c
# cat t3.s
        .file   "t3.c"
        .text
        .p2align 2,,3
.globl i64c
        .type   i64c, @function
i64c:
        movl    4(%esp), %edx
        testl   %edx, %edx
        jle     .L15
        cmpl    $1, %edx
        je      .L16
        leal    -2(%edx), %eax
        cmpl    $9, %eax
        jbe     .L17
        leal    -12(%edx), %eax
        cmpl    $25, %eax
        jbe     .L18
        leal    -38(%edx), %eax
        cmpl    $24, %eax
        ja      .L19
        leal    59(%edx), %eax
        ret
        .p2align 2,,3
.L17:
        leal    46(%edx), %eax
        ret
        .p2align 2,,3
.L16:
        movl    $47, %eax
        ret
        .p2align 2,,3
.L19:
        movl    $122, %eax
        ret
.L18:
        leal    53(%edx), %eax
        ret
.L15:
        movl    $46, %eax
        ret
        .size   i64c, .-i64c
        .p2align 2,,3
.globl i64c_2
        .type   i64c_2, @function
i64c_2:
        movl    4(%esp), %eax
        testl   %eax, %eax
        jle     .L33
        cmpl    $1, %eax
        je      .L34
        cmpl    $11, %eax
        jle     .L35
        cmpl    $37, %eax
        jle     .L36
        cmpl    $62, %eax
        jg      .L37
        addl    $59, %eax
        ret
        .p2align 2,,3
.L35:
        addl    $46, %eax
        ret
        .p2align 2,,3
.L34:
        movb    $47, %al
        ret
        .p2align 2,,3
.L37:
        movl    $122, %eax
        ret
.L36:
        addl    $53, %eax
        ret
.L33:
        movl    $46, %eax
        ret
        .size   i64c_2, .-i64c_2
        .ident  "GCC: (GNU) 4.2.0 20061128 (prerelease)"
        .section        .note.GNU-stack,"",@progbits

--
vda


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