• Bug#267206: gcc-3.4: vector op code generation regression

    From Matthew Dempsky@1:229/2 to All on Sat Aug 21 08:00:11 2004
    From: [email protected]

    Package: gcc-3.4
    Version: 3.4.1-4sarge1
    Severity: normal

    I'm compiling the following code example under both gcc 3.3.4-2 and 3.4.1-4sarge1:

    #include <stdio.h>

    typedef int v4si __attribute__ ((mode(V4SI)));

    static void
    print_v4si (const char * name, v4si val)
    {
    int x;

    printf ("%s:\n", name);
    for (x = 0; x < 4; ++x)
    printf (" vals[%d] = %d\n", x, ((int *)&val)[x]);
    printf ("\n");
    }

    int
    main ()
    {
    v4si a = { 1, 2, 3, 4 };
    v4si b = { 2, 3, 4, 5 };

    print_v4si ("a", a);
    print_v4si ("b", b);
    print_v4si ("a+b", a + b);

    return 0;
    }

    And here are some shell outputs compiling with 3.3 and 3.4 with and
    without sse (along with running the results and commentary):

    $ gcc-3.3 foo.c -o foo-3.3
    foo.c: In function `print_v4si':
    foo.c:14: internal compiler error: in ix86_function_arg_boundary, at config/i386/i386.c:2476
    Please submit a full bug report,
    with preprocessed source if appropriate.
    See <URL:http://gcc.gnu.org/bugs.html> for instructions.
    For Debian GNU/Linux specific bug reporting instructions, see
    <URL:file:///usr/share/doc/gcc-3.3/README.Bugs>.

    This is wrong, but it seems fixed in 3.4:

    $ gcc-3.4 foo.c -o foo-3.4
    foo.c: In function `print_v4si':
    foo.c:7: warning: SSE vector argument without SSE enabled changes the ABI
    foo.c: In function `main':
    foo.c:22: warning: SSE vector argument without SSE enabled changes the ABI
    foo.c:23: warning: SSE vector argument without SSE enabled changes the ABI
    foo.c:24: warning: SSE vector argument without SSE enabled changes the ABI
    $ ./foo-3.4
    a:
    vals[0] = 1
    vals[1] = 2
    vals[2] = 3
    vals[3] = 4

    b:
    vals[0] = 2
    vals[1] = 3
    vals[2] = 4
    vals[3] = 5

    a+b:
    vals[0] = 3
    vals[1] = 5
    vals[2] = 7
    vals[3] = 9

    Only nuissance is that the warnings seems superfluous (others may
    disagree).

    $ gcc-3.3 foo.c -o foo-3.3-sse -msse
    $ ./foo-3.3-sse
    a:
    vals[0] = 1
    vals[1] = 2
    vals[2] = 3
    vals[3] = 4

    b:
    vals[0] = 2
    vals[1] = 3
    vals[2] = 4
    vals[3] = 5

    a+b:
    vals[0] = 3
    vals[1] = 5
    vals[2] = 7
    vals[3] = 9

    This is correct.

    $ gcc-3.4 foo.c -o foo-3.4-sse -msse
    $ ./foo-3.4-sse
    a:
    vals[0] = 1
    vals[1] = 2
    vals[2] = 1
    vals[3] = -1073743580

    b:
    vals[0] = 2
    vals[1] = 3
    vals[2] = 1
    vals[3] = -1073743580

    a+b:
    vals[0] = 3
    vals[1] = 5
    vals[2] = 1
    vals[3] = -1073743580

    No warning, but the generated code seems incorrect (or at least a
    regression from 3.3) unless ((int *)&val)[x] isn't the correct
    portable way to access a vector element, but there doesn't seem to be
    an alternative that I've been able to deduce (and the documentation
    doesn't list any).

    -- System Information:
    Debian Release: 3.1
    APT prefers testing
    APT policy: (500, 'testing')
    Architecture: i386 (i686)
    Kernel: Linux 2.6.7
    Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8

    Versions of packages gcc-3.4 depends on:
    ii binutils 2.14.90.0.7-8 The GNU assembler, linker and bina ii cpp-3.4 3.4.1-4sarge1 The GNU C preprocessor
    ii gcc-3.4-base 3.4.1-4sarge1 The GNU Compiler Collection (base ii libc6 2.3.2.ds1-13 GNU C Library: Shared libraries an ii libgcc1 1:3.4.1-4sarge1 GCC support library

    -- no debconf information


    --
    To UNSUBSCRIBE, email to [email protected]
    with a subject of "unsubscribe". Trouble? Contact [email protected]

    --- SoupGate-Win32 v1.05
    * Origin: you cannot sedate... all the things you hate (1:229/2)
  • From Daniel Jacobowitz@1:229/2 to Matthew Dempsky on Sat Aug 21 16:40:07 2004
    From: [email protected]

    On Sat, Aug 21, 2004 at 12:44:03AM -0500, Matthew Dempsky wrote:
    No warning, but the generated code seems incorrect (or at least a
    regression from 3.3) unless ((int *)&val)[x] isn't the correct
    portable way to access a vector element, but there doesn't seem to be
    an alternative that I've been able to deduce (and the documentation
    doesn't list any).

    It isn't correct. Use a union; you're violating the strict-aliasing
    rules.

    --
    Daniel Jacobowitz


    --
    To UNSUBSCRIBE, email to [email protected]
    with a subject of "unsubscribe". Trouble? Contact [email protected]

    --- SoupGate-Win32 v1.05
    * Origin: you cannot sedate... all the things you hate (1:229/2)
  • From Matthew Dempsky@1:229/2 to Daniel Jacobowitz on Sat Aug 21 21:40:12 2004
    From: [email protected]

    Daniel Jacobowitz <[email protected]> writes:

    On Sat, Aug 21, 2004 at 12:44:03AM -0500, Matthew Dempsky wrote:
    No warning, but the generated code seems incorrect (or at least a
    regression from 3.3) unless ((int *)&val)[x] isn't the correct
    portable way to access a vector element, but there doesn't seem to be
    an alternative that I've been able to deduce (and the documentation
    doesn't list any).

    It isn't correct. Use a union; you're violating the strict-aliasing
    rules.

    Alright, I tried changing print_v4si to this (rest of the code the
    same):

    static void
    print_v4si (const char * name, v4si val)
    {
    union foo
    {
    v4si vector;
    int array[4];
    } l;
    int x;

    l.vector = val;

    printf ("%s:\n", name);
    for (x = 0; x < 4; ++x)
    printf (" vals[%d] = %d\n", x, l.array[x]);
    printf ("\n");
    }

    And it still generates bogus values for the third and fourth vector
    elements. I also just noticed that compiling with -march=athlon-xp
    causes all of the values to be zero.

    Or did I still not get the strict aliasing rules right?
    (-Wstrict-aliasing doesn't seem to generate a warning with either old
    or new code either.)


    --
    To UNSUBSCRIBE, email to [email protected]
    with a subject of "unsubscribe". Trouble? Contact [email protected]

    --- SoupGate-Win32 v1.05
    * Origin: you cannot sedate... all the things you hate (1:229/2)
  • From Daniel Jacobowitz@1:229/2 to Matthew Dempsky on Sat Aug 21 22:00:17 2004
    From: [email protected]

    On Sat, Aug 21, 2004 at 02:27:17PM -0500, Matthew Dempsky wrote:
    Daniel Jacobowitz <[email protected]> writes:

    On Sat, Aug 21, 2004 at 12:44:03AM -0500, Matthew Dempsky wrote:
    No warning, but the generated code seems incorrect (or at least a
    regression from 3.3) unless ((int *)&val)[x] isn't the correct
    portable way to access a vector element, but there doesn't seem to be
    an alternative that I've been able to deduce (and the documentation
    doesn't list any).

    It isn't correct. Use a union; you're violating the strict-aliasing
    rules.

    Alright, I tried changing print_v4si to this (rest of the code the
    same):

    static void
    print_v4si (const char * name, v4si val)
    {
    union foo
    {
    v4si vector;
    int array[4];
    } l;
    int x;

    l.vector = val;

    printf ("%s:\n", name);
    for (x = 0; x < 4; ++x)
    printf (" vals[%d] = %d\n", x, l.array[x]);
    printf ("\n");
    }

    And it still generates bogus values for the third and fourth vector
    elements. I also just noticed that compiling with -march=athlon-xp
    causes all of the values to be zero.

    Or did I still not get the strict aliasing rules right?
    (-Wstrict-aliasing doesn't seem to generate a warning with either old
    or new code either.)

    I'm not sure - I'd have to take a look at the generated code.

    --
    Daniel Jacobowitz


    --
    To UNSUBSCRIBE, email to [email protected]
    with a subject of "unsubscribe". Trouble? Contact [email protected]

    --- SoupGate-Win32 v1.05
    * Origin: you cannot sedate... all the things you hate (1:229/2)