[Bug middle-end/105135] New: [11/12 Regression] Optimization regression for handrolled branchless assignment
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105135 Bug ID: 105135 Summary: [11/12 Regression] Optimization regression for handrolled branchless assignment Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: andre.schackier at gmail dot com Target Milestone: --- Given the following source code [godbolt](https://godbolt.org/z/rrP3bqGW7): ```cpp char to_lower_1(const char c) { return c + ((c >= 'A' && c <= 'Z') * 32); } char to_lower_2(const char c) { return c + (((c >= 'A') & (c <= 'Z')) * 32); } char to_lower_3(const char c) { if (c >= 'A' && c <= 'Z') { return c + 32; } return c; } ``` compiling with `-O3` produces the following assembly ```asm to_lower_1(char): lea eax, [rdi-65] cmp al, 25 setbe al sal eax, 5 add eax, edi ret to_lower_2(char): lea eax, [rdi-65] cmp al, 25 setbe al sal eax, 5 add eax, edi ret to_lower_3(char): lea edx, [rdi-65] lea eax, [rdi+32] cmp dl, 26 cmovnb eax, edi ret ``` Note that gcc-10.3 did produce the same assembly for all 3 functions while gcc-11 and trunk do not.
[Bug libstdc++/105128] source_location compile error for latest clang 15
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105128 --- Comment #4 from CVS Commits --- The master branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:2a82301d409d3aa0e0b3b884e4c6daeaa0486d6b commit r12-7968-g2a82301d409d3aa0e0b3b884e4c6daeaa0486d6b Author: Jakub Jelinek Date: Sat Apr 2 12:49:38 2022 +0200 libstdc++: Tweak source_location for clang trunk [PR105128] Apparently clang trunk implemented __builtin_source_location(), but the using __builtin_ret_type = decltype(__builtin_source_location()); which has been added for it isn't enough, they also need the std::source_location::__impl class to be defined (but incomplete seems to be good enough) before the builtin is used. The following has been tested on godbolt with clang trunk (old version fails with error: 'std::source_location::__impl' was not found; it must be defined before '__builtin_source_location' is called and some follow-up errors), getting back to just void * instead of __builtin_ret_type and commenting out using doesn't work either and just struct __impl; before using __builtin_ret_type doesn't work too. 2022-04-02 Jakub Jelinek PR libstdc++/105128 * include/std/source_location (std::source_location::__impl): Move definition before using __builtin_ret_type.
[Bug libstdc++/105128] source_location compile error for latest clang 15
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105128 Jakub Jelinek changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED --- Comment #5 from Jakub Jelinek --- Fixed.
[Bug middle-end/105136] New: [11/12] Missed optimization regression with 32-bit adds and shifts
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105136 Bug ID: 105136 Summary: [11/12] Missed optimization regression with 32-bit adds and shifts Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: andre.schackier at gmail dot com Target Milestone: --- Given the following source code [godbolt](https://godbolt.org/z/daTxMYWKo) #include int32_t foo(int64_t a, int32_t b, int cond) { if (cond) { a += ((int64_t)b) << 32; } return a >> 32; } int32_t bar(int64_t a, int32_t b, int cond) { int32_t r = a >> 32; if (cond) { r += b; } return r; } and compiling with "-O3" we get the following assembly: foo: sal rsi, 32 mov rax, rdi add rax, rsi testedx, edx cmove rax, rdi shr rax, 32 ret bar: sar rdi, 32 add esi, edi testedx, edx mov eax, esi cmove eax, edi ret With gcc-10.3 we get for bar: bar: sar rdi, 32 testedx, edx lea eax, [rsi+rdi] cmove eax, edi ret Also note that neither versions recognize that foo does the same as bar. Credits: This was entirely found by Trevor Spiteri reported at the llvm-project here: https://github.com/llvm/llvm-project/issues/54718
[Bug c++/104865] Wrong code for conditional expression on VAX or with -ffast-math
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104865 Maciej W. Rozycki changed: What|Removed |Added CC||macro at orcam dot me.uk --- Comment #3 from Maciej W. Rozycki --- Should `__builtin_nan' even compile on non-IEEE-754 FP targets?
[Bug middle-end/105137] New: Missed optimization 64-bit adds and shifts
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105137 Bug ID: 105137 Summary: Missed optimization 64-bit adds and shifts Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: andre.schackier at gmail dot com Target Milestone: --- Given the following source code [godbolt](https://godbolt.org/z/8KMMhefqY) #include typedef __int128_t int128_t; int64_t foo(int128_t a, int64_t b, int cond) { if (cond) { a += ((int128_t)b) << 64; } return a >> 64; } int64_t bar(int128_t a, int64_t b, int cond) { int64_t r = a >> 64; if (cond) { r += b; } return r; } Compiling with "-O3" we get: foo: mov rax, rsi mov rsi, rdi mov rdi, rax testecx, ecx je .L2 xor r8d, r8d add rsi, r8 adc rdi, rdx .L2: mov rax, rdi ret bar: add rdx, rsi mov rax, rsi testecx, ecx cmovne rax, rdx ret Although both functions do the same, gcc implements worse code for foo. Credits: This was entirely found by Trevor Spiteri reported at the llvm-project here: https://github.com/llvm/llvm-project/issues/54718
[Bug c++/104865] Wrong code for conditional expression on VAX or with -ffast-math
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104865 --- Comment #4 from Jonathan Wakely --- They can still have NaNs.
[Bug c++/104865] Wrong code for conditional expression on VAX or with -ffast-math
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104865 --- Comment #5 from Maciej W. Rozycki --- Wrong question then. Should `__builtin_nan' even compile on non-IEEE-754 FP targets that don't have a qNaN? And I'll reply to myself. According to our manual: "-- Built-in Function: double __builtin_nan (const char *str) This is an implementation of the ISO C99 function 'nan'." and then according to ISO C99: "The nan functions return a quiet NaN, if available, with content indicated through tagp. If the implementation does not support quiet NaNs, the functions return zero." so firstly __builtin_isnan(__builtin_nan("")) is supposed to return 0 with the VAX target (because obviously 0.0 is not a NaN), and secondly the compiled program is wrong as `_ZL3nan' is supposed to be set to all-zeros (which is the representation of 0.0 datum with the VAX floating-point format), and then `c1' and `c2' must likewise be both 0. Both asserts are supposed to fail with the VAX target then (and similarly PDP-11, which has a similar FP format).
[Bug c++/104865] Wrong code for conditional expression on VAX or with -ffast-math
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104865 --- Comment #6 from Jonathan Wakely --- OK, maybe I should not have used __builtin_nan in the test. The bug is in the rest of the code though, isn't it? Replace the __builtin_nan with a function returning the same sNaN, does the test still fail? (I can't check myself right now).
[Bug fortran/105138] New: [7,8,9,10,11,12,F95] Bogus error when function name does not shadow an intrinsic when RESULT clause is used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105138 Bug ID: 105138 Summary: [7,8,9,10,11,12,F95] Bogus error when function name does not shadow an intrinsic when RESULT clause is used Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: vladimir.fuka at gmail dot com Target Milestone: --- Reported at Stackoverflow by Denis Cousineau https://stackoverflow.com/questions/71718480/gfortran-compiler-error-for-a-code-from-reputable-source/71718729?noredirect=1#comment126746262_71718729 RECURSIVE FUNCTION LOG_GAMMA(Z) RESULT(RES) COMPLEX,INTENT(IN) :: Z COMPLEX :: RES RES = LOG_GAMMA(Z); END FUNCTION LOG_GAMMA > gfortran-12 shadow.f90 shadow.f90:4:18: 4 | RES = LOG_GAMMA(Z); | 1 Error: ‘x’ argument of ‘log_gamma’ intrinsic at (1) must be REAL When the argument type agrees, the correct function is called.
[Bug fortran/105138] [7,8,9,10,11,12,F95] Bogus error when function name does not shadow an intrinsic when RESULT clause is used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105138 --- Comment #1 from Vladimir Fuka --- For after naming LOG one gets RECURSIVE FUNCTION LOG(Z) RESULT(RES) COMPLEX,INTENT(IN) :: Z COMPLEX :: RES RES = LOG(Z); END FUNCTION LOG > gfortran-12 -c shadow.f90 /tmp/ccbpyhxl.s: Assembler messages: /tmp/ccbpyhxl.s:3: Error: junk at end of line, first unrecognized character is `(' /tmp/ccbpyhxl.s:4: Error: unrecognized symbol type "" /tmp/ccbpyhxl.s:4: Error: junk at end of line, first unrecognized character is `(' /tmp/ccbpyhxl.s:5: Error: invalid character '(' in mnemonic /tmp/ccbpyhxl.s:36: Error: expected comma after name `__' in .size directive
[Bug c++/104865] Wrong code for conditional expression on VAX or with -ffast-math
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104865 --- Comment #7 from Maciej W. Rozycki --- Well, it's not clear to me whether the reserved operand as defined by the VAX floating-point architecture ought be considered an sNaN given that there is no qNaN. Also a reserved operand causes a fault with any FP instruction, even data moves (though one can move a reserved operand bit pattern with an integer move of the right width, observing that there is a single register file for both integer and FP arithmetic, and that of course FP operations can be directly performed on memory as well). In any case there's probably more than one bug here.
[Bug fortran/105138] [7,8,9,10,11,12,F95] Bogus error when function name does not shadow an intrinsic when RESULT clause is used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105138 --- Comment #2 from Vladimir Fuka --- As mentioned, the correct function is called in case everything is REAL a = floor(5.0) print *, a contains RECURSIVE FUNCTION FLOOR(Z) RESULT(RES) REAL,INTENT(IN) :: Z REAL :: RES if (z>0) then RES = FLOOR(Z - 1) else RES = 0 end if END FUNCTION FLOOR end > gfortran-12 shadow.f90 > ./a.out 0.
[Bug fortran/105138] [7,8,9,10,11,12,F95] Bogus error when function name does not shadow an intrinsic when RESULT clause is used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105138 kargl at gcc dot gnu.org changed: What|Removed |Added Priority|P3 |P4 Ever confirmed|0 |1 Status|UNCONFIRMED |NEW CC||kargl at gcc dot gnu.org Target Milestone|--- |13.0 Last reconfirmed||2022-04-02 --- Comment #3 from kargl at gcc dot gnu.org --- F2018, 15.6.2.2, page 319 If RESULT appears, the name of the function result of the function is result-name and all occurrences of the function name in execution-part statements in its scope refer to the function itself. If I change COMPLEX to REAL in the first example, I get % gfcx -c -fdump-parse-tree Namespace: A-H: (REAL 4) I-N: (INTEGER 4) O-Z: (REAL 4) procedure name = log_gamma symtree: 'log_gamma' || symbol: 'log_gamma' type spec : (REAL 4) attributes: (PROCEDURE INTRINSIC-PROC FUNCTION RECURSIVE) result: res Formal arglist: z symtree: 'res' || symbol: 'res' type spec : (REAL 4) attributes: (VARIABLE RESULT) symtree: 'z' || symbol: 'z' type spec : (REAL 4) attributes: (VARIABLE DUMMY(IN)) code: ASSIGN log_gamma:res __lgamma_4[[((log_gamma:z))]] The attributes for log_gamma includes INTRINSIC-PROC, which is clearly wrong.
[Bug fortran/105138] [7,8,9,10,11,12,F95] Bogus error when function name does not shadow an intrinsic when RESULT clause is used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105138 --- Comment #4 from kargl at gcc dot gnu.org --- (In reply to Vladimir Fuka from comment #2) > As mentioned, the correct function is called in case everything is REAL > Actually, the correct function isn't called. See the parse tree that I posted for log_gamma. For your floor example, the parse tree contains code: IF (> floor:z 0) ASSIGN floor:res __convert_i4_r4[[((__floor4_r4[[(((- floor:z 1.e0)) ((arg not-present)))]]))]] ELSE ASSIGN floor:res 0 ENDIF Notice, the __floor4_r4 is the intrinsic routine not the user-defined floor.
[Bug fortran/105138] [7,8,9,10,11,12,F95] Bogus error when function name does not shadow an intrinsic when RESULT clause is used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105138 --- Comment #5 from Vladimir Fuka --- In that case some compiler or linker magic happens after that, because the correct code is executed.
[Bug fortran/105138] [7,8,9,10,11,12,F95] Bogus error when function name does not shadow an intrinsic when RESULT clause is used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105138 --- Comment #6 from anlauf at gcc dot gnu.org --- Workaround: module m interface LOG_GAMMA module procedure LOG_GAMMA_ end interface LOG_GAMMA contains RECURSIVE FUNCTION LOG_GAMMA_(Z) RESULT(RES) COMPLEX,INTENT(IN) :: Z COMPLEX :: RES RES = LOG_GAMMA_(Z) END FUNCTION LOG_GAMMA_ end module m
[Bug tree-optimization/105139] New: GCC produces vmovw instruction with an incorrect argument for -O3 -march=sapphirerapids
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105139 Bug ID: 105139 Summary: GCC produces vmovw instruction with an incorrect argument for -O3 -march=sapphirerapids Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: vsevolod.livinskiy at gmail dot com Target Milestone: --- Link to the Compiler Explorer: https://godbolt.org/z/9GTPqWfn8 It looks like GCC produced vmovw instruction with an incorrect argument (https://software.intel.com/content/www/us/en/develop/download/intel-avx512-fp16-architecture-specification.html) Reproducer: extern long c[]; extern int d[]; long a; long e(long f) { return f < a ? f : a; } void g() { for (signed b = 0; b < 4028643; b++) d[b] = e((char)(~c[b])); } Error: >$ g++ -O3 -march=sapphirerapids -c func.cpp /tmp/ccB2zLYr.s: Assembler messages: /tmp/ccB2zLYr.s:92: Error: operand type mismatch for `vmovw' gcc version 12.0.1 20220401 (git://gcc.gnu.org/git/gcc.git:master 15d683d4f0b390b27c54a7c92c6e4f33195bdc93) P.S. I'm not sure if "tree-optimization" is the correct classification for this fault
[Bug fortran/105138] [7,8,9,10,11,12,F95] Bogus error when function name does not shadow an intrinsic when RESULT clause is used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105138 --- Comment #7 from kargl at gcc dot gnu.org --- It seems the problem is that gfortran does not know that a function name is local to its own scoping unit when a result-name is used. First, if the function is contained in a module it seems to work correctly. Consider, module foo implicit none contains recursive function log_gamma(z) result(res) complex,intent(in) :: z complex :: res complex x if (real(z) == 0) then res = 42 else x = (0,1) res = log_gamma(x) end if end function log_gamma end module foo program bar use foo implicit none complex z z = log_gamma(cmplx(2.,3.)) print *, z end program bar % gfcx -Wall -o z a.f90 a.f90:4:3: 4 |recursive function log_gamma(z) result(res) | 1 Warning: 'log_gamma' declared at (1) may shadow the intrinsic of the same name. In order to call the intrinsic, explicit INTRINSIC declarations may be required. [-Wintrinsic-shadow] % ./z (42.000,0.) Now, consider recursive function log_gamma(z) result(res) complex,intent(in) :: z complex :: res complex x if (real(z) == 0) then res = 42 else x = (0,1) res = log_gamma(x) end if end function log_gamma program bar implicit none complex z z = log_gamma(cmplx(2.,3.)) print *, z end program bar % gfcx -Wall -o z a.f90 a.f90:1:0: 1 | recursive function log_gamma(z) result(res) | Warning: 'log_gamma' declared at (1) is also the name of an intrinsic. It can only be called via an explicit interface or if declared EXTERNAL. [-Wintrinsic-shadow] a.f90:9:22: 9 | res = log_gamma(x) | 1 Error: 'x' argument of 'log_gamma' intrinsic at (1) must be REAL a.f90:16:17: 16 |z = log_gamma(cmplx(2.,3.)) | 1 Error: 'x' argument of 'log_gamma' intrinsic at (1) must be REAL I believe the first error is wrong. The local function name should block the intrinsic name. The second error is correct, because the recursive function requires an explicit interface in program bar and gfortran is picking up the intrinsic function. If the function is modified to recursive function log_gamma(z) result(res) complex,intent(in) :: z complex :: res complex x if (real(z) == 0) then res = 42 else block complex, external :: log_gamma x = (0,1) res = log_gamma(x) end block end if end function log_gamma then the first error message does not occur. The block...end block should not be required. The second error message remains as it should. If the program is modified to program bar implicit none complex z complex, external :: log_gamma z = log_gamma(cmplx(2.,3.)) print *, z end program bar or program bar implicit none interface recursive function log_gamma(z) result(res) complex,intent(in) :: z complex :: res end function log_gamma end interface complex z z = log_gamma(cmplx(2.,3.)) print *, z end program bar it compiles and runs with the block...end block modified function For completeness, if log_gamma() is a contained routine within the program it compiles and runs. program bar implicit none complex z z = log_gamma(cmplx(2.,3.)) print *, z contains recursive function log_gamma(z) result(res) complex,intent(in) :: z complex :: res complex x if (real(z) == 0) then res = 42 else x = (0,1) res = log_gamma(x) end if end function log_gamma end program bar % gfcx -Wall -o z a.f90 a.f90:7:4: 7 | recursive function log_gamma(z) result(res) |1 Warning: 'log_gamma' declared at (1) may shadow the intrinsic of the same name. In order to call the intrinsic, explicit INTRINSIC declarations may be required. [-Wintrinsic-shadow] %./z (42.000,0.)
[Bug libquadmath/105101] incorrect rounding for sqrtq
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105101 Michael_S changed: What|Removed |Added CC||already5chosen at yahoo dot com --- Comment #4 from Michael_S --- If you want quick fix for immediate shipment then you can take that: #include #include __float128 quick_and_dirty_sqrtq(__float128 x) { if (isnanq(x)) return x; if (x==0) return x; if (x < 0) return nanq(""); if (isinfq(x)) return x; int xExp; x = frexpq(x, &xExp); if (xExp & 1) x *= 2.0; // x in [0.5:2.0) __float128 r = (__float128)(1.0/sqrt((double)x)); // r=rsqrt(x) estimate (53 bits) r *= 1.5 - r*r*x*0.5; // NR iteration improves precision of r to 105.4 bit __float128 y = x*r; // y=sqrt(x) estimate (105.4 bits) // extended-precision NR iteration __float128 yH = (double)y; __float128 yL = y - yH; __float128 deltaX = x - yH*yH; deltaX -= yH*yL*2; deltaX -= yL*yL; y += deltaX*r*0.5; // improve precision of y to ~210.2 bits. Not enough for perfect rounding, but not too bad return ldexpq(y, xExp >> 1); } It is very slow, even slower than what you have now, which by itself is quite astonishingly slow. It is also not sufficiently precise for correct rounding in all cases. But, at least, the worst error is something like (0.5+2**-98) ULP, so you are unlikely to be ever caught by black box type of testing. It's biggest advantage is extreme portability. Should run on all platforms where double==IEEE binary64 and __float128 == IEEE binary128. May be, few days later I'll have better variant for "good" 64-bit platforms i.e. for those where we have __int128. It would be 15-25 times faster than the variant above and rounding would be mathematically correct rather than just "impossible to be caught" like above. But it would not run everywhere. Also, I want to give it away under MIT or BSD license, rather than under GPL.
[Bug fortran/105138] [7,8,9,10,11,12,F95] Bogus error when function name does not shadow an intrinsic when RESULT clause is used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105138 --- Comment #8 from kargl at gcc dot gnu.org --- This patch fixes the error. The comment in the patch explains it. diff --git a/gcc/fortran/intrinsic.cc b/gcc/fortran/intrinsic.cc index 52e5f4ed39e..ec833667dbe 100644 --- a/gcc/fortran/intrinsic.cc +++ b/gcc/fortran/intrinsic.cc @@ -1167,6 +1167,11 @@ gfc_is_intrinsic (gfc_symbol* sym, int subroutine_flag, locus loc) || sym->attr.if_source == IFSRC_IFBODY) return false; + /* If the function has a result-name and it's recursive, it cannot be + an intrinsic subprogram. */ + if (sym->result && sym->attr.recursive) +return false; + if (subroutine_flag) isym = gfc_find_subroutine (sym->name); else