Thread

Commits

  1. Update configure probes for CFLAGS needed for ARM CRC instructions.

  1. Re: BUG #18839: ARMv7 builds fail due to missing __crc32cw and similar

    Mathew Heard <mat999@gmail.com> — 2025-03-13T02:09:53Z

    Hi,
    
    The relevant commit we have removed from our build that has returned the
    ability to build is.
    
    https://github.com/postgres/postgres/commit/5980f1884fc911af120c98ad440b9546ed9012c5
    
    GCC 12.2.0-3 (latest for debian bullseye)
    Debian Bullseye
    ARMv7 (Allwinner H3)
    
    When I have time I'll remove the reverted patch and find that config.log
    
    We have tested forcing CFLAGS='-march=armv7ve+simd'
    CXXFLAGS='-march=armv7ve+simd' with no luck.
    
    Regards,
    Mathew
    
  2. Re: BUG #18839: ARMv7 builds fail due to missing __crc32cw and similar

    Tom Lane <tgl@sss.pgh.pa.us> — 2025-03-13T02:21:20Z

    Mathew Heard <mat999@gmail.com> writes:
    > The relevant commit we have removed from our build that has returned the
    > ability to build is.
    > https://github.com/postgres/postgres/commit/5980f1884fc911af120c98ad440b9546ed9012c5
    
    > GCC 12.2.0-3 (latest for debian bullseye)
    > Debian Bullseye
    > ARMv7 (Allwinner H3)
    
    We have buildfarm animals matching that description, eg grison:
    
    https://buildfarm.postgresql.org/cgi-bin/show_history.pl?nm=grison&br=master
    
    So this is not enough info to debug why it doesn't work for you.
    
    			regards, tom lane
    
    
    
    
  3. Re: BUG #18839: ARMv7 builds fail due to missing __crc32cw and similar

    Tom Lane <tgl@sss.pgh.pa.us> — 2025-03-14T00:19:42Z

    Mathew Heard <mat999@gmail.com> writes:
    > The relevant commit we have removed from our build that has returned the
    > ability to build is.
    > https://github.com/postgres/postgres/commit/5980f1884fc911af120c98ad440b9546ed9012c5
    > GCC 12.2.0-3 (latest for debian bullseye)
    > Debian Bullseye
    > ARMv7 (Allwinner H3)
    
    I spent some time today trying to reproduce this, without success.
    One thing I noticed is that Debian 11 seems to have shipped with
    gcc 10.2.1, while gcc 12.2.0 comes with Debian 12 (Bookworm).
    I don't doubt that you can get gcc 12 for Debian 11, but I wonder
    if there's some OS-vs-compiler version skew underlying this issue
    for you.
    
    The real question though is how the configure test could succeed
    only to get a failure in the main build.  If you would get
    "undefined reference to `__crc32cb'" etc in the main build,
    the configure probe should have failed in the same way.
    I tried assorted -march settings with both of those gcc versions
    and it acted as-expected for me.
    
    			regards, tom lane
    
    
    
    
  4. Re: BUG #18839: ARMv7 builds fail due to missing __crc32cw and similar

    Mathew Heard <mat999@gmail.com> — 2025-03-14T00:51:22Z

    My apologies regarding the gcc version. We have tested this on both
    bullseye ( and bookworm. I have tested on both bookworm (gcc 12.2.0)  we
    also tested on bullseye (gcc 10.2.1) to verify it wasnt GCC related, I
    extracted the build version from the wrong logs.
    
    I had some communication with our build system provider and I think they
    provided the missing key.
    
    Although we are building for ARMv7 (the container the build runs in is an
    ARMv7 base etc) the underlying hardware performing the build is an ARMv8
    CPU which works due to instruction set backwards compatibility. This is
    probably a bit esoteric but its also out of our control (and has worked
    well with postgresql and all the other packages we build for years).
    
    If I am correct, postgresql is identifying the CPU of the build system as
    ARMv8 in that test, and using this rather than the target architecture.
    Perhaps postgresql configure could look at the target architecture rather
    than the build system architecture before trying to compile for an
    unsupported march feature?
    
    Providing CFLAGS for march ARMv7 (e.g  CFLAGS='-march=armv7ve+simd') does
    not change the result of the configure test,. AFAIK other than patching out
    that commit (which is what we are currently doing) there isn't a way to
    override configure tests at the command line. Of course I could be missing
    something, by no means am I an expert in autoconf.
    
    On Fri, 14 Mar 2025 at 11:19, Tom Lane <tgl@sss.pgh.pa.us> wrote:
    
    > Mathew Heard <mat999@gmail.com> writes:
    > > The relevant commit we have removed from our build that has returned the
    > > ability to build is.
    > >
    > https://github.com/postgres/postgres/commit/5980f1884fc911af120c98ad440b9546ed9012c5
    > > GCC 12.2.0-3 (latest for debian bullseye)
    > > Debian Bullseye
    > > ARMv7 (Allwinner H3)
    >
    > I spent some time today trying to reproduce this, without success.
    > One thing I noticed is that Debian 11 seems to have shipped with
    > gcc 10.2.1, while gcc 12.2.0 comes with Debian 12 (Bookworm).
    > I don't doubt that you can get gcc 12 for Debian 11, but I wonder
    > if there's some OS-vs-compiler version skew underlying this issue
    > for you.
    >
    > The real question though is how the configure test could succeed
    > only to get a failure in the main build.  If you would get
    > "undefined reference to `__crc32cb'" etc in the main build,
    > the configure probe should have failed in the same way.
    > I tried assorted -march settings with both of those gcc versions
    > and it acted as-expected for me.
    >
    >                         regards, tom lane
    >
    
  5. Re: BUG #18839: ARMv7 builds fail due to missing __crc32cw and similar

    Tom Lane <tgl@sss.pgh.pa.us> — 2025-03-14T01:08:56Z

    Mathew Heard <mat999@gmail.com> writes:
    > If I am correct, postgresql is identifying the CPU of the build system as
    > ARMv8 in that test, and using this rather than the target architecture.
    
    The configure script isn't "identifying" anything.  It's just seeing
    whether references to __crc32cb() etc will compile with different
    -march flags.  It's not apparent why a successful test of that sort
    would not lead to a successful compilation with the same flags later
    on.  We might do a *run time* probe of the actual CPU type, but that
    has nothing to do with compilation.
    
    You still haven't told us which -march setting configure is selecting,
    nor provided the config.log trace showing why it chose that one.
    You also haven't described the compilation environment in any detail
    --- eg, I still am not sure if this is a hard-float or soft-float
    environment.
    
    			regards, tom lane
    
    
    
    
  6. Re: BUG #18839: ARMv7 builds fail due to missing __crc32cw and similar

    Tom Lane <tgl@sss.pgh.pa.us> — 2025-03-14T01:45:39Z

    I wrote:
    > The configure script isn't "identifying" anything.  It's just seeing
    > whether references to __crc32cb() etc will compile with different
    > -march flags.  It's not apparent why a successful test of that sort
    > would not lead to a successful compilation with the same flags later
    > on.
    
    Actually ... looking harder at the test code, perhaps I see a way.
    We're testing this:
    
       unsigned int crc = 0;
       crc = __crc32cb(crc, 0);
       crc = __crc32ch(crc, 0);
       crc = __crc32cw(crc, 0);
       crc = __crc32cd(crc, 0);
       /* return computed value, to prevent the above being optimized away */
       return crc == 0;
    
    but that "prevent the above being optimized away" looks mighty leaky.
    Specifically, there's nothing stopping the compiler from folding all
    these CRC calls to constants, since the input is constant.  So in
    an environment where the compiler knows these functions but glibc
    doesn't have them, perhaps we could get a false pass --- and then
    the real code with non-constant inputs could fail?
    
    I'm not very convinced of this theory, because I checked with gcc
    12.2.0 and it wouldn't do that even at max -O level.  But maybe
    your compiler is different.  Could you try the attached patch
    for configure and see if it arrives at the right conclusions?
    
    			regards, tom lane
    
    
  7. Re: BUG #18839: ARMv7 builds fail due to missing __crc32cw and similar

    Mathew Heard <mat999@gmail.com> — 2025-03-14T03:12:35Z

    Tom,
    
    When the configure test is running its forcing armv8-a+crc+simd (has
    __crc32cb, etc)  rather than testing for the feature against target
    architecture (no __crc32cb, etc). While make is compiling for the target
    architecture armv7ve+simd (no __crc32cb, etc). During the make it is of
    course failing to find __crc32cb etc, they only existed during the
    configure test due to the custom cflags used for that feature test (march
    armv8-a+crc+simd).
    
    Regardless of if CFLAGS are provided or not to make - make is
    targeting ARMv7, not what was used specifically within that specific
    configure test.
    
    I'm not really sure what's so confusing about this situation. It seems like
    a configure feature test that will always detect CRC support on any ARM gcc
    (that supports those functions). I'm mostly surprised your arm build
    environment is passing.
    
    armv7 target (no crc) does not generate functions __crc32cb etc.
    armv8-a+crc+simd does, but that isnt what make is using. Make is (as it
    should be) building a binary for armv7 not armv8-a+crc+simd. Neither does
    armv8-a without crc either.
    
    # gcc -march=armv8-a+simd test.c
    test.c: In function ‘main’:
    test.c:10:10: warning: implicit declaration of function ‘__crc32cb’
    [-Wimplicit-function-declaration]
       10 |    crc = __crc32cb(crc, 0);
          |          ^~~~~~~~~
    test.c:11:10: warning: implicit declaration of function ‘__crc32ch’
    [-Wimplicit-function-declaration]
       11 |    crc = __crc32ch(crc, 0);
          |          ^~~~~~~~~
    test.c:12:10: warning: implicit declaration of function ‘__crc32cw’
    [-Wimplicit-function-declaration]
       12 |    crc = __crc32cw(crc, 0);
          |          ^~~~~~~~~
    test.c:13:10: warning: implicit declaration of function ‘__crc32cd’
    [-Wimplicit-function-declaration]
       13 |    crc = __crc32cd(crc, 0);
          |          ^~~~~~~~~
    /usr/bin/ld: /tmp/cccXuWKB.o: in function `main':
    test.c:(.text+0xe): undefined reference to `__crc32cb'
    /usr/bin/ld: test.c:(.text+0x26): undefined reference to `__crc32ch'
    /usr/bin/ld: test.c:(.text+0x3e): undefined reference to `__crc32cw'
    /usr/bin/ld: test.c:(.text+0x56): undefined reference to `__crc32cd'
    collect2: error: ld returned 1 exit status
    
    It seems like an appropriate fix would be that test should be always no
    feature support unless detected march contains crc if armv8 or lower. All
    the feature test is currently doing is detecting GCC support for CRC. Its
    not detecting if those functions will exist at build time for the target
    architecture which is why the build fails.
    
    On Fri, 14 Mar 2025 at 13:18, Tom Lane <tgl@sss.pgh.pa.us> wrote:
    
    > Mathew Heard <mat999@gmail.com> writes:
    > > I don't think its constant folding. It looks like the configure test is
    > > doing what you are asking for, compiling for a different target
    > > architecture than the target. ARMv7 GCC knows about ARMv8
    >
    > Right, that's what we want.  What we are expecting is that the calls
    > to __crc32cb() will compile to machine instructions given the right
    > -march flag, and then we can build pg_crc32c_armv8.c that way too.
    > At runtime we'll probe to see if the target is ARMv8+CRC and if so
    > we'll call the pg_crc32c_armv8.c code to do CRC, instead of doing it
    > the hard way (see pg_crc32c_armv8_choose.c).
    >
    > What seems to be happening for you is that the configure test succeeds
    > --- presumably by generating machine instructions --- but then when
    > we try to do the very same thing to compile pg_crc32c_armv8.c,
    > suddenly the compiler disclaims knowledge of these functions.
    > That doesn't make a lot of sense, unless you've modified the build
    > process or injected some relevant CFLAGS post-configure.  So I'm
    > casting about for other explanations.
    >
    >                         regards, tom lane
    >
    
  8. Re: BUG #18839: ARMv7 builds fail due to missing __crc32cw and similar

    Tom Lane <tgl@sss.pgh.pa.us> — 2025-03-14T03:46:10Z

    Mathew Heard <mat999@gmail.com> writes:
    > When the configure test is running its forcing armv8-a+crc+simd (has
    > __crc32cb, etc)  rather than testing for the feature against target
    > architecture (no __crc32cb, etc). While make is compiling for the target
    > architecture armv7ve+simd (no __crc32cb, etc). During the make it is of
    > course failing to find __crc32cb etc, they only existed during the
    > configure test due to the custom cflags used for that feature test (march
    > armv8-a+crc+simd).
    
    No, because when pg_crc32c_armv8.c is compiled, that same -march
    setting is used for that one specific file -- trace through the
    use of CFLAGS_CRC in the Makefiles.  For instance, on buildfarm
    member grison[1] which seems like it should be a pretty close match
    for your situation, the configure log shows
    
    checking for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=... (cached) no
    checking for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=-march=armv8-a+crc+simd... (cached) yes
    checking which CRC-32C implementation to use... ARMv8 CRC instructions with runtime check
    
    and then in the build log we find
    
    ccache gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -O2 -march=armv8-a+crc+simd -I../../src/port -DFRONTEND -I../../src/include  -D_GNU_SOURCE -I/usr/include/libxml2   -c -o pg_crc32c_armv8.o pg_crc32c_armv8.c
    
    (note the -march flag) so that's expected to compile, and does,
    even though the platform is armv7l in general.  I have no idea whether
    grison's underlying hardware is v7 or v8, and it shouldn't matter for
    this purpose, because the only thing at stake is the build toolchain's
    behavior.
    
    > I'm not really sure what's so confusing about this situation. It seems like
    > a configure feature test that will always detect CRC support on any ARM gcc
    > (that supports those functions). I'm mostly surprised your arm build
    > environment is passing.
    
    I'm not sure how I can put this any more plainly: it works fine for
    everyone but you, including ARMv7 machines.  I have no intention of
    regressing performance for everyone who runs on mixed ARMv7/v8
    platforms in order to un-break your build.  We need to figure out what
    is unusual about your build environment that is causing this mechanism
    not to work as-expected.
    
    			regards, tom lane
    
    [1] https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=grison&dt=2025-03-14%2000%3A04%3A12