Bug 107358 - [13 Regression] i686-linux: Since r13-3290-g98e341130f8798 code fails to build libjxl-0/7.0 (vector float code)
Summary: [13 Regression] i686-linux: Since r13-3290-g98e341130f8798 code fails to buil...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 13.0
: P1 normal
Target Milestone: 13.0
Assignee: Jakub Jelinek
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-10-22 12:57 UTC by Sergei Trofimovich
Modified: 2023-05-04 07:21 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2022-10-22 00:00:00


Attachments
gcc13-pr107358.patch (1.07 KB, patch)
2022-10-22 17:30 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2022-10-22 12:57:32 UTC
Initially observed build failure on libjxl-0.7.0 on i686-linux target.

Seems to happen only on i686-unknown-linux-gnu and only on -std=c++11.

PR107295 does not seem to be enough to fix it. Here is the minimal example:

// $ cat skcms.cc
// this works:
float approx_scal(float e) {
    return e - 124.225514990f;
}

typedef float __attribute__((vector_size(4*sizeof(float)))) F;

// this fails:
//   error: conversion of scalar 'long double' to vector 'F' {aka '__vector(4) float'} involves truncation
F approx_vec(F e) {
    return e - 124.225514990f;
    //return e - 1.0f; // this works, does 'f' get ignored when float does not fit?
}


$ g++-13 -fPIC -std=c++11 -o skcms.cc.o -c skcms.cc
skcms.cc: In function 'F approx_vec(F)':
skcms.cc:10:17: warning: SSE vector return without SSE enabled changes the ABI [-Wpsabi]
   10 | F approx_vec(F e) {
      |                 ^
skcms.cc:11:14: error: conversion of scalar 'long double' to vector 'F' {aka '__vector(4) float'} involves truncation
   11 |     return e - 124.225514990f;
      |            ~~^~~~~~~~~~~~~~~~

$ g++-12 -fPIC -std=c++11 -o skcms.cc.o -c skcms.cc
skcms.cc: In function 'F approx_vec(F)':
skcms.cc:10:17: warning: SSE vector return without SSE enabled changes the ABI [-Wpsabi]
   10 | F approx_vec(F e) {
      |                 ^
skcms.cc:10:3: note: the ABI for passing parameters with 16-byte alignment has changed in GCC 4.6
   10 | F approx_vec(F e) {
      |   ^~~~~~~~~~
skcms.cc:10:3: warning: SSE vector argument without SSE enabled changes the ABI 

Note: gcc-12 works, gcc-13 fails.
Comment 1 Jakub Jelinek 2022-10-22 13:14:21 UTC
I think that is the preexisting C issue I've talked about in
https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603265.html
typedef float __attribute__((vector_size (16))) float32x4_t;
float32x4_t foo(float32x4_t x, float y) { return x + y; }
where C also fails for years with -fexcess-precision=standard.
Comment 2 Jakub Jelinek 2022-10-22 17:30:27 UTC
Created attachment 53757 [details]
gcc13-pr107358.patch

Untested fix.
Comment 3 Sergei Trofimovich 2022-10-22 23:07:13 UTC
(In reply to Jakub Jelinek from comment #2)
> Created attachment 53757 [details]
> gcc13-pr107358.patch
> 
> Untested fix.

The proposed patch fixes libjxl-0.7.0 build for me.
Comment 4 GCC Commits 2022-10-24 15:54:38 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:65e3274e363cb2c6bfe6b5e648916eb7696f7e2f

commit r13-3461-g65e3274e363cb2c6bfe6b5e648916eb7696f7e2f
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Mon Oct 24 17:53:16 2022 +0200

    c, c++: Fix up excess precision handling of scalar_to_vector conversion [PR107358]
    
    As mentioned earlier in the C++ excess precision support mail, the following
    testcase is broken with excess precision both in C and C++ (though just in C++
    it was triggered in real-world code).
    scalar_to_vector is called in both FEs after the excess precision promotions
    (or stripping of EXCESS_PRECISION_EXPR), so we can then get invalid
    diagnostics that say float vector + float involves truncation (on ia32
    from long double to float).
    
    The following patch fixes that by calling scalar_to_vector on the operands
    before the excess precision promotions, let scalar_to_vector just do the
    diagnostics (it does e.g. fold_for_warn so it will fold
    EXCESS_PRECISION_EXPR around REAL_CST to constants etc.) but will then
    do the actual conversions using the excess precision promoted operands
    (so say if we have vector double + (float + float) we don't actually do
    vector double + (float) ((long double) float + (long double) float)
    but
    vector double + (double) ((long double) float + (long double) float)
    
    2022-10-24  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/107358
    gcc/c/
            * c-typeck.cc (build_binary_op): Pass operands before excess precision
            promotions to scalar_to_vector call.
    gcc/cp/
            * typeck.cc (cp_build_binary_op): Pass operands before excess precision
            promotions to scalar_to_vector call.
    gcc/testsuite/
            * c-c++-common/pr107358.c: New test.
            * g++.dg/cpp1y/pr68180.C: Remove -fexcess-precision=fast from
            dg-options.
Comment 5 Jakub Jelinek 2022-10-24 15:55:37 UTC
Should be fixed now on the trunk.
I'll backport the C part later.
Comment 6 GCC Commits 2022-11-03 00:23:29 UTC
The releases/gcc-12 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:31f25cf4ef9a0a0ccc0b0f9158773c5a71e74cc5

commit r12-8889-g31f25cf4ef9a0a0ccc0b0f9158773c5a71e74cc5
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Mon Oct 24 17:53:16 2022 +0200

    c, c++: Fix up excess precision handling of scalar_to_vector conversion [PR107358]
    
    As mentioned earlier in the C++ excess precision support mail, the following
    testcase is broken with excess precision both in C and C++ (though just in C++
    it was triggered in real-world code).
    scalar_to_vector is called in both FEs after the excess precision promotions
    (or stripping of EXCESS_PRECISION_EXPR), so we can then get invalid
    diagnostics that say float vector + float involves truncation (on ia32
    from long double to float).
    
    The following patch fixes that by calling scalar_to_vector on the operands
    before the excess precision promotions, let scalar_to_vector just do the
    diagnostics (it does e.g. fold_for_warn so it will fold
    EXCESS_PRECISION_EXPR around REAL_CST to constants etc.) but will then
    do the actual conversions using the excess precision promoted operands
    (so say if we have vector double + (float + float) we don't actually do
    vector double + (float) ((long double) float + (long double) float)
    but
    vector double + (double) ((long double) float + (long double) float)
    
    2022-10-24  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/107358
    gcc/c/
            * c-typeck.cc (build_binary_op): Pass operands before excess precision
            promotions to scalar_to_vector call.
    gcc/testsuite/
            * c-c++-common/pr107358.c: New test.
    
    (cherry picked from commit 65e3274e363cb2c6bfe6b5e648916eb7696f7e2f)
Comment 7 GCC Commits 2022-11-04 08:31:33 UTC
The releases/gcc-11 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:57da0797a73f32c879bca77e121a4f55fcc57ce1

commit r11-10363-g57da0797a73f32c879bca77e121a4f55fcc57ce1
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Mon Oct 24 17:53:16 2022 +0200

    c, c++: Fix up excess precision handling of scalar_to_vector conversion [PR107358]
    
    As mentioned earlier in the C++ excess precision support mail, the following
    testcase is broken with excess precision both in C and C++ (though just in C++
    it was triggered in real-world code).
    scalar_to_vector is called in both FEs after the excess precision promotions
    (or stripping of EXCESS_PRECISION_EXPR), so we can then get invalid
    diagnostics that say float vector + float involves truncation (on ia32
    from long double to float).
    
    The following patch fixes that by calling scalar_to_vector on the operands
    before the excess precision promotions, let scalar_to_vector just do the
    diagnostics (it does e.g. fold_for_warn so it will fold
    EXCESS_PRECISION_EXPR around REAL_CST to constants etc.) but will then
    do the actual conversions using the excess precision promoted operands
    (so say if we have vector double + (float + float) we don't actually do
    vector double + (float) ((long double) float + (long double) float)
    but
    vector double + (double) ((long double) float + (long double) float)
    
    2022-10-24  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/107358
    gcc/c/
            * c-typeck.c (build_binary_op): Pass operands before excess precision
            promotions to scalar_to_vector call.
    gcc/testsuite/
            * c-c++-common/pr107358.c: New test.
    
    (cherry picked from commit 65e3274e363cb2c6bfe6b5e648916eb7696f7e2f)
Comment 8 Jakub Jelinek 2022-11-04 11:01:47 UTC
Fixed for 11.4+/12.3+ in C too.
Comment 9 GCC Commits 2023-05-03 15:19:24 UTC
The releases/gcc-10 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:16bdaf29ff9df3c3c70ecc07bb37511d456d05c6

commit r10-11341-g16bdaf29ff9df3c3c70ecc07bb37511d456d05c6
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Mon Oct 24 17:53:16 2022 +0200

    c, c++: Fix up excess precision handling of scalar_to_vector conversion [PR107358]
    
    As mentioned earlier in the C++ excess precision support mail, the following
    testcase is broken with excess precision both in C and C++ (though just in C++
    it was triggered in real-world code).
    scalar_to_vector is called in both FEs after the excess precision promotions
    (or stripping of EXCESS_PRECISION_EXPR), so we can then get invalid
    diagnostics that say float vector + float involves truncation (on ia32
    from long double to float).
    
    The following patch fixes that by calling scalar_to_vector on the operands
    before the excess precision promotions, let scalar_to_vector just do the
    diagnostics (it does e.g. fold_for_warn so it will fold
    EXCESS_PRECISION_EXPR around REAL_CST to constants etc.) but will then
    do the actual conversions using the excess precision promoted operands
    (so say if we have vector double + (float + float) we don't actually do
    vector double + (float) ((long double) float + (long double) float)
    but
    vector double + (double) ((long double) float + (long double) float)
    
    2022-10-24  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/107358
    gcc/c/
            * c-typeck.c (build_binary_op): Pass operands before excess precision
            promotions to scalar_to_vector call.
    gcc/testsuite/
            * c-c++-common/pr107358.c: New test.
    
    (cherry picked from commit 65e3274e363cb2c6bfe6b5e648916eb7696f7e2f)
Comment 10 Jakub Jelinek 2023-05-04 07:21:20 UTC
Fixed for 10.5 too.