On Wed, May 22, 2024 at 3:59 PM Jakub Jelinek <ja...@redhat.com> wrote: > > On Wed, May 22, 2024 at 09:46:41AM +0200, Richard Biener wrote: > > On Wed, May 22, 2024 at 3:58 AM liuhongt <hongtao....@intel.com> wrote: > > > > > > According to IEEE standard, for conversions from floating point to > > > integer. When a NaN or infinite operand cannot be represented in the > > > destination format and this cannot otherwise be indicated, the invalid > > > operation exception shall be signaled. When a numeric operand would > > > convert to an integer outside the range of the destination format, the > > > invalid operation exception shall be signaled if this situation cannot > > > otherwise be indicated. > > > > > > The patch prevent simplication of the conversion from floating point > > > to integer for NAN/INF/out-of-range constant when flag_trapping_math. > > > > > > Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,} > > > Ok for trunk? > > > > OK if there are no further comments today. > > As I wrote in the PR, I don't think this is the right fix for the PR, > the simplify-rtx.cc change is the right thing to do, the C standard > in F.4 says that the out of range conversions to integers should raise > exceptions, but still says that the resulting value in those cases is > unspecified. > So, for the C part we should verify that with -ftrapping-math we don't > constant fold it and cover it both by pure C and perhaps backend specific > testcases which just search asm for the conversion instructions > or even runtime test which tests that the exceptions are triggered, > verify that we don't fold it either during GIMPLE opts or RTL opts > (dunno whether they can be folded in e.g. C constant initializers or not). > There're lots of warnings for Wconversion that rely on gimple fold, lots of new failures after the patch below. Should we also add -fno-trapping-math to those testcases?
- t = force_fit_type (type, val, -1, overflow | TREE_OVERFLOW (arg1)); + /* According to IEEE standard, for conversions from floating point to + integer. When a NaN or infinite operand cannot be represented in the + destination format and this cannot otherwise be indicated, the invalid + operation exception shall be signaled. When a numeric operand would + convert to an integer outside the range of the destination format, the + invalid operation exception shall be signaled if this situation cannot + otherwise be indicated. */ + if (!flag_trapping_math || !overflow) + t = force_fit_type (type, val, -1, overflow | TREE_OVERFLOW (arg1)); + else + t = NULL_TREE; + return t; } g++: c-c++-common/Wconversion-1.c -std=gnu++14 (test for warnings, line 13) g++: c-c++-common/Wconversion-1.c -std=gnu++17 (test for warnings, line 13) g++: c-c++-common/Wconversion-1.c -std=gnu++20 (test for warnings, line 13) g++: c-c++-common/Wconversion-1.c -std=gnu++98 (test for warnings, line 13) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++14 (test for warnings, line 26) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++14 (test for warnings, line 30) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++14 (test for warnings, line 34) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++14 (test for warnings, line 39) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++14 (test for warnings, line 43) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++14 (test for warnings, line 47) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++14 (test for warnings, line 51) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++14 (test for warnings, line 55) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++14 (test for warnings, line 59) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++14 execution test g++: c-c++-common/dfp/convert-int-saturate.c -std=c++17 (test for warnings, line 26) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++17 (test for warnings, line 30) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++17 (test for warnings, line 34) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++17 (test for warnings, line 39) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++17 (test for warnings, line 43) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++17 (test for warnings, line 47) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++17 (test for warnings, line 51) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++17 (test for warnings, line 55) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++17 (test for warnings, line 59) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++17 execution test g++: c-c++-common/dfp/convert-int-saturate.c -std=c++20 (test for warnings, line 26) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++20 (test for warnings, line 30) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++20 (test for warnings, line 34) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++20 (test for warnings, line 39) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++20 (test for warnings, line 43) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++20 (test for warnings, line 47) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++20 (test for warnings, line 51) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++20 (test for warnings, line 55) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++20 (test for warnings, line 59) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++20 execution test g++: c-c++-common/dfp/convert-int-saturate.c -std=c++98 (test for warnings, line 26) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++98 (test for warnings, line 30) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++98 (test for warnings, line 34) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++98 (test for warnings, line 39) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++98 (test for warnings, line 43) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++98 (test for warnings, line 47) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++98 (test for warnings, line 51) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++98 (test for warnings, line 55) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++98 (test for warnings, line 59) g++: c-c++-common/dfp/convert-int-saturate.c -std=c++98 execution test g++: g++.dg/ubsan/pr63956.C (test for errors, line 159) g++: g++.dg/ubsan/pr63956.C (test for excess errors) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 100) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 101) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 102) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 110) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 111) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 33) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 34) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 86) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 87) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 88) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 89) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 90) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 91) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 92) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 93) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 95) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 96) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 97) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 98) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++14 (test for warnings, line 99) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 100) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 101) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 102) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 110) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 111) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 33) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 34) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 86) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 87) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 88) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 89) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 90) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 91) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 92) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 93) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 95) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 96) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 97) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 98) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++17 (test for warnings, line 99) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 100) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 101) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 102) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 110) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 111) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 33) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 34) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 86) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 87) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 88) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 89) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 90) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 91) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 92) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 93) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 95) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 96) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 97) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 98) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++20 (test for warnings, line 99) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 100) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 101) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 102) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 110) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 111) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 33) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 34) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 86) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 87) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 88) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 89) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 90) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 91) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 92) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 93) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 95) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 96) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 97) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 98) g++: g++.dg/warn/Wconversion-real-integer.C -std=gnu++98 (test for warnings, line 99) gcc: c-c++-common/Wconversion-1.c -Wc++-compat (test for warnings, line 13) gcc: c-c++-common/dfp/convert-int-saturate.c (test for warnings, line 26) gcc: c-c++-common/dfp/convert-int-saturate.c (test for warnings, line 30) gcc: c-c++-common/dfp/convert-int-saturate.c (test for warnings, line 34) gcc: c-c++-common/dfp/convert-int-saturate.c (test for warnings, line 39) gcc: c-c++-common/dfp/convert-int-saturate.c (test for warnings, line 43) gcc: c-c++-common/dfp/convert-int-saturate.c (test for warnings, line 47) gcc: c-c++-common/dfp/convert-int-saturate.c (test for warnings, line 51) gcc: c-c++-common/dfp/convert-int-saturate.c (test for warnings, line 55) gcc: c-c++-common/dfp/convert-int-saturate.c (test for warnings, line 59) gcc: c-c++-common/dfp/convert-int-saturate.c execution test gcc: gcc.c-torture/execute/20031003-1.c -O0 execution test gcc: gcc.c-torture/execute/20031003-1.c -O1 execution test gcc: gcc.c-torture/execute/20031003-1.c -O2 execution test gcc: gcc.c-torture/execute/20031003-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test gcc: gcc.c-torture/execute/20031003-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test gcc: gcc.c-torture/execute/20031003-1.c -O3 -g execution test gcc: gcc.c-torture/execute/20031003-1.c -Os execution test gcc: gcc.dg/Wconversion-complex-c99.c (test for warnings, line 118) gcc: gcc.dg/Wconversion-complex-c99.c (test for warnings, line 119) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 100) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 101) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 102) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 103) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 111) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 112) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 34) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 35) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 87) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 88) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 89) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 90) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 91) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 92) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 93) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 94) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 96) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 97) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 98) gcc: gcc.dg/Wconversion-real-integer.c (test for warnings, line 99) gcc: gcc.dg/c90-const-expr-11.c (test for warnings, line 23) gcc: gcc.dg/c90-const-expr-11.c constant at line 24 (test for errors, line 23) gcc: gcc.dg/overflow-warn-8.c (test for warnings, line 10) > > Jakub > -- BR, Hongtao