[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-10 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #27 from LIU Hao  ---
Thank you!

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-10 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #24 from LIU Hao  ---
GCC 14 branch built successfully on i686-w64-mingw32 with the backported
commit. I have also built boost 1.84 successfully.

I'm now trying to fix the LD fault..

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-10 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #23 from LIU Hao  ---
I am afraid I can't do a complete bootstrap any more due to
https://sourceware.org/bugzilla/show_bug.cgi?id=31720. LD is segfaulting
randomly.

I will backport the commit to GCC 14 branch and make a non-bootstrapped build,
then build others as usual.

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #19 from LIU Hao  ---
(In reply to Jakub Jelinek from comment #17)
> Created attachment 58125 [details]
> gcc15-pr114968.patch
> 
> Here is an updated patch.
> Note, even when not taking thiscall attribute into consideration, the
> existing
> code was wrong on the !targetm.cxx.use_atexit_for_cxa_atexit () targets (aka
> mingw), because it would happily use the atexit function argument type (aka
> void (*) ()) for __cxa_thread_atexit.

Bootstrapped successfully on {i686,x86_64}-w64-mingw32. Also rebuilt mingw-w64
CRT, binutils, GDB and boost. Everything went well.

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #18 from LIU Hao  ---
(In reply to Jakub Jelinek from comment #16)
> What is the reason behind
> /* mingw32 atexit function is safe to use in shared libraries.  Use it
>to register C++ static destructors.  */
> #define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true
> ?
> Couldn't we just drop that?

I think so. We have a statically linked `atexit()` much like glibc [1]. However
we have added `__cxa_atexit()` a couple of years ago, so it might be preferred.
As the Windows system library does not provide `__cxa_*` routines, those
functions are also linked statically, so they ignore the DSO handle parameter.


 [1]
https://github.com/mingw-w64/mingw-w64/blob/19cf5d171f6df208b27271b40014c66d2b44e38b/mingw-w64-crt/crt/crtdll.c#L205
 [2]
https://github.com/mingw-w64/mingw-w64/blob/19cf5d171f6df208b27271b40014c66d2b44e38b/mingw-w64-crt/crt/cxa_atexit.c#L11


> while with __cxa_atexit one can just pass the destructor itself to the
> __cxa_atexit function (indeed with slightly more instructions there because
> in addition to the function pointer it needs to pass the address of the
> object and __dso_handle).
> But it is still smaller.

Can `./configure --enable-__cxa_atexit` be safely used? Documentation says it's
only available with glibc [3], but I don't see any stuff specific to glibc.

 [3] https://gcc.gnu.org/install/configure.html


> Anyway, if there is some strong reason to keep it, I think it would be
> better to avoid adding yet another GTY tree, the __cxa_throw last argument
> type is the same as __cxa_atexit/__cxa_thread_atexit.

Maybe it can be kept for backward compatibility.

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #15 from LIU Hao  ---
Created attachment 58124
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58124=edit
proposed patch v2

Update the patch. Did a quick test on i686-w64-mingw32 and seemed to solve the
issue.

Rebuilding everything now.

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #14 from LIU Hao  ---
I suspect it's because that `get_atexit_fn_ptr_type` is shared by `atexit` and
`__cxa_thread_atexit` but the destructors for them do not use the same calling
convention ..

So I should make a copy of it, as well as `atexit_fn_ptr_type_node`.

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #13 from LIU Hao  ---
I am using a modified patch:

```
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 4d6b2b98761..fbd9b4dac2e 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -25799,6 +25799,24 @@ ix86_bitint_type_info (int n, struct bitint_info
*info)
   return true;
 }

+/* Returns modified FUNCTION_TYPE for cdtor callabi.  */
+tree
+ix86_cxx_adjust_cdtor_callabi_fntype (tree fntype)
+{
+fprintf(stderr, "TARGET_64BIT = %d\n", (bool) TARGET_64BIT);
+fprintf(stderr, "TARGET_RTD = %d\n", (bool) TARGET_RTD);
+fprintf(stderr, "ix86_function_type_abi = %d\n", ix86_function_type_abi
(fntype));
+  if (TARGET_64BIT
+  || TARGET_RTD
+  || ix86_function_type_abi (fntype) != MS_ABI)
+return fntype;
+  /* For 32-bit MS ABI add thiscall attribute.  */
+  tree attribs = tree_cons (get_identifier ("thiscall"), NULL_TREE,
+ TYPE_ATTRIBUTES (fntype));
+fprintf(stderr, "__thiscall applied!\n");
+  return build_type_attribute_variant (fntype, attribs);
+}
+
 /* Implement PUSH_ROUNDING.  On 386, we have pushw instruction that
decrements by exactly 2 no matter what the position was, there is no pushb.

```

There is no message when compiling the testcase:

```
E:\lh_mouse\Desktop>g++ test.cc -Wall -Wextra
: error: conflicting declaration of C function 'int
__cxxabiv1::__cxa_thread_atexit(void (*)(), void*, void*)'
test.cc:3:16: note: previous declaration 'int
__cxxabiv1::__cxa_thread_atexit(void (__attribute__((thiscall)) *)(void*),
void*, void*)'
3 | extern "C" int __cxa_thread_atexit(void (__thiscall* dtor)(void*),
void* obj, void* dso) noexcept;
  |^~~
```

So I suspect this is a wrong place to look at.. ?

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #12 from LIU Hao  ---
testcase:

```
namespace __cxxabiv1
{
extern "C" int __cxa_thread_atexit(void (__thiscall* dtor)(void*), void* obj,
void* dso) noexcept;
}

struct nontrivial
{
  nontrivial();
  ~nontrivial();
};

void*
get_data()
{
  thread_local nontrivial nt;
  return 
}
```

```
E:\lh_mouse\Desktop>g++ test.cc
: error: conflicting declaration of C function 'int
__cxxabiv1::__cxa_thread_atexit(void (*)(), void*, void*)'
test.cc:3:18: note: previous declaration 'int
__cxxabiv1::__cxa_thread_atexit(void (__attribute__((thiscall)) *)(void*),
void*, void*)'
3 |   extern "C" int __cxa_thread_atexit(void (__thiscall* dtor)(void*),
void* obj, void* dso) noexcept;
  |  ^~~
```

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #11 from LIU Hao  ---
(In reply to LIU Hao from comment #10)
> (In reply to Jakub Jelinek from comment #8)
> > Created attachment 58123 [details]
> > gcc15-pr114968.patch
> > 
> > This is what I'd do, but completely untested...
> 
> It does not solve the issue.
> 

Wait, I can't reproduce the error with
```
namespace std {
class type_info;
}  // namespace std

extern "C" {
int __cxa_at_quick_exit(void (__thiscall* dtor)(void*), void* obj, void* dso)
noexcept;
int __cxa_atexit(void (__thiscall* dtor)(void*), void* obj, void* dso)
noexcept;
int __cxa_thread_atexit(void (__thiscall* dtor)(void*), void* obj, void* dso)
noexcept;
void __cxa_throw(void* obj, std::type_info* type, void (__thiscall*
dtor)(void*));
}  // extern "C"
```

Probably there's something wrong in boost configuration. Investigating.

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #10 from LIU Hao  ---
(In reply to Jakub Jelinek from comment #8)
> Created attachment 58123 [details]
> gcc15-pr114968.patch
> 
> This is what I'd do, but completely untested...

It does not solve the issue.

Side note: Although I think `-mrtd` should mostly not be useful, the MSVC `/Gz`
and Clang `-mrtd` function do not affect the calling convention of non-static
member functions; they are always `__thiscall`, which means `this` goes in ECX
and the others are passed on stack and popped by callee like `__stdcall`.

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-07 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #9 from LIU Hao  ---
(In reply to Jakub Jelinek from comment #8)
> Created attachment 58123 [details]
> gcc15-pr114968.patch
> 
> This is what I'd do, but completely untested...

Thanks. I am gonna give it a run.

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-07 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #6 from LIU Hao  ---
I suspect this isn't correct. I am getting strange errors like 'ld exited with
code 5'  not sure what could cause it (possibly also recent MSYS2 updates):

```
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 2af026d255d..f5dce6a93bc 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -9669,6 +9669,16 @@ get_atexit_fn_ptr_type (void)

   fn_type = build_function_type_list (void_type_node,
  arg_type, NULL_TREE);
+#ifdef IX86_CALLCVT_THISCALL
+  if (flag_use_cxa_atexit
+  && !targetm.cxx.use_atexit_for_cxa_atexit ())
+{
+  fn_type = copy_node (fn_type);
+  TYPE_ATTRIBUTES (fn_type) = tree_cons (
+get_identifier ("thiscall"), NULL_TREE,
+TYPE_ATTRIBUTES (fn_type));
+}
+#endif
   atexit_fn_ptr_type_node = build_pointer_type (fn_type);
 }

diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc
index f1ffda22fd3..00a8843fa2e 100644
--- a/gcc/cp/except.cc
+++ b/gcc/cp/except.cc
@@ -648,6 +648,12 @@ build_throw (location_t loc, tree exp, tsubst_flags_t
complain)
{
  tree tmp = build_function_type_list (void_type_node,
   ptr_type_node, NULL_TREE);
+#ifdef IX86_CALLCVT_THISCALL
+  tmp = copy_node (tmp);
+  TYPE_ATTRIBUTES (tmp) = tree_cons (
+get_identifier ("thiscall"), NULL_TREE,
+TYPE_ATTRIBUTES (tmp));
+#endif
  cleanup_type = build_pointer_type (tmp);
}


```

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-07 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #5 from LIU Hao  ---
(In reply to LIU Hao from comment #4)
> > (build_function_type_list returns a shared type, so if attributes are to be
> > added, it needs to go on a variant of the type.
> > 


Just saw this. So I would have to clone the tree..

[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-07 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

--- Comment #4 from LIU Hao  ---
(In reply to Jakub Jelinek from comment #2)
> Guess you need to add a target hook next to use_aeabi_atexit and
> use_atexit_for_cxa_atexit which returns attributes that should be added to a
> FUNCTION_TYPE constructed by get_atexit_fn_ptr_type
> (build_function_type_list returns a shared type, so if attributes are to be
> added, it needs to go on a variant of the type.
> 
> On all but mingw ia32 it shouldn't add anything, and guess it shouldn't be
> done if
> !flag_use_cxa_atexit || !targetm.cxx.use_atexit_for_cxa_atexit ()
> A question is what to do about the __tcf_* cleanup functions that might be
> sometimes created.
> 
> Anyway, seems to be primarily mingw maintainer responsibility given that it
> is the only target with such requirements.

I think a quick and dirty solution should look like this?

```
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 2af026d255d..311f1ca780b 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -9669,6 +9669,13 @@ get_atexit_fn_ptr_type (void)

   fn_type = build_function_type_list (void_type_node,
   arg_type, NULL_TREE);
+#ifdef IX86_CALLCVT_THISCALL
+  if (flag_use_cxa_atexit
+  && !targetm.cxx.use_atexit_for_cxa_atexit ())
+TYPE_ATTRIBUTES (fn_type) = tree_cons (
+  get_identifier ("thiscall"), NULL_TREE,
+  TYPE_ATTRIBUTES (fn_type));
+#endif
   atexit_fn_ptr_type_node = build_pointer_type (fn_type);
 }

```

[Bug target/114968] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-07 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

LIU Hao  changed:

   What|Removed |Added

 Target||i686-w64-mingw32,
   ||x86_64-w64-mingw32
 CC||nathan at acm dot org
  Known to work||13.1.0
  Known to fail||14.1.0

--- Comment #1 from LIU Hao  ---
CC'ing the author of eaeaad3fcac4d7a30b5a256410cb59fa1a3fa9dd.

The declaration of `__cxa_atexit` probably misses the exact attribute, and
requires a same fix.

[Bug target/114968] New: missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`

2024-05-07 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968

Bug ID: 114968
   Summary: missing `__thiscall` attribute on builtin declaration
of `__cxa_thread_atexit()`
   Product: gcc
   Version: 14.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

The builtin declaration lacks a `__thiscall` attribute on its first argument
(the callback) and conflicts with the libstdc++ declaration.

This issue has been introduced in eaeaad3fcac4d7a30b5a256410cb59fa1a3fa9dd.

This error is observed when building boost 1.48.

```
gcc.compile.c++
bin.v2\libs\stacktrace\build\gcc-14\release\pch-off\threadapi-win32\threading-multi\visibility-hidden\windbg_cached.o
: error: conflicting declaration of C function 'int
__cxxabiv1::__cxa_thread_atexit(void (*)(), void*, void*)'
In file included from ./boost/core/demangle.hpp:32,
 from ./boost/stacktrace/detail/frame_msvc.ipp:17,
 from libs/stacktrace/build/../src/windbg_cached.cpp:10:
C:/msys64/mingw32/include/c++/14.0.1/cxxabi.h:140:3: note: previous declaration
'int __cxxabiv1::__cxa_thread_atexit(void (__attribute__((thiscall)) *)(void*),
void*, void*)'
  140 |   __cxa_thread_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*,
void *) _GLIBCXX_NOTHROW;
```

[Bug c++/114933] [15 Regression] mcfgthread-1.6.1 typecheck failure: error: explicit specializations are not permitted here

2024-05-03 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114933

--- Comment #8 from LIU Hao  ---
Fixed in this commit:
https://github.com/lhmouse/mcfgthread/commit/86ea295e41523183e7680c03cab35e6eb74c4857

It has actually been disallowed since C++98 (N1804) but as part of a different
paragraph.

[Bug c++/114933] [15 Regression] mcfgthread-1.6.1 typecheck failure: error: explicit specializations are not permitted here

2024-05-03 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114933

--- Comment #6 from LIU Hao  ---
ISO/IEC WG21 N4917
> 13.9.4 Explicit specialization [temp.expl.spec]
> 2 An explicit specialization shall not use a storage-class-specifier (9.2.2) 
> other than thread_local.

This paragraph is new in N4658 and was not in N4917. Better to avoid it by
moving the specialization into an extern "C++" block. Thanks for the report.

[Bug target/53687] _mm_cmpistri generates redundant movslq %ecx, %rcx on x86-64

2024-04-29 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53687

LIU Hao  changed:

   What|Removed |Added

 CC||lh_mouse at 126 dot com

--- Comment #2 from LIU Hao  ---
Intel's choice that `_mm_cmpistri()` should return `int` is just awkward. The
result has always been zero-extended to RCX; similarly for `PMOVMSK` (with AVX,
`VPMOVMSKB` produces a 32-bit result which is still zero-extended).

For Clang, casting the result to `uint32_t` is sufficient to eliminate the
zero-extension; for GCC it does not work.

[Bug c/95130] GCC ignoring attribute(format(gnu_printf)) on printf in mingw

2024-04-19 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95130

--- Comment #28 from LIU Hao  ---
(In reply to Andrew Pinski from comment #27)
> %zu should be added to ms_printf too.

MSVCRT.DLL from Windows 7 does not support the `z` modifier.

It seems supported on Windows 10; however people really should prefer UCRT
there.

[Bug c/95130] GCC ignoring attribute(format(gnu_printf)) on printf in mingw

2024-04-19 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95130

--- Comment #26 from LIU Hao  ---
(In reply to Martin Storsjö from comment #25)
> But since the change in c51f1e7427e6a5ae2a6d82b5a790df77a3adc99a (released
> in GCC 12 already), we probably don't need this any longer. So I think it
> might be more correct to revert to ms_printf for UCRT, at least for GCC >=
> 12 - what do you think?

Yes, makes perfect sense.

One reason for it is the difference about `long double`, and another is that
there are GNU specifiers that MS doesn't support e.g. `%m`.

[Bug c/95130] GCC ignoring attribute(format(gnu_printf)) on printf in mingw

2024-04-18 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95130

--- Comment #24 from LIU Hao  ---
(In reply to Andrew Pinski from comment #23)
> Note since MSVC 2015 runtime, printf has support %ll so ms_printf should be
> fixed to incldue that.
> 
> https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-
> syntax-printf-and-wprintf-functions?view=msvc-140
> 
> I think for GCC 15, we should just update ms_printf to the 2015 version of
> what is supported ...

`%ll` has been supported since c51f1e7427e6a5ae2a6d82b5a790df77a3adc99a.

`%L` (for floating-point specifiers) is not compatible between `ms_printf` and
`gnu_printf`.

[Bug ipa/114262] Over-inlining when optimizing for size with gnu_inline function

2024-03-07 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114262

--- Comment #7 from LIU Hao  ---
(In reply to Jan Hubicka from comment #6)
> > Note GCC has not retuned its -Os heurstics for a long time because it has 
> > been
> > decent enough for most folks and corner cases like this is almost never come
> > up.
> There were quite few changes to -Os heuristics :)
> One of bigger challenges is that we do see more and more C++ code built
> with -Os which relies on certain functions to be inlined and optimized
> in context, so we had to get more optimistic in a hope that inlined code
> will optimize well.
> 
> COMDAT functions are more likely inlined because statistics shows that
> many of them are not really shared between translations units
> (see -param=comdat-sharing-probability parameter). This was necessary to
> get reasonable code for Firefox approx 15 years ago.

So is there no way to get the C99 extern inline behavior? i.e. sibling calls to
gnu_inline functions are inlined even when optimizing for size.

[Bug ipa/114262] Over-inlining when optimizing for size with gnu_inline function

2024-03-06 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114262

--- Comment #4 from LIU Hao  ---
(In reply to Andrew Pinski from comment #3)
> It looks like it has been this way since r0-37737-g4838c5ee553f06 (2001) (or
> rather that is when it was used by the tree inline; I don't want to dig
> further back to understand the RTL inliner). So looks like this is just
> missing documentation ...

It's not just about `gnu_inline`. If we switch to C++ inline we get the same
result:

(https://gcc.godbolt.org/z/ehbjqj5xh)
```
struct impl;
struct impl* get_impl(int key);
int get_value(struct impl* p);


extern inline
int get_value_by_key(int key)
  {
struct impl* p = get_impl(key);
if(!p)
  return -1;
return get_value(p);
  }

int real_get_value_by_key(int key)
  {
return get_value_by_key(key);
  }
```

GCC outputs:
```
real_get_value_by_key(int):
pushrsi
callget_impl(int)
testrax, rax
je  .L2
mov rdi, rax
pop rcx
jmp get_value(impl*)
.L2:
or  eax, -1
pop rdx
ret
```


If we switched to C99 `extern inline` then it would produce desired result:
```
get_value_by_key:
pushrsi
callget_impl
testrax, rax
je  .L2
mov rdi, rax
pop rcx
jmp get_value
.L2:
or  eax, -1
pop rdx
ret
real_get_value_by_key:
jmp get_value_by_key
``

The only difference between the C99 `extern inline` and C++ `extern inline` is
that the C++ external definition is COMDAT.

[Bug ipa/114262] Over-inlining when optimizing for size with gnu_inline function

2024-03-06 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114262

--- Comment #2 from LIU Hao  ---
(In reply to Andrew Pinski from comment #1)
> I thought it was documented that gnu_inline also causes always_inline if
> optimization is turned on but I can't seem to find that ...

Is that the case in GCC source? I think I would have to find a workaround for
it.

[Bug tree-optimization/114262] New: Over-inlining when optimizing for size?

2024-03-06 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114262

Bug ID: 114262
   Summary: Over-inlining when optimizing for size?
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

(https://gcc.godbolt.org/z/a4ox6oEfT)
```
struct impl;
struct impl* get_impl(int key);
int get_value(struct impl* p);


extern __inline__ __attribute__((__gnu_inline__))
int get_value_by_key(int key)
  {
struct impl* p = get_impl(key);
if(!p)
  return -1;
return get_value(p);
  }

int real_get_value_by_key(int key)
  {
return get_value_by_key(key);
  }

```

This is actually two functions, one is `gnu_inline` and the other is a
non-inline one. It looks to me that if I mark a function `gnu_inline`, I assert
that 'somewhere I shall provide an external definition for you' so when
optimizing for size, GCC may generate a call instead of using the more complex
inline definition.

The `real_get_value_by_key` function is made a deliberate sibling call, so
ideally this should be
```
real_get_value_by_key:
jmp get_value_by_key
```
and not 
```
real_get_value_by_key:
pushrsi
callget_impl
testrax, rax
je  .L2
mov rdi, rax
pop rcx
jmp get_value
.L2:
or  eax, -1
pop rdx
ret
```

It still gets inlined with `-finline-limit=0` and can only be disabled by
`-fno-inline`. I have no idea how it is controlled.

---

# Trivia

These are two `gnu_inline` functions from the same library. Most of the time
they should both be inlined in user code. However, external definitions are
required when optimization is not turned on, or when their addresses are taken,
so they must still exist. As they are unlikely to be used  anyway, optimizing
for size makes much more sense.

[Bug target/113633] FAIL: gcc.dg/bf-ms-attrib.c execution test, wrong size for ms_struct

2024-01-31 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113633

LIU Hao  changed:

   What|Removed |Added

 CC||lh_mouse at 126 dot com

--- Comment #1 from LIU Hao  ---
My suggestion is that following what MSVC produces is the only way to go.

[Bug target/53929] [meta-bug] -masm=intel with global symbol

2024-01-23 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53929

--- Comment #26 from LIU Hao  ---
Created attachment 57199
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57199=edit
Draft patch Ver. 2

1. Fix a typo in `ASM_OUTPUT_SYMBOL_REF`  (`x` => `SYM`)
2. For Intel syntax, if the name does not start with a `*`, then it is taken as
a symbol,
   and is quoted.
3. If the name starts with a `*`, then it is a request for verbatim output.
According to
   comments in 'dwarf2cfi.cc' which say 'dwarf2out.cc might give us a label
expression
   (e.g. .LVL548-1) as second argument. If so, make it a subexpression, ... '
so the name
   may be a combined expression. In this case parse it for `+` or `-` where the
symbol
   stops, then quote the symbol and print the remaining part verbatim.

[Bug target/53929] [meta-bug] -masm=intel with global symbol

2024-01-22 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53929

--- Comment #25 from LIU Hao  ---
Created attachment 57191
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57191=edit
Draft patch

This is a draft patch, bootstrapped on {i686,x86_64}-w64-mingw32 successfully.
Haven't run tests though.

[Bug libstdc++/64064] basic_filebuf seekoff return value is unusable for files opened in text mode on Windows

2024-01-19 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64064

--- Comment #2 from LIU Hao  ---
It looks that MS STL calls `_fseeki64(fp, ...)` [1], while libstdc++ calls
`lseek(_fileno(fp), ...)` [2].

The seek operation shall take the buffering of `FILE` struct into account,
hence I think the libstdc++ implementation is incorrect.


[1]
https://github.com/microsoft/STL/blob/442029c6fa37f1b6f9203357de09672d5704077c/stl/inc/__msvc_filebuf.hpp#L624
[2]
https://github.com/gcc-mirror/gcc/blob/9693459e030977d6e906ea7eb587ed09ee4fddbd/libstdc%2B%2B-v3/config/io/basic_file_stdio.cc#L425

[Bug libstdc++/64064] basic_filebuf seekoff return value is unusable for files opened in text mode on Windows

2024-01-18 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64064

LIU Hao  changed:

   What|Removed |Added

 CC||lh_mouse at 126 dot com

--- Comment #1 from LIU Hao  ---
AFAICT the only issue here is that one can't pass the result of `pubseekoff()`
back to `pubseekpos()`. Both MSVCRT GCC and UCRT GCC are affected, but MSVC
isn't.


```
#include 
#include 

int main(int, char* argv[])
{
  using traits   = std::filebuf::traits_type;
  using int_type = std::filebuf::int_type;

  std::filebuf fb;
  fb.open(argv[1], std::ios::in);

  int_type c;
  while (!traits::eq_int_type(c = fb.sbumpc(), traits::eof()))
  {
std::cout << static_cast(c);
auto pos = fb.pubseekoff(0, std::ios::cur, std::ios::in);
fb.pubseekpos(pos, std::ios::in);
  }

  std::cout << '\n';
}
```

This outputs
```
hl
ol
```

[Bug target/53929] [meta-bug] -masm=intel with global symbol

2024-01-17 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53929

--- Comment #24 from LIU Hao  ---
I've composed a proposal to address this issue:

 
https://github.com/lhmouse/mcfgthread/wiki/Formalized-Intel-Syntax-for-x86#the-proposal


The proposal is to treat names between `ptr` and `[` as symbols, and to treat
to treat names between `[` and `]` as registers. This

   lea  rax, bx[rip]

should be rejected due to invalidity, while

   lea  rax, BYTE PTR bx[rip]

can be parsed as referencing the symbol `bx` with no ambiguity.

[Bug target/99913] GCC11 fails to build for MinGW-w64 for Windows 32-bit

2024-01-15 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99913

LIU Hao  changed:

   What|Removed |Added

 CC||lh_mouse at 126 dot com

--- Comment #4 from LIU Hao  ---
Is there still such an error for you?

It looks to me that this linker command line did not contain `-pthread` unlike
the ones above. Maybe the configure script is worth looking at.

```
configure:16911: /R/winlibs32_stage/gcc-11-20210404/build_mingw/./gcc/xgcc
-B/R/winlibs32_stage/gcc-11-20210404/build_mingw/./gcc/
-L/R/winlibs32_stage/inst_gcc-11-20210404/share/gcc/i686-w64-mingw32/lib
-L/R/winlibs32_stage/inst_gcc-11-20210404/share/gcc/mingw/lib -isystem
/R/winlibs32_stage/inst_gcc-11-20210404/share/gcc/i686-w64-mingw32/include
-isystem /R/winlibs32_stage/inst_gcc-11-20210404/share/gcc/mingw/include
-B/R/winlibs32_stage/inst_gcc-11-20210404/share/gcc/i686-w64-mingw32/bin/
-B/R/winlibs32_stage/inst_gcc-11-20210404/share/gcc/i686-w64-mingw32/lib/
-isystem
/R/winlibs32_stage/inst_gcc-11-20210404/share/gcc/i686-w64-mingw32/include
-isystem
/R/winlibs32_stage/inst_gcc-11-20210404/share/gcc/i686-w64-mingw32/sys-include
--sysroot=/R/winlibs32_stage/gcc-11-20210404/build_mingw/mingw-w64   -o
conftest.exe -O0 -include confdefs.h -include
../../../libgomp/config/posix/omp-lock.h  -s conftest.c -ldl  >&5
D:\prog\winlibs32_stage\mingw32\i686-w64-mingw32\bin\ld.exe:
R:/winlibs32_stage/gcc-11-20210404/build_mingw/gcc/libgcc_eh.a(unwind-dw2.o):
in function `_gthread_once':
R:\winlibs32_stage\gcc-11-20210404\build_mingw\i686-w64-mingw32\libgcc/./gthr-default.h:700:
undefined reference to `pthread_once'
```

[Bug target/81456] [11/12/13/14 Regression] x86-64 optimizer makes wrong decision when optimizing for size

2023-12-27 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81456

LIU Hao  changed:

   What|Removed |Added

 CC||lh_mouse at 126 dot com

--- Comment #12 from LIU Hao  ---
Is this the same issue?

https://gcc.godbolt.org/z/sTs3E9EP1
```
struct stack
  {
void** base;
unsigned int top, cap;
  };

struct context
  {
void* data;
stack* st;
  };

int
clear_stack(context& ctx)
  {
ctx.st->top = 0;
return 0;
  }
```

GCC reuses RAX for `ctx.st` and the return value, so an extra XOR is generated:
```
clear_stack(context&):
 movrax,QWORD PTR [rdi+0x8]
 xoredx,edx  <-- this would be unnecessary if
 `xor eax, eax` was lifted here
 movDWORD PTR [rax+0x8],edx
 xoreax,eax
 ret
```

as in
```
clear_stack_2(context&):
 movrcx,QWORD PTR [rdi+0x8]# 48 8b 4f 08
 xoreax,eax# 31 c0
 movDWORD PTR [rcx+0x8],eax# 89 41 08
 ret   # c3
```

[Bug target/80878] -mcx16 (enable 128 bit CAS) on x86_64 seems not to work on 7.1.0

2023-12-10 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878

--- Comment #42 from LIU Hao  ---
(In reply to Yongwei Wu from comment #27)
> Anyone can show a valid use case for a non-lock-free version of 128-bit
> atomic_compare_exchange?
> 
> I am trying to use it in a data structure intended to be lock-free. I am
> surprised to find that the C++ std::atomic::compare_exchange_weak does not
> result in lock-free code for a 128-bit struct intended for ABA-free CAS. As
> a result, the GCC-generated code is MUCH slower than the mutex-based version
> in my 8-thread contention test, defeating all its valid purposes. I am
> talking about a 10x difference. And the Clang-generated code is more than
> 200x faster in the same test.

[I think this is off topic though.]

I tested CMPXCHG16B with inline assembly on an i7-1165G7 (Dell XPS 13 9305) and
it turned out to be much slower than CMPXCHG, even slower than a pair of calls
to `pthread_mutex_lock()` and unlock. Similar results were observed on a
desktop i7 11700 and a server Xeon Cascadelake. The performance degeneration
might be caused by more μops, more locking work for the extra width of
operands, and more cache synchronization, which makes some sense if we assume
the CPU should be optimized mostly for 8-byte access.

The conclusion is probably that 16-byte compare-and-swap isn't recommended.

[Bug target/97503] Suboptimal use of cntlzw and cntlzd

2023-11-27 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97503

--- Comment #8 from LIU Hao  ---
(In reply to Uroš Bizjak from comment #7)
> Actually, sign-extension, but the result is never sign-extended.

Yes but it should be a no-op right?

[Bug target/111170] [13/14 regression] Malformed manifest does not allow to run gcc on Windows XP (Accessing a corrupted shared library) since r13-6552-gd11e088210a551

2023-11-20 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70

--- Comment #9 from LIU Hao  ---
(In reply to Costas Argyris from comment #8)
> (In reply to LIU Hao from comment #3)
> > Costas, would you like to provide a configure option to exclude that
> > manifest?
> 
> I created a patch for that and attached it here:
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108865#c45
> 
> I have built it natively on x86_64-w64-mingw32 but without bootstrap yet
> (not sure if that would add anything in this particular case) and no
> i[34567]86 yet.
> 
> It would be nice if you could also give it a go in your builds.

I suspect there should be an `AC_ARG_ENABLE` in configure.ac?

[Bug target/80878] -mcx16 (enable 128 bit CAS) on x86_64 seems not to work on 7.1.0

2023-11-15 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878

--- Comment #41 from LIU Hao  ---
There should have been an option, long ago since GCC 7, which may be called

 
-mcx16-just-emit-the-god-damn-cmpxchg16b-for-me-if-it-does-not-work-its-not-your-fault


`__sync_*` are not an option as 1) they do not pass the old value and the zero
flag in a single operation, and 2) they do not accept 16-byte structs, and 3)
they are not full barriers.

[Bug target/111170] [13/14 regression] Malformed manifest does not allow to run gcc on Windows XP (Accessing a corrupted shared library) since r13-6552-gd11e088210a551

2023-11-15 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70

--- Comment #5 from LIU Hao  ---
(In reply to Costas Argyris from comment #4)
> A couple of comments:
> 
> 1) Isn't Windows XP officially not supported any more?If that is the
> case, does it make sense to introduce a new configure option solely to deal
> with an unsupported host?I'm not even sure why this is called a
> regression, given that it breaks something that is not officially supported.

I don't think we have declared Windows XP unsupported. There was even an
attempt to maintain Windows 98:
https://www.mail-archive.com/mingw-w64-public@lists.sourceforge.net/msg21399.html

I think the decision is probably we have default as Windows 10 but don't break
old systems by intention, so when someone requests it they get it.


> 2) Would it be easier if, instead of excluding the manifest via a new
> configure option, we somehow made the manifest file itself smart enough to
> ignore itself when running on Windows XP?

https://learn.microsoft.com/en-us/windows/win32/win7appqual/compatibility---application-manifest#manifestation-of-change

```
Applications without a Compatibility section in their manifest will receive
Windows Vista behavior by default on Windows 7 and future Windows versions.
Note that Windows XP and Windows Vista ignore this manifest section and it has
no impact on them.
```

But Microsoft documentation sometimes lies. If Windows XP does not ignore the
manifest and fails instead, we will need a solution.


> which has separate entries for all the Windows versions, marking them as
> 'supportedOS'.
> 
> Would it be possible to do this in the GCC manifest and solve this problem,
> or did I misunderstand how the compatibility section works?

XP was not assigned a UUID because it (2001) predated this manifest thing (2004
or 2005 I guess? since MSVCR80).

[Bug target/111170] [13/14 regression] Malformed manifest does not allow to run gcc on Windows XP (Accessing a corrupted shared library) since r13-6552-gd11e088210a551

2023-11-14 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70

--- Comment #3 from LIU Hao  ---
Costas, would you like to provide a configure option to exclude that manifest?

[Bug driver/108865] gcc on Windows fails with Unicode path to source file

2023-11-14 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108865

--- Comment #38 from LIU Hao  ---
(In reply to Andrew Pinski from comment #35)
> (In reply to peter0x44 from comment #34)
> > Unfortunately, this option breaks GCC running under Windows XP.
> 
> XP has not been supported by mingw for a long time so I have no idea how you
> have been building there.

In the last year, some efforts have been made to ensure that the mingw-w64 CRT
no longer references symbols that did not exist on XP (e.g. to provide our
alternative when there was no `llabs()`). While I didn't test it (I do not have
XP installed on any device) it was said to make GNU toolchains produce
executables that run on XP.

I'd say XP is still sort of 'supported'. However one still has to take care,
for example, not pass `%lld` to `printf()`.

[Bug target/97503] Suboptimal use of cntlzw and cntlzd

2023-11-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97503

--- Comment #5 from LIU Hao  ---
(In reply to LIU Hao from comment #4)
> lzcnt   rax, rdx
> testrdx, rdx
> mov edx, 64
> cmove   rax, rdx

There is actually another missed optimization here. LZCNT sets CF if the source
operand is zero. so the TEST instruction is totally unnecessary. We can do
this:

```
  ...
  xor eax, eax
  lzcnt rax, rdx
  mov edx, 64   # or something else, whatever
  cmovb eax, edx
```

[Bug target/97503] Suboptimal use of cntlzw and cntlzd

2023-11-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97503

LIU Hao  changed:

   What|Removed |Added

 CC||lh_mouse at 126 dot com

--- Comment #4 from LIU Hao  ---
Are there any reasons why this was not done for 64?
(https://gcc.godbolt.org/z/7vddPdxaP)


```
using int32_t = int;
using int64_t = long long;
using uint32_t = unsigned int;
using uint64_t = unsigned long long;

void
xlzcnt32(int32_t& val)
  {
val = val ? (__builtin_clz(val) & 31) : 32;
  }

void
xlzcnt64(int64_t& val)
  {
val = val ? (__builtin_clzll(val) & 63) : 64;
  }
```

results in
```
xlzcnt32(int&):
xor eax, eax
lzcnt   eax, DWORD PTR [rdi]
mov DWORD PTR [rdi], eax
ret
xlzcnt64(long long&):
mov rdx, QWORD PTR [rdi]
xor eax, eax
lzcnt   rax, rdx
testrdx, rdx
mov edx, 64
cmove   rax, rdx
mov QWORD PTR [rdi], rax
ret
```

[Bug tree-optimization/112272] New: suboptimal zero-initialization of struct of mixed pointer and integer types

2023-10-29 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112272

Bug ID: 112272
   Summary: suboptimal zero-initialization of struct of mixed
pointer and integer types
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

Testcase:
(https://gcc.godbolt.org/z/97cThnszM)

```
struct data_mixed
  {
int* p1;
int* p2;
__INTPTR_TYPE__ i3;
int* p4;

constexpr data_mixed() noexcept : p1(), p2(), i3(), p4() { }
  };

data_mixed
create_data_mixed()
  {
return {};  // somehow suboptimal ↓↓
//mov QWORD PTR [rdi+16], 0
//mov QWORD PTR [rdi+24], 0
//vmovdqu XMMWORD PTR [rdi], xmm0
  }


struct data_ptrs
  {
int* p1;
int* p2;
void* p3;
int* p4;

constexpr data_ptrs() noexcept : p1(), p2(), p3(), p4() { }
  };

data_ptrs
create_data_ptrs()
  {
return {}; // vmovdqu YMMWORD PTR [rdi], ymm0
  }


struct data_ints
  {
__INTPTR_TYPE__ p1;
__INTPTR_TYPE__ p2;
__INTPTR_TYPE__ p3;
__INTPTR_TYPE__ p4;

constexpr data_ints() noexcept : p1(), p2(), p3(), p4() { }
  };

data_ints
create_data_ints()
  {
return {};  // vmovdqu YMMWORD PTR [rdi], ymm0
  }
```

I believe these structs should be initialized in the same way, by storing a
zero YMM register. However mixed use of pointer and integer types seems to
prevent that. This is not specific to GCC 13; in GCC 12 it used to prevent
vectorization completely.

[Bug target/111170] Malformed manifest does not allow to run gcc on Windows XP (Accessing a corrupted shared library)

2023-08-27 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70

--- Comment #2 from LIU Hao  ---
(In reply to Costas Argyris from comment #1)
> Looks like '... @ Windows XP' is the Host, not the Target, in the PR.   
> Target seems irrelevant here.
> 
> LH, is this the issue you originally mentioned about my change inadvertently
> replacing the default MSYS2 manifest?

It looks like that the current GCC manifest contains values that their host
does not support. In theory it should be ignored; however if it causes errors,
it might be worth looking into.

The MSYS2 manifest contains a `compatibility` section that is not supported by
XP and Vista and is ignored [1], so it has no effect.


[1]
https://learn.microsoft.com/en-us/windows/win32/win7appqual/compatibility---application-manifest#manifestation-of-change

[Bug tree-optimization/110613] optimization about combined store of adjacent bitfields

2023-07-11 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110613

--- Comment #3 from LIU Hao  ---
There are some more cases about loading adjacent bitfields; not sure whether I
should create new PRs or paste them here. They seem highly related to the
aliasing characteristics of `unsigned char`; if I inject
`__atomic_signal_fence(__ATOMIC_RELAXED);` between the loads and the stores,
the issue is gone.

[Bug tree-optimization/110613] New: optimization about combined store of adjacent bitfields

2023-07-10 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110613

Bug ID: 110613
   Summary: optimization about combined store of adjacent
bitfields
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

This is a piece of code taken from a WebSocket frame parser:
```
#include 

struct Header 
  {
// 1st byte
uint8_t opcode : 4;
uint8_t rsv3 : 1;
uint8_t rsv2 : 1;
uint8_t rsv1 : 1;
uint8_t fin : 1;

// 2nd byte
uint8_t reserved_1 : 7;
uint8_t mask : 1;

// 3rd and 4th bytes
uint8_t reserved_2;
uint8_t reserved_3;

// 5th to 7th bytes
union {
  char mask_key[4];
  uint32_t mask_key_u32;
};

// 8th to 15th bytes
uint64_t payload_len;
  };

void
set_header(Header* ph, const uint8_t* bptr)
  {
uint8_t f = bptr[0];
uint8_t t = bptr[1];

ph->fin = f >> 7;
ph->rsv1 = f >> 6;
ph->rsv2 = f >> 5;
ph->rsv3 = f >> 4;
ph->opcode = f;

ph->mask = t >> 7;
ph->reserved_1 = t;
  }
```

The structure is designed to match x86_64 ABI (little endian), so
```
ph->fin = f >> 7;
ph->rsv1 = f >> 6;
ph->rsv2 = f >> 5;
ph->rsv3 = f >> 4;
ph->opcode = f;
```
should be a simple move (https://gcc.godbolt.org/z/9vTqs7axj), and
```
ph->mask = t >> 7;
ph->reserved_1 = t;
```
should also be a simple move (https://gcc.godbolt.org/z/KdchWvEn1), but!

When put these two pieces of code together, guess what?:
(godbolt: https://gcc.godbolt.org/z/hbEaeb3MT)
```
set_header(Header*, unsigned char const*):
movzx   edx, BYTE PTR [rsi]
movzx   ecx, BYTE PTR [rsi+1]
mov eax, edx
mov esi, edx
shr al, 4
and esi, 15
and eax, 1
sal eax, 4
or  eax, esi
mov esi, edx
shr sil, 5
and esi, 1
sal esi, 5
or  eax, esi
mov esi, edx
shr dl, 7
shr sil, 6
movzx   edx, dl
and esi, 1
sal edx, 7
sal esi, 6
or  eax, esi
or  eax, edx
mov edx, ecx
shr cl, 7
and edx, 127
sal ecx, 15
sal edx, 8
or  eax, edx
or  eax, ecx
mov WORD PTR [rdi], ax
ret
```

[Bug target/110247] suboptimal code about `no_caller_saved_registers` on caller side

2023-06-14 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110247

--- Comment #2 from LIU Hao  ---
(In reply to Andrew Pinski from comment #1)
> The way I read the documentation, it will NOT be used when dealing with

If it is known, then why shouldn't it?

One potential usecase where this would be helpful is `__errno_location()` in
GNU libc., and maybe `__emutls_get_address()`.


> And it is used only for calls from an interrupt handler (e.g. directly from
> assembly). and even more you need to use -mgeneral-regs-only too.

That function will be compiled with `-mgeneral-regs-only`, but callers need
not.

[Bug target/110247] New: suboptimal code about `no_caller_saved_registers` on caller side

2023-06-14 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110247

Bug ID: 110247
   Summary: suboptimal code about `no_caller_saved_registers` on
caller side
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

Given:
(https://gcc.godbolt.org/z/xevzx56Y5)

```
int complex(int x, int y)
  __attribute__((__no_caller_saved_registers__));

int test(int x, int y, int z)
  {
return complex(x, y) + complex(y, z) + complex(z, x);
  }
```


My understanding is that `__no_caller_saved_registers__` says no register will
be clobbered by `complex`, so it is not necessary for GCC to establish a stack
frame and push arguments there. This is gonna help a lot if the function will
be inlined.


Clang generates much better assembly but I wonder whether it is valid to assume
that arguments registers are also preserved, like

```
test:
  push rcx; align %rsp
  ; %edi := x, %esi = y, %edx = z
  call complex;
  mov ecx, eax; %ecx = complex(x, y)
  xchg edi, esi   ; %edi = y
  xchg esi, edx   ; %esi = z, %edx = x
  call complex;
  add ecx, eax; %ecx += complex(y, z)
  mov edi, esi; %edi = z
  mov esi, edx; %esi = x
  call complex;
  add eax, ecx; %eax = %ecx + complex(z, x)
  pop rcx
  ret
```

[Bug rtl-optimization/110008] New: early returns from functions result in suboptimal code

2023-05-27 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110008

Bug ID: 110008
   Summary: early returns from functions result in suboptimal code
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: rtl-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

https://gcc.godbolt.org/z/94Wf3Worq
```
int complex_one(int, int);

int
test(int a, int b, int c)
  {
if(__builtin_expect(a, 0) == 0)
  return 0;

int r = complex_one(a, b);
r += complex_one(r, c);
return r + a + b;
  }
```

GCC:
```
test:
pushrdi
pushrsi
pushrbx
sub rsp, 32
mov ebx, ecx
mov esi, edx
testecx, ecx
jne .L7
mov eax, ebx
add rsp, 32
pop rbx
pop rsi
pop rdi
ret
.L7:
mov DWORD PTR 80[rsp], r8d
callcomplex_one
mov edx, DWORD PTR 80[rsp]
mov ecx, eax
mov edi, eax
callcomplex_one
add edi, eax
add ebx, edi
add ebx, esi
mov eax, ebx
add rsp, 32
pop rbx
pop rsi
pop rdi
ret
```

Clang:
```
test:   # @test
xor eax, eax
testedi, edi
jne .LBB0_1
ret
.LBB0_1:
pushrbp
pushr15
pushr14
pushrbx
pushrax
mov r14d, edx
mov ebx, esi
mov ebp, edi
callcomplex_one@PLT
mov r15d, eax
mov edi, eax
mov esi, r14d
callcomplex_one@PLT
add ebx, ebp
add ebx, r15d
add ebx, eax
mov eax, ebx
add rsp, 8
pop rbx
pop r14
pop r15
pop rbp
ret
```

There are two issues in this code: The first one is that GCC uses apparently
more space for temporary variables than Clang. The other is that when `a`
equals zero, Clang skips the normal function prologue which pushes a lot of
registers onto the stack, but GCC performs the check after it, in which case
both the prologue and epilogue get executed for nothing.

[Bug rtl-optimization/109992] New: Addition/subtraction to the last bitfield of a struct can be optimized

2023-05-26 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109992

Bug ID: 109992
   Summary: Addition/subtraction to the last bitfield of a struct
can be optimized
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: rtl-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

For an unsigned bit field:
```
struct foo
  {
unsigned a :  3;
unsigned b : 29;
  };

void
bad_add(struct foo* p, unsigned add)
  {
p->b += add;
  }
```

GCC:
```
bad_add:
mov eax, DWORD PTR [rdi]
mov edx, eax
and eax, 7
shr edx, 3
add edx, esi
sal edx, 3
or  eax, edx
mov DWORD PTR [rdi], eax
ret
```

Clang:
```
bad_add:# @bad_add
shl esi, 3
add dword ptr [rdi], esi
ret
```

It looks like GCC extracts the bitfield first, performs the addition, then
inserts it back.

The result is almost the same for a signed bitfield, but not exacting the
bitfield first is subject to overflows, so it may be a different story.

[Bug tree-optimization/109950] can array subscripts be assumed to be non-negative?

2023-05-25 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109950

--- Comment #4 from LIU Hao  ---
Given the fact that GCC is already able to warn about out-of-range indexes for
an array, why wouldn't it be possible to infer that `*(data + next)` is always
an element of `data`?

If the result of `data + next` (after array-to-pointer conversion) does not
point to an element of `data` (or the past-the-end position, but that's not the
case, as it's not dereferenceable), then the behavior will be undefined.

[Bug tree-optimization/109950] can array subscripts be assumed to be non-negative?

2023-05-24 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109950

--- Comment #2 from LIU Hao  ---
(In reply to Alexander Monakov from comment #1)
> That's the REX prefix, not an operand size override prefix. It doesn't cause
> a decoding stall.

Thanks for pointing this out. Thought it was 66H.

[Bug tree-optimization/109950] New: can array subscripts be assumed to be non-negative?

2023-05-23 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109950

Bug ID: 109950
   Summary: can array subscripts be assumed to be non-negative?
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

There is a lot of historical code which has been using `int` for array indexes:

```
extern int data[];
extern int next;

int
test_function(int* outptr)
  {
*outptr = data[next];
return next >= 0;
  }
```

In this example, the value of `next` is used as an array index. Despite the
unknown size, elements in an array can't have negative indexes, so maybe here
`next >= 0` can be optimized to a constant?


Specifically about x86_64, there is some more optimization that we can do: The
value of `next` can be loaded into a 32-bit register, zeroing the upper half
implicitly, without using a sign-extension instruction, as in machine code:

```
48 63 05 IMM32   ; movsxd rax, dword ptr [rip + IMM32]
   8B 05 IMM32   ; moveax, dword ptr [rip + IMM32]
```

The former contains an operand size override prefix, takes up one more byte,
and costs an extra cycle to decode.

[Bug target/109257] `-masm=intel` generates weird syntax for indirect jumps

2023-05-20 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109257

--- Comment #6 from LIU Hao  ---
gcc/config/i386/i386.cc:
```
void
ix86_print_operand (FILE *file, rtx x, int code)
{
  if (code)
{
  switch (code)
{
case 'A':
  switch (ASSEMBLER_DIALECT)
{
case ASM_ATT:
  putc ('*', file);
  break;

case ASM_INTEL:
  /* Intel syntax. For absolute addresses, registers should not
 be surrounded by braces.  */
  if (!REG_P (x))
{
  putc ('[', file);
  ix86_print_operand (file, x, 0);
  putc (']', file);
  return;
}
  break;

default:
  gcc_unreachable ();
}

  ix86_print_operand (file, x, 0);
  return;
```

I hope someone can clean this up a bit. The AT part is an obvious recursion,
so why should we write something like that? It could be

```
case 'A':
  if (ASSEMBLER_DIALECT == ASM_ATT)
{
  putc ('*', file);
  break;
}

  // intel stuff here.
  return;

```

[Bug libgcc/109670] [13/14 regression] Exception handling broken for 32-bit Windows

2023-05-12 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109670

--- Comment #14 from LIU Hao  ---
(In reply to Thomas Neumann from comment #12)
> Created attachment 55037 [details]
> radix sort fix
> 
> I could reproduce the problem, the radix sort did not behave correctly when
> we ran out of bits, which can happen on 32bit platforms. The attached patch
> fixes the problem.

This fixes GDB for me.

[Bug libgcc/109670] [13/14 regression] Exception handling broken for 32-bit Windows

2023-05-12 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109670

--- Comment #13 from LIU Hao  ---
I will test this later today.

[Bug target/53929] [meta-bug] -masm=intel with global symbol

2023-05-11 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53929

--- Comment #23 from LIU Hao  ---
Changes to GCC should look like this I suspect (I didn't test this):

```
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index fbd33a6bfd1..de80c7a805f 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -14080,7 +14080,11 @@ ix86_print_operand_address_as (FILE *file, rtx addr,
  if (flag_pic)
output_pic_addr_const (file, disp, 0);
  else if (GET_CODE (disp) == LABEL_REF)
-   output_asm_label (disp);
+   {
+ putc ('\"', file);
+ output_asm_label (disp);
+ putc ('\"', file);
+   }
  else if (CONST_INT_P (disp))
offset = disp;
  else
```

It's a bit strange that `output_asm_label` writes output via a global `FILE*`.

[Bug target/53929] [meta-bug] -masm=intel with global symbol

2023-05-11 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53929

--- Comment #21 from LIU Hao  ---
(In reply to jbeulich from comment #20)
> This is assembly; I don't see how (dis)similarity with C would matter. I
> also don't see how your example is any different in this regard from
> 
> mov eax, "symbol"
> 
> which gas has been supporting for quite some time.

oh really? I thought it would have to be implemented. If it's readily
available, we can start making use of it right now.

[Bug target/53929] [meta-bug] -masm=intel with global symbol

2023-05-11 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53929

--- Comment #19 from LIU Hao  ---
(In reply to jbeulich from comment #11)
> I have a rough plan on the gas side, but that will then need a gcc side
> change as well: For a couple of years we have had quoted symbol names there.
> While this doesn't currently work right in a number of cases (including the
> one needed here) the plan is to make e.g.
> 
> mov eax, "ecx"
> 
> not be treated the same as
> 
> mov eax, ecx
> 
> but considering "ecx" a symbol name due to the quotation. Obviously gcc's

I don't like double quotes here, because it looks something different, like in
C. Would it make some sense if we take the approach for MIPS and AArch64 [1],
so

  mov eax, %ecx

or

  mov eax, :ecx

denotes `ecx` is the name of a label, and otherwise a register. Also, such a
prefix should be optional, so people who write assembly can omit it if they
carefully avoid such names.


[1] https://maskray.me/blog/2023-05-08-assemblers

[Bug libgcc/109670] Exception handling broken for 32bit Windows starting with GCC 13

2023-05-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109670

--- Comment #11 from LIU Hao  ---
(In reply to Thomas Neumann from comment #10)
> (In reply to LIU Hao from comment #9)
> > GDB is affected, too:
> 
> I will debug that. That is easier to build than Ada. Strange that it only
> affects 32bit Windows. I will take a look.

Only on i686-w64-mingw64 is DWARF2 used for exception handling; SEH is used on
all the other *-w64-mingw32 targets.

[Bug libgcc/109670] Exception handling broken for 32bit Windows starting with GCC 13

2023-05-08 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109670

--- Comment #9 from LIU Hao  ---
GDB is affected, too:

https://github.com/msys2/MINGW-packages/pull/16968#issuecomment-1533702758

[Bug libgcc/109670] Exception handling broken for 32bit Windows starting with GCC 13

2023-05-06 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109670

LIU Hao  changed:

   What|Removed |Added

 CC||lh_mouse at 126 dot com

--- Comment #6 from LIU Hao  ---
Try reverting 1c118c9970600117700cc12284587e0238de6bbe?

[Bug target/53929] [meta-bug] -masm=intel with global symbol

2023-05-04 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53929

--- Comment #18 from LIU Hao  ---
Would it make any sense to have GAS be more permissive about such labels,

1. unconditionally? or
2. when input is from a pipe? or
3. when a special option is in effect e.g. `--output-from-gcc`?

[Bug target/53929] [meta-bug] -masm=intel with global symbol

2023-05-04 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53929

--- Comment #17 from LIU Hao  ---
Yeah. It looks to me like the Microsoft compiler doesn't actually uses the
assembler (like LLVM).

Given the C source:
```
extern int rax;
int main() { return rax; }
```

which compiled without errors:
```
> cl /O2 /c test.c /Fatest.asm
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30148 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

test.c
```

and produced this assembly file
```
include listing.inc

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC  main
EXTRN   rax:DWORD
_TEXT   SEGMENT
mainPROC; COMDAT
mov eax, DWORD PTR rax
ret 0
mainENDP
_TEXT   ENDS
END
```

which can't be assembled
```
> ml64 /c test.asm
Microsoft (R) Macro Assembler (x64) Version 14.29.30148.0
Copyright (C) Microsoft Corporation.  All rights reserved.

 Assembling: test.asm
test.asm(9) : error A2008:syntax error : rax
test.asm(16) : error A2032:invalid use of register
```

[Bug target/53929] [meta-bug] -masm=intel with global symbol

2023-05-04 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53929

--- Comment #15 from LIU Hao  ---
> Which as least MASM up to 12.x won't assemble. For one it complains about
> "rip" being undeclared. And then the load of "ecx" is _not_ a memory access
> (i.e. the "DWORD PTR" is ignored there). Which is in line with it also
> objecting to something like "extrn eax:dword".

This is accepted by ML64:

```
PUBLIC  main
EXTRN   rip:DWORD
_TEXT   SEGMENT
mainPROC
mov eax, DWORD PTR rip
ret 0
mainENDP
_TEXT   ENDS
END
```

Does it make sense to create kinda compatibility mode for ML, in addition to
MASM, if they are deemed to be incompatible? 


> I say this because I'd be happy to help this on the gas side, but only
> without breaking MASM compatibility. My present plan for gas is (as already
> outlined in #11) to make quoted identifiers unambiguously mean symbols, not
> registers. But of course that would still require a gcc side change as well.
> Unfortunately there continue to be inconsistencies in gas with quoted
> identifiers in general, and it's not entirely clear yet whether those may
> need addressing first.

That quoting thing will be yet another extension. I think we had better keep
extensions as few as possible.

[Bug target/53929] [meta-bug] -masm=intel with global symbol

2023-05-03 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53929

--- Comment #13 from LIU Hao  ---
dup notwithstanding, I think I had better copy my recommendation here for
reference:



This is how MSVC handles such names:
(https://gcc.godbolt.org/z/TonjYaxqj)

```
static int* volatile rip;
static unsigned int volatile eax;

int
get_value(void)
  {
return rip[eax];
  }
```

MSVC outputs:
```
get_value PROC  ; COMDAT
mov ecx, DWORD PTR eax
mov rax, QWORD PTR rip
mov eax, DWORD PTR [rax+rcx*4]
ret 0
get_value ENDP
```

GCC outputs:
```
get_value:
mov rdx, QWORD PTR rip[rip]
mov eax, DWORD PTR eax[rip]
mov eax, DWORD PTR [rdx+rax*4]
ret
```

In the case of MSVC, `DWORD PTR eax` is unambiguously parsed as the label `eax`
and `DWORD PTR [eax]` is unambiguously parsed as the register `eax`. The
address of all labels are always relative to RIP, but it is implied, and
brackets are not written explicitly.


Maybe GCC can follow MSVC to omit the RIP register and brackets. The x86_64
memory reference syntax matches x86 with the only change in semantics of the
immediate offset (for x86_64 it is relative to the next instruction, while for
i686 it is absolute), but the opcode is the same.

[Bug target/109726] New: use of variables whose name happen to match register names or keywords

2023-05-03 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109726

Bug ID: 109726
   Summary: use of variables whose name happen to match register
names or keywords
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

GAS PR: https://sourceware.org/bugzilla/show_bug.cgi?id=30418
Filed in both places, as we need changes both.


This is how MSVC handles such names:
(https://gcc.godbolt.org/z/TonjYaxqj)

```
static int* volatile rip;
static unsigned int volatile eax;

int
get_value(void)
  {
return rip[eax];
  }
```

MSVC outputs:
```
get_value PROC  ; COMDAT
mov ecx, DWORD PTR eax
mov rax, QWORD PTR rip
mov eax, DWORD PTR [rax+rcx*4]
ret 0
get_value ENDP
```

GCC outputs:
```
get_value:
mov rdx, QWORD PTR rip[rip]
mov eax, DWORD PTR eax[rip]
mov eax, DWORD PTR [rdx+rax*4]
ret
```

In the case of MSVC, `DWORD PTR eax` is unambiguously parsed as the label `eax`
and `DWORD PTR [eax]` is unambiguously parsed as the register `eax`. The
address of all labels are always relative to RIP, but it is implied, and
brackets are not written explicitly.


Maybe GCC can follow MSVC to omit the RIP register and brackets. The x86_64
memory reference syntax matches x86 with the only change in semantics of the
immediate offset (for x86_64 it is relative to the next instruction, while for
i686 it is absolute), but the opcode is the same.

[Bug target/105523] Wrong warning array subscript [0] is outside array bounds

2023-04-27 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523

--- Comment #31 from LIU Hao  ---
(In reply to Andrew Pinski from comment #24)
> The warning is there for the above case really (and similar ones with struct
> offsets). Where you originally have a null pointer and have an offset from
> there; by the time the warning happens, the IR does not know if it was
> originally from an offset of a null pointer or if the value was written in.

I understand that completely, but it does not justify the confusion. Something
like 'warning: array subscript 0 is outside array bounds of' says nothing about
null pointers, and is thus misleading. It is addition of a non-zero offset to a
null pointer that the warning really belongs to.

[Bug target/105523] Wrong warning array subscript [0] is outside array bounds

2023-04-25 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523

--- Comment #22 from LIU Hao  ---
Yes, GCC should be told to shut up about dereferencing artificial address
values.

[Bug c++/80883] Hardcoded null DSO handle parameter to __cxa_thread_atexit() on MinGW-w64 targets

2023-04-11 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80883

LIU Hao  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #1 from LIU Hao  ---
I'm closing this. It looks like if mingw-w64 CRT doesn't define `__dso_handle`
then a null pointer is passed, but with more recent versions it is defined, and
the argument is no longer a null pointer.

[Bug c++/109464] gcc does not instantiate constructor for explicitly instantiated template

2023-04-11 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109464

--- Comment #5 from LIU Hao  ---
Additional information:

I tried splitting the two class templates into two separate .cpp files, so the
explicit instantiation of `basic_shallow_string` should not be subject to
the instantiation of `basic_cow_string`. This made GCC emit the
constructor correctly (checked by examining assembly), but still failed to the
very same undefined reference.

At the moment, a temporary workaround is to mark the constructor of
`basic_shallow_string` as `always_inline`. This works for GCC 10, 11 and 12.
Haven't checked GCC 9 as it's no longer available from APT sources of my
current machine.

[Bug c++/109464] gcc does not instantiate constructor for explicitly instantiated template

2023-04-10 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109464

LIU Hao  changed:

   What|Removed |Added

  Known to fail||10.4.0, 9.5.0

--- Comment #4 from LIU Hao  ---
Manually reduced testcase:
(godbolt: https://gcc.godbolt.org/z/YsaoM78vM)

```
template
struct shallow
 {
   int len;
   constexpr shallow() : len(0) { }
  };

template
struct use_shallow
  {
   static constexpr shallow s_zstr = { };
   static_assert(s_zstr.len == 0);
  };

extern template struct shallow;
extern template struct use_shallow;

template struct shallow;
template struct use_shallow;
```

Constructor of `shallow` is lost. All GCC versions are affected.

[Bug c++/109464] gcc does not instantiate constructor for explicitly instantiated template

2023-04-10 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109464

--- Comment #2 from LIU Hao  ---
shouldn't this be classified as wrong code?

[Bug c++/109464] New: gcc does not instantiate constructor for explicitly instantiated template

2023-04-10 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109464

Bug ID: 109464
   Summary: gcc does not instantiate constructor for explicitly
instantiated template
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

Created attachment 54824
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54824=edit
unreduced testcase

Attached is a preprocessed file. I don't know how to reduce it for absence of a
function.


```
template
class basic_shallow_string
  {
static_assert(!is_array::value, "invalid character type");
static_assert(is_trivial::value, "characters must be trivial");
template friend class basic_cow_string;

  private:
const charT* m_ptr;
size_t m_len;

  public:
explicit constexpr
basic_shallow_string(const charT* ptr) noexcept
  : m_ptr(ptr), m_len(noadl::xstrlen(ptr))
  { }

  public:
constexpr
const charT*
c_str() const noexcept
  { return this->m_ptr;  }

constexpr
size_t
length() const noexcept
  { return this->m_len;  }

(... more member functions follow ...)
  };

extern template class basic_shallow_string;
```

And in 'cow_string.cpp' I have 

```
#include "cow_string.hpp"
namespace rocket {

template class basic_shallow_string;

(... more explicit instantiations follow ...)
}  // namespace rocket
```

This explicit instantiation instantiates all inline member functions above, but
not the constructor. I have examined assembly output, and there is no
constructor. Unless optimization is enabled, this causes undefined references:

```
/usr/bin/ld: asteria/repl/bin_asteria-commands.o: in function
`rocket::basic_shallow_string rocket::sref(char const*)':
/home/lh_mouse/GitHub/asteria/asteria/repl/../../rocket/cow_string.hpp:97:
undefined reference to
`rocket::basic_shallow_string::basic_shallow_string(char const*)'
collect2: error: ld returned 1 exit status
```

This happens only with the constructor.

[Bug target/82028] Windows x86_64 should not pass float aggregates in xmm

2023-04-06 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82028

--- Comment #7 from LIU Hao  ---
clang generates 14 bytes:

```
mov rax, 0x7FFF   # 48 B8 FF FF FF FF FF FF FF 7F
and rax, rcx  # 48 23 C1
ret   # C3
``

but in principle this function requires only 8 bytes:

```
lea rax, qword ptr [rcx + rcx]# 48 8D 04 09
shr rax, 1# 48 D1 E8
ret   # C3
``

[Bug target/82028] Windows x86_64 should not pass float aggregates in xmm

2023-04-06 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82028

--- Comment #6 from LIU Hao  ---
Looks like this has been fixed?  https://gcc.godbolt.org/z/xP5E76aYz

Despite that however, GCC generates suboptimal code that uses an XMM register
to perform the bitwise AND operation.

[Bug target/109380] inline member function symbol not exported with explicit template instantiation declaration on MinGW

2023-04-03 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109380

LIU Hao  changed:

   What|Removed |Added

 CC||lh_mouse at 126 dot com

--- Comment #4 from LIU Hao  ---
Looks like GCC doesn't generate `-export:` after `.section .drectve`. The
functions are generated in `.linkonce` sections correctly; they are just not
exported.

[Bug target/109257] `-masm=intel` generates weird syntax for indirect jumps

2023-03-23 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109257

--- Comment #5 from LIU Hao  ---
(In reply to jbeulich from comment #4)
> Being as compatible as possible with MASM has been the primary goal of
> supporting Intel syntax. Intel's SDM doesn't specify complete assembly
> language; it serves as a reference where possible/sensible.

GAS may accept it at any cost but GCC should not generate it. This is an issue
about GCC, not GAS.

[Bug target/109257] `-masm=intel` generates weird syntax for indirect jumps

2023-03-23 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109257

--- Comment #3 from LIU Hao  ---
(In reply to jbeulich from comment #2)
> Sure, but there's no reason for gas to not accept what MASM would. You also
> don't really make clear why you think this is an issue, and hence why it
> should be changed in gcc.

Why not? The syntax is invalid because Intel software developer manual has no
reference to such construction. The fact that MASM would accept it doesn't
render it valid.


> > The `foo[rip]` part is also invalid but it's a common issue for all
> > addressing operands for x86_64, not specifically about jmp.
> 
> Why's that invalid? foo[eax] and [foo+eax] have always been equivalent in
> MASM, and I see no reason why this shouldn't hold for rip-relative
> addressing as well.

Ok that's fine, just not intuitive. I wouldn't argue on this.

[Bug target/109257] New: `-masm=intel` generates weird syntax for indirect jumps

2023-03-22 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109257

Bug ID: 109257
   Summary: `-masm=intel` generates weird syntax for indirect
jumps
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

https://gcc.godbolt.org/z/Tc8v5qfv1

a proper tail call:

```
extern int (*foo)(int, int);
int ptc_to_foo(int a, int b) { return foo(a, b);  }
```

GCC compiles it to this:

```
ptc_to_foo:
jmp [QWORD PTR foo[rip]]
```

The outer pair of brackets are superfluous.


The `foo[rip]` part is also invalid but it's a common issue for all addressing
operands for x86_64, not specifically about jmp.

[Bug driver/108865] gcc on Windows fails with Unicode path to source file

2023-03-22 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108865

--- Comment #26 from LIU Hao  ---
(In reply to Costas Argyris from comment #23)
> Created attachment 54730 [details]
> Make symbol optional
> 
> Could you please try this patch?

Works for me. I have checked that cpp.exe, cc1.exe, cc1plus.exe all contain the
desired UTF-8 manifest in their resources.

[Bug driver/108865] gcc on Windows fails with Unicode path to source file

2023-03-22 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108865

--- Comment #24 from LIU Hao  ---
(In reply to Costas Argyris from comment #23)
> Created attachment 54730 [details]
> Make symbol optional
> 
> Could you please try this patch?

Didn't test this completely, but it did allow the build to continue. The error
was caused by the fact that `sym-mingw32.o` was not built.

Also the variable in `sym-mingw32.cc` had better have `extern "C"`.

[Bug driver/108865] gcc on Windows fails with Unicode path to source file

2023-03-22 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108865

LIU Hao  changed:

   What|Removed |Added

 CC||lh_mouse at 126 dot com

--- Comment #22 from LIU Hao  ---
This causes x86_64-w64-mingw32 to fail:


```
C:/MSYS2/mingw64/lib/gcc/x86_64-w64-mingw32/13.0.1/../../../../x86_64-w64-mingw32/bin/ld.exe:
required symbol `HOST_EXTRA_OBJS_SYMBOL' not defined
collect2.exe: error: ld returned 1 exit status
```

[Bug middle-end/108847] New: unnecessary bitwise AND on boolean types

2023-02-20 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108847

Bug ID: 108847
   Summary: unnecessary bitwise AND on boolean types
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: middle-end
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

Godbolt: https://gcc.godbolt.org/z/fsavMzMo7

```
void
set_bool(bool& fl, __UINT32_TYPE__ value)
  {
fl |= value >> 31;
  }
```

This code shifts a `uint32` to the right by 31 bits, so the result will only be
0 or 1.

Clang outputs:

```
set_bool(bool&, unsigned int): # @set_bool(bool&,
unsigned int)
shr esi, 31
or  byte ptr [rdi], sil
ret
```

but GCC emits an additional unnecessary bitwise AND operation on the
destination operand:

```
set_bool(bool&, unsigned int):
shr esi, 31
or  BYTE PTR [rdi], sil
and BYTE PTR [rdi], 1
ret
```

[Bug testsuite/108675] FAIL: gcc.c-torture/execute/builtins/*printf.c when stdio.h includes definitions

2023-02-06 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108675

--- Comment #7 from LIU Hao  ---
(In reply to nightstrike from comment #5)
> (In reply to LIU Hao from comment #4)
> > Does it make any sense to remove `#include ` from
> > 'gcc.c-torture/execute/builtins/lib/fprintf.c' ?
> 
> That will prevent the FILE type from existing, so the replacement functions
> won't compile.

That file never uses any fields of `FILE` directly. `FILE*` is always passed as
a pointer to `vfprintf()`, so it is perfectly valid to declare

   typedef struct _iobuf FILE;

or even 

   int fprintf (void* fp, const char* fmt, ...);

[Bug testsuite/108675] FAIL: gcc.c-torture/execute/builtins/*printf.c when stdio.h includes definitions

2023-02-06 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108675

--- Comment #4 from LIU Hao  ---
Does it make any sense to remove `#include ` from
'gcc.c-torture/execute/builtins/lib/fprintf.c' ?

[Bug target/108673] New: ICE with -fstack-clash-protection and noreturn attribute on x86_64-w64-mingw32

2023-02-04 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108673

Bug ID: 108673
   Summary: ICE with -fstack-clash-protection and noreturn
attribute on x86_64-w64-mingw32
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

Original reported by Théo Cavignac here:
https://sourceforge.net/p/mingw-w64/mailman/message/37773946/

The ICE is only reproducible on x86_64-w64-mingw32, not on i686-w64-mingw32.
Original testcase follows:

```
/*
   /usr/bin/x86_64-w64-mingw32-gcc \
 -O2 -fstack-clash-protection -c \
 -freport-bug \
 -o f.o f.c
  */
void exit(int) __attribute__((noreturn));

void foo(int p) {
   exit(p);
}
```

```
# gcc -O2 -fstack-clash-protection f.c
during RTL pass: final
f.c: In function 'foo':
f.c:11:4: internal compiler error: in seh_emit_stackalloc, at
config/i386/winnt.cc:1055
   11 |}
  |^
libbacktrace could not find executable to open
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
See  for instructions.
```

[Bug tree-optimization/108341] argument to `__builtin_ctz` should be assumed non-zero when CTZ_DEFINED_VALUE_AT_ZERO says it is undefined

2023-01-10 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108341

--- Comment #7 from LIU Hao  ---
(In reply to Jakub Jelinek from comment #4)
> I think 0 argument for __builtin_c[lt]z{,l,ll,imax} is always undefined, 0
> argument
> to .C[LT]Z (internal calls) is undefined if C[LT]Z_DEFINED_VALUE_AT_ZERO is
> not 2 and
> 0 argument to C[LT]Z RTL is undefined if C[LT]Z_DEFINED_VALUE_AT_ZERO is not
> non-zero.

I agree with this.


#94801 mentioned the `if(value == 0) __builtin_unreachable();` trick, but it
isn't an option if the argument is really possibly a zero:

(https://gcc.godbolt.org/z/dePvcMhTr)
```
#include 

uint32_t
my_tzcnt(uint32_t value)
  {
return (value == 0) ? 32 : __builtin_ctz(value);
  }
```

This can be TZCNT if the CPU supports it.

[Bug tree-optimization/108341] New: argument to `__builtin_ctz` should be assumed non-zero

2023-01-09 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108341

Bug ID: 108341
   Summary: argument to `__builtin_ctz` should be assumed non-zero
   Product: gcc
   Version: 12.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

Godbolt: https://gcc.godbolt.org/z/PrPP4v9z1


```
extern int r;

int
bz(int value)
  {
r = __builtin_ctz(value);
return value != 0;  // always true
  }
```


According to GCC manual, if the argument to `__builtin_ctz()` is zero then the
behavior is undefined, but GCC fails to assume that this function always
returns `1`. 

But I have read https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94801, not sure
whether it's related.

[Bug middle-end/108300] `abort()` macro cause bootstrap failure on *-w64-mingw32

2023-01-07 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108300

--- Comment #10 from LIU Hao  ---
(In reply to Arsen Arsenović from comment #9)
> (In reply to LIU Hao from comment #8)
> > The commit above just lets GCC bootstrap on Windows. The cause of this issue
> > is still there.
> > 
> > Maybe it's possible to replace all direct calls to `abort()` in gcc and
> > libcpp with `fancy_abort (__FILE__, __LINE__, __FUNCTION__)`, and eventually
> > get rid of that macro.
> 
> See Jonathans comment above.  I'll do that refactor this week, likely.

I think Jonathan's proposal makes it unnecessarily complex. Renaming `abort` to
`gcc_fancy_abort`, as well as all invocations accordingly, should be much
simpler than those inline functions and `__builtin_*` stuff.

[Bug middle-end/108300] `abort()` macro cause bootstrap failure on *-w64-mingw32

2023-01-07 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108300

--- Comment #8 from LIU Hao  ---
The commit above just lets GCC bootstrap on Windows. The cause of this issue is
still there.

Maybe it's possible to replace all direct calls to `abort()` in gcc and libcpp
with `fancy_abort (__FILE__, __LINE__, __FUNCTION__)`, and eventually get rid
of that macro.

[Bug middle-end/108300] `abort()` macro cause bootstrap failure on *-w64-mingw32

2023-01-06 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108300

--- Comment #5 from LIU Hao  ---
A quick and obvious fix is to add `CPPFLAGS='-DWIN32_LEAN_AND_MEAN'` when
configuring. Bootstrapped successfully on {i686,x86_64}-w64-mingw32.

I still think GCC source files should be patched.

[Bug bootstrap/108300] `abort()` macro cause bootstrap failure on *-w64-mingw32

2023-01-05 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108300

--- Comment #2 from LIU Hao  ---
(In reply to Jonathan Wakely from comment #1)
> (In reply to LIU Hao from comment #0)
> >   791 | #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
> 
> The C++ standard says this is undefined.
> 
> We should do something like:
> 

I was almost going to submit a patch for mingw-w64 headers. If you think this
can be fixed for GCC 13, that's very kind of you, and please consider
backporting.

[Bug bootstrap/108300] New: `abort()` macro cause bootstrap failure on *-w64-mingw32

2023-01-05 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108300

Bug ID: 108300
   Summary: `abort()` macro cause bootstrap failure on
*-w64-mingw32
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: bootstrap
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

Recently, mingw-w64 has got updated  from Wine. GCC then ceases to
build:

```
../../gcc/gcc/system.h:791:30: error: expected identifier before string
constant
  791 | #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
  |  ^~~~
```

The reason is elaborated in this piece of log of #gcc on OFTC:

```
[16:51:28]  on Windows hosts,  now involves ,
which brings a struct that has `abort()` as a member function, so if the macro
above is expanded there it will become nonsense.
[16:52:34]  if GCC does not use that struct (and a plenty more) the
standard way to prevent them from being included is to define
`WIN32_LEAN_AND_MEAN` before inclusion of .  unfortunately, not all
GCC source files do so.
[16:53:31]  there are about thirty to forty files that include
 without defining `WIN32_LEAN_AND_MEAN`.  do you think it is a good
idea to patch them all?
[16:54:11]  this can be generated by an sed command, but it's gonna
be a large patch, touching files that I am not familiar with.
[16:55:03]  or, we can patch mingw-w64 msxml.h to `#undef abort`.
[16:57:22]  can you fixincludes windows.h to add a wrapperr that defines
WIN32_LEAN_AND_MEAN and then include_next windows.h?
[16:58:11]  (that means you do not have to patch the original file ..
you could also use fixincludes to do that too - but it seems maybe more
complicated than the wrapper)
[17:06:14]  .. of course, that does not help if the files are sources
that need to be built by the bootstrap compiler - it’s only going to succeed if
they are all target-libs related.
[17:23:52]  .. hmm but if they are sources in the gcc tree, I’d suppose
that windows.h should not be included directly - but via system.h where you
could place the #define before the inclusion.
[17:34:14]  ugh, the wonders of macros
[17:34:25]  maybe that can be a static inline fn instead?
[17:34:41]  (or even just regular ol inline)
[18:08:19]  yeah, GCC should not #define abort like that, it's
disgusting
[18:08:40]  "but we've always done it like that" - time to stop
```

I create this PR for the record. In my opinion, including  without
`WIN32_LEAN_AND_MEAN` pulls in tons of unnecessary stuff and is almost never
desired. This can be fixed by

```
sed -Ei 's,^( *)#( *)include ,\1#\2define WIN32_LEAN_AND_MEAN
1\n&,'  \
  $(grep --inc "*.[hc]" --inc "*.cc" -Flr "")
```

(Some source files already have it.)

[Bug c++/108203] Format string checking with __USE_MINGW_ANSI_STDIO

2022-12-23 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108203

--- Comment #2 from LIU Hao  ---
(In reply to nightstrike from comment #0)
> Bug report that came from it:
> https://sourceforge.net/p/mingw-w64/bugs/292/
> 

I think this should be no longer the case. Two years ago I submitted a patch
that made the `ms_printf` attribute accept `%lld`, so there is now a universal
modifier for `long long`.

The issue here looks like that `printf` , which is a 'well known' function to
GCC, has a pre-defined attribute. If a new `*_printf` attribute is declared, it
gets both, as pointed out by Andrew Pinski.

[Bug c++/108059] internal compiler error: in tsubst_copy, at cp/pt.c:16425

2022-12-11 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108059

--- Comment #2 from LIU Hao  ---
Reconfirmed with all the following versions:

* g++-10 (Ubuntu 10.4.0-4ubuntu1~22.04) 10.4.0
* g++-11 (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
* g++-12 (Ubuntu 12.2.0-3ubuntu1~22.04) 12.2.0

[Bug c++/108059] internal compiler error: in tsubst_copy, at cp/pt.c:16425

2022-12-11 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108059

LIU Hao  changed:

   What|Removed |Added

  Known to fail||10.3.0, 11.1.0
 Target||x86_64-linux-gnu
   Host||x86_64-linux-gnu

--- Comment #1 from LIU Hao  ---
Reduced testcase, also ICEs with GCC 10.3.0 and 11.1.0, but 9.4.0 is fine:

```
template  using a = int;
template  auto b() {
  [](auto... c) { [](a...) {}; };
}
template  using e = decltype(b);
e<1> f;

```


```
$ g++-10 -std=c++17 test.cc
test.cc: In instantiation of ‘auto b() [with int  = 1]’:
test.cc:5:24:   required by substitution of ‘template using e = decltype
(b) [with int d = 1]’
test.cc:6:4:   required from here
test.cc:3:19: internal compiler error: in tsubst_copy, at cp/pt.c:16425
3 |   [](auto... c) { [](a...) {}; };
  |   ^~
0x7f76079c809a __libc_start_main
../csu/libc-start.c:308
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See  for instructions.

```

[Bug c++/108059] New: internal compiler error: in tsubst_copy, at cp/pt.c:16425

2022-12-11 Thread lh_mouse at 126 dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108059

Bug ID: 108059
   Summary: internal compiler error: in tsubst_copy, at
cp/pt.c:16425
   Product: gcc
   Version: 10.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

This was reported on IRC by Vladimir_Kozelko:


https://godbolt.org/z/oMjTc1813

```
#include 

struct unused {
template 
constexpr unused(T&&) noexcept {}
};

template 
using ignore_index_t = unused;

template 
constexpr inline auto pack_element(Tp&&... arr) noexcept {
auto unpack = [&](auto... v){
auto impl = [](ignore_index_t..., auto&& out, auto&&) {
return out;
};
};
}

template 
using pack_element_t = decltype(pack_element(std::declval()...));

void f1() { using H = pack_element_t<1, int, int&>; }

//idea (and it works):

auto test = [](auto v){
constexpr auto vv = v;
};

void f2() { test(std::integral_constant()); }
```

which ICEs:

```
: In instantiation of 'constexpr auto pack_element(Tp&& ...) [with int
index = 1; Tp = {int, int&}]':
:21:52:   required by substitution of 'template using pack_element_t = decltype (pack_element((declval)()...))
[with int index = 1; Tp = {int, int&}]'
:23:50:   required from here
:14:21: internal compiler error: in tsubst_copy, at cp/pt.cc:16949
   14 | auto impl = [](ignore_index_t..., auto&& out, auto&&) {
  | ^~
   15 | return out;
  | ~~~
   16 | };
  | ~
0x1bb069e internal_error(char const*, ...)
???:0
0x6ff396 fancy_abort(char const*, int, char const*)
???:0
0x88d46f tsubst_template_args(tree_node*, tree_node*, int, tree_node*)
???:0
0x87aa08 tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0x87a50a tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0x887353 tsubst_pack_expansion(tree_node*, tree_node*, int, tree_node*)
???:0
0x87a817 tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0x89084a tsubst_lambda_expr(tree_node*, tree_node*, int, tree_node*)
???:0
0x890a58 tsubst_lambda_expr(tree_node*, tree_node*, int, tree_node*)
???:0
0x87d4f7 instantiate_decl(tree_node*, bool, bool)
???:0
0x7a1e03 maybe_instantiate_decl(tree_node*)
???:0
0x72588e build_new_function_call(tree_node*, vec**, int)
???:0
0x8aaf0c finish_call_expr(tree_node*, vec**, bool,
bool, int)
???:0
0x87abbd tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0x87b097 tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0x891f4a instantiate_template(tree_node*, tree_node*, int)
???:0
0x87a682 tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0x88495f lookup_template_class(tree_node*, tree_node*, tree_node*, tree_node*,
int, int)
???:0
0x8aa461 finish_template_type(tree_node*, tree_node*, int)
???:0
0x861eaa c_parse_file()
???:0
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.
Compiler returned: 1
```

  1   2   >