[Bug c/105343] New: Inefficient initialisation in some kinds of structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105343 Bug ID: 105343 Summary: Inefficient initialisation in some kinds of structs Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: david at westcontrol dot com Target Milestone: --- struct S { int a[1000]; }; struct X { struct S s; int b[2];}; extern int foobar(struct X * p); int foo(struct S *s) { struct X x = { *s }; return foobar(&x); } When the size of the array "a" is small enough that the compiler does the initialisation inline, the code is fine. With a bigger array it uses memset and memcpy, either as calls to external functions or inline loops depending on details of the version of gcc and the target. (This too is appropriate.) However, it does that by turning the code into the equivalent of : memset(&x, 0, sizeof(struct X)); memcpy(&x, s, sizeof(struct S)); It /should/ be doing : memset(&x.b, 0, sizeof(struct X.b)); memcpy(&x, s, sizeof(struct S)); In other words, it is first zeroing out the entire X structure, then copying from *s into the structure. Only the extra part of X, the array "b", needs to be zero'ed.
[Bug c/105343] Inefficient initialisation in some kinds of structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105343 Andrew Pinski changed: What|Removed |Added Severity|normal |enhancement --- Comment #1 from Andrew Pinski --- There might be a dup or a related bug to this one already. I remember seeing it.
[Bug middle-end/105342] [Extended Asm]Memory barrier geater than a function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105342 --- Comment #5 from rguenther at suse dot de --- On Fri, 22 Apr 2022, 570070308 at qq dot com wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105342 > > --- Comment #4 from 。 <570070308 at qq dot com> --- > (In reply to Richard Biener from comment #1) > > Is it really important though? > > The doc says that "The asm statement allows you to include assembly > instructions directly within C code. This may help you to maximize performance > in time-sensitive code or to access assembly instructions that are not readily > available to C programs.", and I use extended-asm rather than writing a whole > function with assembly just for maximize performance. > > I try my best for not using "memory" clobber, but in some cases I have to use > it, for example, using the asm to operate a list structure like the `struct > list_head` in Linux. It is impossible to list all the list elements in the > Input/OutputOperands. Indeed. I think there's duplicate bugreports on the lack of a clobber specifying "memory reachable by pointer X", the clobber syntax is somewhat limited here.
[Bug target/105325] power10: Error: operand out of range
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105325 --- Comment #10 from Kewen Lin --- (In reply to Jakub Jelinek from comment #9) > where it no longer satisfies the predicate but does satisfy the constraint. > It is unclear if there is any matching constraint for ds_form_mem_operand, > maybe wY? But not really sure about it. As the comments above wY, it's mainly for those VSX instructions and also checks no update, seems not perfect to be used here? The current ds_form_mem_operand predicate looks also contradicted with the below split condition address_is_non_pfx_d_or_x (XEXP (operands[1], 0), SImode, NON_PREFIXED_DS)). ds_form_mem_operand requires address_to_insn_form should always return INSN_FORM_DS, while address_is_non_pfx_d_or_x calls address_to_insn_form, it will never have the chance to return false since the address_to_insn_form will only return INSN_FORM_DS as predicate guards. The below snippet makes the split work and the failure gone. diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index b1fcc69bb60..a1b58dfa0c9 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1099,7 +1099,11 @@ (define_predicate "ds_form_mem_operand" rtx addr = XEXP (op, 0); - return address_to_insn_form (addr, mode, NON_PREFIXED_DS) == INSN_FORM_DS; + enum insn_form form = address_to_insn_form (addr, mode, NON_PREFIXED_DS); + + return form == INSN_FORM_DS + || (reload_completed && form == INSN_FORM_PREFIXED_NUMERIC); + }) ;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. But as Jakub noted, I'm not sure reload can ensure to make the address satisfy this updated predicate under the unmatched constraint "m".
[Bug c++/88165] error: default member initializer for 'A::B::m' required before the end of its enclosing class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165 JC Liang changed: What|Removed |Added CC||jcl at nvidia dot com --- Comment #8 from JC Liang --- Also suffering from this issue, it's really annoying and diverged from msvc...
[Bug c++/88165] error: default member initializer for 'A::B::m' required before the end of its enclosing class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165 Jonathan Wakely changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |DUPLICATE --- Comment #9 from Jonathan Wakely --- This is PR 96645 and the examples on comment 1 and comment 7 compile with GCC trunk. The example in comment 0 doesn't compile still, see PR 96645 for details. *** This bug has been marked as a duplicate of bug 96645 ***
[Bug c++/96645] [9/10/11/12 Regression] [CWG2335] std::variant default constructor and unparsed DMI
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96645 Jonathan Wakely changed: What|Removed |Added CC||leanid.chaika at gmail dot com --- Comment #27 from Jonathan Wakely --- *** Bug 88165 has been marked as a duplicate of this bug. ***
[Bug c++/58616] [meta-bug] nsdmi
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58616 Bug 58616 depends on bug 88165, which changed state. Bug 88165 Summary: error: default member initializer for 'A::B::m' required before the end of its enclosing class https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165 What|Removed |Added Status|NEW |RESOLVED Resolution|--- |DUPLICATE
[Bug c++/88165] error: default member initializer for 'A::B::m' required before the end of its enclosing class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165 --- Comment #10 from Jonathan Wakely --- (In reply to Fedor Chelnokov from comment #7) > This struct definition: > ``` > struct A { > struct B { > int i = 0; > B() {} This declares default constructor, meaning that the type is default constructible. Period. By declaring B(); you assert that B is default constructible. > }; > A(B = {}); This is valid, because the user-provided default constructor for B is all the compiler needs to see to know that B={} is valid. > }; > ``` > is accepted by GCC, but another one ({} replaced with = default) is not: > ``` > struct C { > struct D { > int i = 0; > D() = default; This declares a default constructor that might be defined implicitly by the compiler, **or** it might get deleted if the member definitions of D would make the implicit default constructor ill-formed. This is obviously very different from the case where you declare B(); There is no assertion that D is default constructible, the compiler has to deduce whether or not that's true. That depends on the default member initializer for D::i. The initializer (which is just '0' here) is a "complete class context" which means it is not processed until the class D is complete (this allows you to use other members, or e.g. sizeof(D) as the initializer). A nested class like C::D is not complete until its enclosing class is complete. This means the initializer for C::D::i is compiled after C is complete. This means whether C::D is default constructible is not known until C is complete. > }; > C(D = {}); This requires checking whether C::D is default constructible, but we are still in the body of C, so C is not complete, which means C::D is not complete, which means we don't know if C::D is default constructible. > }; > ``` > Demo: https://gcc.godbolt.org/z/WTPdTn1Yf > > Could you please explain why? I though that both must be same accepted or > same rejected. I hope the explanation above helps. GCC trunk now has a tweak to parse simple initializers like 0 immediately, instead of waiting for the class to be complete (because 0 doesn't depend on anything in the class). But for the original example in comment 0 the initializer std::numeric_limits::max(); has to perform name lookup and overload resolution, and so is still delayed until the class is complete.
[Bug middle-end/105343] Inefficient initialisation in some kinds of structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105343 Richard Biener changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2022-04-22 Ever confirmed|0 |1 Version|unknown |12.0 Component|c |middle-end --- Comment #2 from Richard Biener --- Hmm, on x86-64 I see : x = {}; x.s = *s_3(D); _6 = foobar (&x); so I suppose this is DSE mem* trimming not working for the x = {}; variant. There might be already a bug with respect to that. Indeed gimplification could be smarter and handle the contiguous zeros case better. I also wonder why it chooses to do the zero pre-init for just two ints, maybe it gives up for arrays.
[Bug middle-end/105343] Inefficient initialisation in some kinds of structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105343 --- Comment #3 from Richard Biener --- categorize_ctor_elements computes (gdb) p num_nonzero_elements $3 = 1000 (gdb) p num_unique_nonzero_elements $4 = 1000 (gdb) p num_ctor_elements $5 = 1000 (gdb) p complete_p $6 = false so it fails to compute the required CTOR elements (num_ctor_elements lacks the missing parts), falling into else if (!complete_p) /* If the constructor isn't complete, clear the whole object beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it. ??? This ought not to be needed. For any element not present in the initializer, we should simply set them to zero. Except we'd need to *find* the elements that are not present, and that requires trickery to avoid quadratic compile-time behavior in large cases or excessive memory use in small cases. */ cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
[Bug c++/88165] error: default member initializer for 'A::B::m' required before the end of its enclosing class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165 --- Comment #11 from Fedor Chelnokov --- Thanks a lot for the explanation!
[Bug middle-end/82739] [9/10 Regression] Sort is 30% slower compared to gcc44 on presorted array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82739 Jonathan Wakely changed: What|Removed |Added Component|libstdc++ |middle-end --- Comment #9 from Jonathan Wakely --- Changing component to middle-end, since neither the regression nor the fix was a change to libstdc++ code.
[Bug fortran/93256] Assumed-shape unlimited polymorphic variable passes values incorrectly
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93256 Thomas Koenig changed: What|Removed |Added Status|WAITING |NEW Keywords||needs-bisection, wrong-code --- Comment #3 from Thomas Koenig --- Also works with gcc-Version 11.2.1 20220108 (GCC), so definitely fixed. Anybody up for bisecting this?
[Bug c++/88165] error: default member initializer for 'A::B::m' required before the end of its enclosing class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165 --- Comment #12 from JC Liang --- (In reply to Jonathan Wakely from comment #10) > (In reply to Fedor Chelnokov from comment #7) > > This struct definition: > > ``` > > struct A { > > struct B { > > int i = 0; > > B() {} > > This declares default constructor, meaning that the type is default > constructible. Period. > > By declaring B(); you assert that B is default constructible. > > > }; > > A(B = {}); > > This is valid, because the user-provided default constructor for B is all > the compiler needs to see to know that B={} is valid. > > > }; > > ``` > > is accepted by GCC, but another one ({} replaced with = default) is not: > > ``` > > struct C { > > struct D { > > int i = 0; > > D() = default; > > This declares a default constructor that might be defined implicitly by the > compiler, **or** it might get deleted if the member definitions of D would > make the implicit default constructor ill-formed. This is obviously very > different from the case where you declare B(); There is no assertion that D > is default constructible, the compiler has to deduce whether or not that's > true. That depends on the default member initializer for D::i. The > initializer (which is just '0' here) is a "complete class context" which > means it is not processed until the class D is complete (this allows you to > use other members, or e.g. sizeof(D) as the initializer). > > A nested class like C::D is not complete until its enclosing class is > complete. This means the initializer for C::D::i is compiled after C is > complete. This means whether C::D is default constructible is not known > until C is complete. > > > > }; > > C(D = {}); > > This requires checking whether C::D is default constructible, but we are > still in the body of C, so C is not complete, which means C::D is not > complete, which means we don't know if C::D is default constructible. > > > }; > > ``` > > Demo: https://gcc.godbolt.org/z/WTPdTn1Yf > > > > Could you please explain why? I though that both must be same accepted or > > same rejected. > > I hope the explanation above helps. > > GCC trunk now has a tweak to parse simple initializers like 0 immediately, > instead of waiting for the class to be complete (because 0 doesn't depend on > anything in the class). But for the original example in comment 0 the > initializer std::numeric_limits::max(); has to perform name lookup > and overload resolution, and so is still delayed until the class is complete. This is an excellent explanation, hope it benefits everyone who got here from Google search.
[Bug fortran/93256] Assumed-shape unlimited polymorphic variable passes values incorrectly
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93256 Jakub Jelinek changed: What|Removed |Added Keywords|needs-bisection | CC||jakub at gcc dot gnu.org --- Comment #4 from Jakub Jelinek --- r10-6924-g7485ace81de9ec9dd5c87edf67e359d31ce35a20
[Bug rtl-optimization/105338] [12 Regression] Regression: jump or cmove generated for pattern (x ? CST : 0)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105338 Jakub Jelinek changed: What|Removed |Added Keywords|needs-bisection | CC||jakub at gcc dot gnu.org --- Comment #1 from Jakub Jelinek --- Started with r12-7687-g3a7ba8fd0cda387809e4902328af2473662b6a4a All the *.optimized dump differences with that change look like: @@ -8,14 +8,14 @@ int f (int i) [local count: 1073741824]: if (i_2(D) != 0) -goto ; [35.00%] +goto ; [35.00%] else -goto ; [65.00%] +goto ; [65.00%] - [local count: 697932184]: + [local count: 375809640]: [local count: 1073741824]: - # iftmp.0_1 = PHI <5(2), i_2(D)(3)> + # iftmp.0_1 = PHI <5(3), i_2(D)(2)> return iftmp.0_1; } i.e. swapping whether true or false edge goes through the empty bb. Wonder why we emit different code based on that...
[Bug lto/94157] [10 Regression] error: lto-wrapper failed with -Wa,--noexecstack -Wa,--noexecstack since r10-6807-gf1a681a174cdfb82
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94157 jiawei changed: What|Removed |Added CC||jiawei at iscas dot ac.cn --- Comment #9 from jiawei --- I had run the regression on the RISC-V target, and get a ld warning: `requires executable stack (because the .note.GNU-stack section is executable)` Executing on host: /root/riscv-gnu-toolchain/build-gcc-newlib-stage2/gcc/xgcc -B/root/riscv-gnu-toolchain/build-gcc-newlib-stage2/gcc/ c_lto_pr94157_0.o -march=rv64imafdc -mabi=lp64d -mcmodel=medlow -fdiagnostics-plain-output -O0 -fipa-vrp -flto -Wa,--noexecstack -Wa,--noexecstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -o gcc-dg-lto-pr94157-01.exe(timeout = 600) spawn -ignore SIGHUP /root/riscv-gnu-toolchain/build-gcc-newlib-stage2/gcc/xgcc -B/root/riscv-gnu-toolchain/build-gcc-newlib-stage2/gcc/ c_lto_pr94157_0.o -march=rv64imafdc -mabi=lp64d -mcmodel=medlow -fdiagnostics-plain-output -O0 -fipa-vrp -flto -Wa,--noexecstack -Wa,--noexecstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -o gcc-dg-lto-pr94157-01.exe^M /opt/riscv/riscv64-unknown-elf/bin/ld: warning: /tmp/ccrEUuLH.ltrans0.ltrans.o: requires executable stack (because the .note.GNU-stack section is executable)^M FAIL: gcc.dg/lto/pr94157 c_lto_pr94157_0.o-c_lto_pr94157_0.o link, -O0 -fipa-vrp -flto -Wa,--noexecstack -Wa,--noexecstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack -Wa,--execstack Any suggestions?
[Bug target/105314] [12 Regression] ifcvt regression in noce_try_store_flag_mask
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105314 Andrew Pinski changed: What|Removed |Added Summary|ifcvt regression in |[12 Regression] ifcvt |noce_try_store_flag_mask|regression in ||noce_try_store_flag_mask Target Milestone|--- |12.0
[Bug rtl-optimization/105338] [12 Regression] Regression: jump or cmove generated for pattern (x ? CST : 0)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105338 --- Comment #2 from Andrew Pinski --- I think this is the same issue as PR 105314 really.
[Bug c++/105344] New: std::source_location::curent() seemingly treated as a pure function in template specializations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105344 Bug ID: 105344 Summary: std::source_location::curent() seemingly treated as a pure function in template specializations Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: jan at twosigma dot com Target Milestone: --- When using std::source_location::current().line() in certain contexts on two different lines, gcc seems to incorrectly think the expression refers to the same value. Testcase: #include #include template struct foo; // Two following two specializations are different, yet gcc errors out, // claiming they are the same. template struct foo> { static constexpr int num = i; }; template struct foo> { static constexpr int num = i; }; This outputs: :14:8: error: redefinition of 'struct foo::type>' 14 | struct foo> { | ^ :9:8: note: previous definition of 'struct foo::type>' 9 | struct foo> { | ^ Compiler returned: 1 https://godbolt.org/z/ozf1MbG3n shows this code works fine under MSVC.
[Bug c++/88165] error: default member initializer for 'A::B::m' required before the end of its enclosing class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165 --- Comment #13 from andysem at mail dot ru --- (In reply to Jonathan Wakely from comment #10) > (In reply to Fedor Chelnokov from comment #7) > > This struct definition: > > ``` > > struct A { > > struct B { > > int i = 0; > > B() {} > > This declares default constructor, meaning that the type is default > constructible. Period. > > By declaring B(); you assert that B is default constructible. > > > }; > > A(B = {}); > > This is valid, because the user-provided default constructor for B is all > the compiler needs to see to know that B={} is valid. > > > }; > > ``` > > is accepted by GCC, but another one ({} replaced with = default) is not: > > ``` > > struct C { > > struct D { > > int i = 0; > > D() = default; > > This declares a default constructor that might be defined implicitly by the > compiler, **or** it might get deleted if the member definitions of D would > make the implicit default constructor ill-formed. This is obviously very > different from the case where you declare B(); There is no assertion that D > is default constructible, the compiler has to deduce whether or not that's > true. That depends on the default member initializer for D::i. The > initializer (which is just '0' here) is a "complete class context" which > means it is not processed until the class D is complete (this allows you to > use other members, or e.g. sizeof(D) as the initializer). > > A nested class like C::D is not complete until its enclosing class is > complete. This means the initializer for C::D::i is compiled after C is > complete. This means whether C::D is default constructible is not known > until C is complete. > > > > }; > > C(D = {}); > > This requires checking whether C::D is default constructible, but we are > still in the body of C, so C is not complete, which means C::D is not > complete, which means we don't know if C::D is default constructible. Does it? I thought the default arguments were only evaluated at the point where they are actually used, i.e. in this case - when `C` constructor is invoked with no arguments. > > }; > > ``` > > Demo: https://gcc.godbolt.org/z/WTPdTn1Yf > > > > Could you please explain why? I though that both must be same accepted or > > same rejected. > > I hope the explanation above helps. Thank you for the explanation. If this is how the standard specifies compiler behavior, I wonder if this should be considered as a defect (DR). There is nothing in `std::numeric_limits::max()` that depends on the definition of `C`, so there is no reason to prevent it from compiling.
[Bug tree-optimization/105329] Bogus restrict warning when assigning 1-char string literal to std::string
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105329 Aldy Hernandez changed: What|Removed |Added CC||aldyh at gcc dot gnu.org --- Comment #4 from Aldy Hernandez --- (In reply to Andrew Macleod from comment #3) > p vr.dump(stderr) > const size_type [1, 9223372036854775807] > > I also have a breakpoint in set_range_info for this name which hasn't been > triggered. So either the set routine have been bypassed or perhaps > inlining is setting this global value? > > Im still trying to figure out who and where has decided that __nleft_49 is > [2, 0x7FFF] instead of [2, 0x] Global ranges can also be set via duplicate_ssa_name_range_info, which is used by the inliner. It looks like [1, 9223372036854775807] was originally calculated in evrp for __nleft_64: === BB 45 Imports: _27 __s_53(D) Exports: _27 _34 __s_53(D) __nleft_64 _34 : _27(I) __s_53(D)(I) __nleft_64 : _27(I) _34 __s_53(D)(I) _27 char * [1B, -2B] __s_53(D) const char * [0B, -3B] Relational : (__s_53(D) < _26) Relational : (_27 > __s_53(D)) : _34 = _27 - __s_53(D); __nleft_64 = (const size_type) _34; if (_34 == 1) goto ; [34.00%] else goto ; [66.00%] _34 : long int [1, +INF] __nleft_64 : long unsigned int [1, 9223372036854775807] 45->46 (T) _27 : char * [1B, -2B] 45->46 (T) _34 : long int [1, 1] 45->46 (T) __s_53(D) : const char * [0B, -3B] 45->46 (T) __nleft_64 :long unsigned int [1, 9223372036854775807] 45->47 (F) _27 : char * [1B, -2B] 45->47 (F) _34 : long int [2, +INF] 45->47 (F) __s_53(D) : const char * [0B, -3B] 45->47 (F) __nleft_64 :long unsigned int [1, 9223372036854775807] This was later renamed to __nleft_40, and then copied by the IPA inliner to __nleft_47 and ultimately to __nleft_49.
[Bug middle-end/105345] New: [OpenMP] Wrong iteration loop count when mixing signed and unsigned
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105345 Bug ID: 105345 Summary: [OpenMP] Wrong iteration loop count when mixing signed and unsigned Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: openmp, wrong-code Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: burnus at gcc dot gnu.org CC: frederik at gcc dot gnu.org, jakub at gcc dot gnu.org Target Milestone: --- The following program has a loop count of 0 without OpenMP (-fno-openmp) but is executed 1010 times with -fopenmp in GCC. The problem is that the following is not honored: "If var has a signed integer type and the var operand of test-expr after usual arithmetic conversions has an unsigned integer type then the loop iteration count is computed from lb, test-expr and incr using an unsigned integer type corresponding to the type of var." (OpenMP 5.2, 4.4.2 OpenMP Loop-Iteration Spaces and Vectors) (Likewise: OpenMP 5.1, 2.11.1 Canonical Loop Nest Form) The wording seems to be new since OpenMP 5.1 - and to ensure that the OpenMP and C loop counts are the same: int main () { #pragma omp for for (int i = -1000; i < 10u; ++i) { __builtin_printf("%d\n", i); __builtin_abort (); } }
[Bug c++/88165] error: default member initializer for 'A::B::m' required before the end of its enclosing class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165 --- Comment #14 from Jonathan Wakely --- (In reply to andysem from comment #13) > (In reply to Jonathan Wakely from comment #10) > > > C(D = {}); > > > > This requires checking whether C::D is default constructible, but we are > > still in the body of C, so C is not complete, which means C::D is not > > complete, which means we don't know if C::D is default constructible. > > Does it? I thought the default arguments were only evaluated at the point > where they are actually used, i.e. in this case - when `C` constructor is > invoked with no arguments. It's surprising, I agree. Whether the default argument is valid determines whether this constructor is considered a default constructor, which determines whether the compiler needs to implicitly declare a separate default constructor I think that's why the default argument is needed earlier than you expect. > If this is how the standard specifies compiler behavior, I wonder if this > should be considered as a defect (DR). I closed this as a dup of PR 96645 which has a DR number right there in the title. Like I said, see there for more details. > There is nothing in > `std::numeric_limits::max()` that depends on the definition of `C`, > so there is no reason to prevent it from compiling. Are you sure? What if C::std is declared? Then the initializer means something very different. Again, see PR 96645 for further discussion of when the initializer can be compiled (and a possible patch to do it differently).
[Bug rtl-optimization/105338] [12 Regression] Regression: jump or cmove generated for pattern (x ? CST : 0)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105338 --- Comment #3 from Jakub Jelinek --- So, if I change passes.def NEXT_PASS (pass_sink_code, true /* unsplit edges */); line NEXT_PASS (pass_sink_code, false /* unsplit edges */); I get back the 11.x code. Before ce1 pass, in that case say f looks like: 8: flags:CCZ=cmp(r83:SI,0) 9: pc={(flags:CCZ!=0)?L22:pc} REG_DEAD flags:CCZ REG_BR_PROB 375809644 10: NOTE_INSN_BASIC_BLOCK 3 5: r82:SI=0 REG_DEAD r83:SI ; pc falls through to BB 5 22: L22: 21: NOTE_INSN_BASIC_BLOCK 4 4: r82:SI=0x5 15: L15: 18: NOTE_INSN_BASIC_BLOCK 5 use (r82) i.e. essentially if (tmp83 != 0) tmp82 = 5; else tmp82 = 0; But with vanilla trunk, it is instead: 7: flags:CCZ=cmp(r83:SI,0) 8: pc={(flags:CCZ==0)?L10:pc} REG_DEAD flags:CCZ REG_BR_PROB 697932188 9: NOTE_INSN_BASIC_BLOCK 4 4: r83:SI=0x5 10: L10: 11: NOTE_INSN_BASIC_BLOCK 5 use (r83) i.e. if (tmp83 != 0) tmp83 = 5; Before fwprop1, the code looks roughly the same except for the swapped branches, so in C if (tmp83 != 0) tmp82 = 5; else tmp82 = tmp83; vs. if (tmp83 == 0) tmp82 = tmp83; else tmp82 = 5; I think fwprop1 only works on extended basic blocks and therefore turns the latter into if (tmp83 == 0) tmp82 = 0; else tmp82 = 5; and not the former.
[Bug rtl-optimization/105338] [12 Regression] Regression: jump or cmove generated for pattern (x ? CST : 0)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105338 Richard Biener changed: What|Removed |Added CC||rguenth at gcc dot gnu.org Ever confirmed|0 |1 Status|UNCONFIRMED |NEW Last reconfirmed||2022-04-22 --- Comment #4 from Richard Biener --- I think none is more canonical so I wonder if there's an easy way to have ifcvt recognize both? But yes, it's probably a duplicate, but at least for x86 and with complete testcases. Note one of the issues is that creating/removing forwarders can end up swapping things. To avoid this (for GCC 13) we can try to not as aggressively remove them (basically keep critical edges split) and maybe mark (temporarily) created forwarders with a flag so that CFG cleanup can pick the "correct" one when it is used as vehicle to remove them again (as in this case).
[Bug rtl-optimization/105338] [12 Regression] Regression: jump or cmove generated for pattern (x ? CST : 0)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105338 --- Comment #5 from Richard Biener --- (In reply to Jakub Jelinek from comment #3) > Before fwprop1, the code looks roughly the same except for the swapped > branches, > so in C > if (tmp83 != 0) > tmp82 = 5; > else > tmp82 = tmp83; > vs. > if (tmp83 == 0) > tmp82 = tmp83; > else > tmp82 = 5; Specifically for this we could also look to canonicalize this in uncprop which introduces the copies, making sure to rewrite this into an equality compare?
[Bug rtl-optimization/105338] [12 Regression] Regression: jump or cmove generated for pattern (x ? CST : 0)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105338 --- Comment #6 from Richard Biener --- (In reply to Richard Biener from comment #5) > (In reply to Jakub Jelinek from comment #3) > > Before fwprop1, the code looks roughly the same except for the swapped > > branches, > > so in C > > if (tmp83 != 0) > > tmp82 = 5; > > else > > tmp82 = tmp83; > > vs. > > if (tmp83 == 0) > > tmp82 = tmp83; > > else > > tmp82 = 5; > > Specifically for this we could also look to canonicalize this in > uncprop which introduces the copies, making sure to rewrite this into > an equality compare? When un-propagating into a PHI in uncprop_into_successor_phis mark the BB of the PHI node. In uncprop_dom_walker::before_dom_children, when it is marked, match a diamond/half-diamond with the immediate dominator and do the rewrite of the conditional and swapping of edge flags.
[Bug lto/94157] [10 Regression] error: lto-wrapper failed with -Wa,--noexecstack -Wa,--noexecstack since r10-6807-gf1a681a174cdfb82
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94157 --- Comment #10 from Martin Liška --- Seems you are using the latest binutils ld, right? It's the newly added warning which tells that usage of executable stack is a potential security issue: https://sourceware.org/pipermail/binutils/2022-April/120476.html
[Bug rtl-optimization/105333] [10/11/12 Regression] ICE: in simplify_subreg, at simplify-rtx.cc:7346 with -Og -fno-tree-coalesce-vars -fno-tree-fre since r10-1094-g9919f5fe87a3def1
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105333 --- Comment #4 from CVS Commits --- The master branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:7092b7aea122a91824d048aeb23834cf1d19b1a1 commit r12-8224-g7092b7aea122a91824d048aeb23834cf1d19b1a1 Author: Jakub Jelinek Date: Fri Apr 22 13:38:11 2022 +0200 rtlanal: Fix up replace_rtx [PR105333] The following testcase FAILs, because replace_rtx replaces a REG with CONST_WIDE_INT inside of a SUBREG, which is an invalid transformation because a SUBREG relies on SUBREG_REG having non-VOIDmode but CONST_WIDE_INT has VOIDmode. replace_rtx already has code to deal with it, but it was doing it only for CONST_INTs. The following patch does it also for VOIDmode CONST_DOUBLE or CONST_WIDE_INT. 2022-04-22 Jakub Jelinek PR rtl-optimization/105333 * rtlanal.cc (replace_rtx): Use simplify_subreg or simplify_unary_operation if CONST_SCALAR_INT_P rather than just CONST_INT_P. * gcc.dg/pr105333.c: New test.
[Bug rtl-optimization/105333] [10/11 Regression] ICE: in simplify_subreg, at simplify-rtx.cc:7346 with -Og -fno-tree-coalesce-vars -fno-tree-fre since r10-1094-g9919f5fe87a3def1
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105333 Jakub Jelinek changed: What|Removed |Added Summary|[10/11/12 Regression] ICE: |[10/11 Regression] ICE: in |in simplify_subreg, at |simplify_subreg, at |simplify-rtx.cc:7346 with |simplify-rtx.cc:7346 with |-Og -fno-tree-coalesce-vars |-Og -fno-tree-coalesce-vars |-fno-tree-fre since |-fno-tree-fre since |r10-1094-g9919f5fe87a3def1 |r10-1094-g9919f5fe87a3def1 --- Comment #5 from Jakub Jelinek --- Fixed on the trunk so far.
[Bug c++/104470] internal compiler error: Segmentation fault compiling std::variant with -std=c++20
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104470 Max changed: What|Removed |Added CC||max.kan...@nu-cost.com --- Comment #4 from Max --- Not sure whether it helps, but here is a version of the same ICE without the struct having a member, see https://godbolt.org/z/4xjbcToxj #include template struct A {}; template using Var = std::variant>; int main() { auto var = Var{}; } Here the compiler can clearly not deduce the type, so this is invalid code. Adding the type leads to valid code which is compiled as expected.
[Bug c/105346] New: -Wno-free-nonheap-object false positive (on Bison-generated grammar code)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105346 Bug ID: 105346 Summary: -Wno-free-nonheap-object false positive (on Bison-generated grammar code) Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: tim.vanholder at anubex dot com Target Milestone: --- Bison grammars (can) include code like /* The state stack: array, bottom, top. */ yy_state_t yyssa[YYINITDEPTH]; yy_state_t *yyss = yyssa; yy_state_t *yyssp = yyss; ... (code that may allocate a larger stack if needed, in which case `yyss` and `yyssp` get repointed) #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif (with YYSTACK_FREE() expanding to free()). For this gcc (Debian 11.2.0-19) 11.2.0 is reporting (with -Werror): Linux/DML-grammar.cc:13901:18: error: ‘void free(void*)’ called on unallocated object ‘yyssa’ [-Werror=free-nonheap-object] 13901 | YYSTACK_FREE (yyss); Linux/DML-grammar.cc:5609:16: note: declared here 5609 | yy_state_t yyssa[YYINITDEPTH]; |^ So it is tracing yyss to yyssa from its declaration, but is apparently not seeing that there is an explicit test that yyss is not equal to yyssa around the free. (I'd test with a more recent version, but this is what I have available.)
[Bug c/105346] -Wno-free-nonheap-object false positive (on Bison-generated grammar code)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105346 Richard Biener changed: What|Removed |Added Status|UNCONFIRMED |WAITING Ever confirmed|0 |1 Last reconfirmed||2022-04-22 --- Comment #1 from Richard Biener --- It doesn't diagnose a simple testcase like #include void bar (void *); void foo (int n) { int a[100]; int *p = a; if (n > 100) p = malloc (n*sizeof(int)); bar (p); if (p != a) free (p); } so maybe you can provide preprocessed source of the TU that diagnoses such a case in a more complicated setting?
[Bug rtl-optimization/105338] [12 Regression] Regression: jump or cmove generated for pattern (x ? CST : 0)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105338 --- Comment #7 from Jakub Jelinek --- --- gcc/config/i386/i386-expand.cc.jj 2022-04-13 15:42:39.0 +0200 +++ gcc/config/i386/i386-expand.cc 2022-04-22 14:18:27.347135185 +0200 @@ -3136,6 +3136,8 @@ ix86_expand_int_movcc (rtx operands[]) bool sign_bit_compare_p = false; rtx op0 = XEXP (operands[1], 0); rtx op1 = XEXP (operands[1], 1); + rtx op2 = operands[2]; + rtx op3 = operands[3]; if (GET_MODE (op0) == TImode || (GET_MODE (op0) == DImode @@ -3153,17 +3155,29 @@ ix86_expand_int_movcc (rtx operands[]) || (op1 == constm1_rtx && (code == GT || code == LE))) sign_bit_compare_p = true; + /* op0 == op1 ? op0 : op3 is equivalent to op0 == op1 ? op1 : op3, + but if op1 is a constant, the latter form allows more optimizations, + either through the last 2 ops being constant handling, or the one + constant and one variable cases. On the other side, for cmov the + former might be better as we don't need to load the constant into + another register. */ + if (code == EQ && CONST_INT_P (op1) && rtx_equal_p (op0, op2)) +op2 = op1; + /* Similarly for op0 != op1 ? op2 : op0 and op0 != op1 ? op2 : op1. */ + else if (code == NE && CONST_INT_P (op1) && rtx_equal_p (op0, op3)) +op3 = op1; + /* Don't attempt mode expansion here -- if we had to expand 5 or 6 HImode insns, we'd be swallowed in word prefix ops. */ if ((mode != HImode || TARGET_FAST_PREFIX) && (mode != (TARGET_64BIT ? TImode : DImode)) - && CONST_INT_P (operands[2]) - && CONST_INT_P (operands[3])) + && CONST_INT_P (op2) + && CONST_INT_P (op3)) { rtx out = operands[0]; - HOST_WIDE_INT ct = INTVAL (operands[2]); - HOST_WIDE_INT cf = INTVAL (operands[3]); + HOST_WIDE_INT ct = INTVAL (op2); + HOST_WIDE_INT cf = INTVAL (op3); HOST_WIDE_INT diff; diff = ct - cf; @@ -3559,6 +3573,9 @@ ix86_expand_int_movcc (rtx operands[]) if (BRANCH_COST (optimize_insn_for_speed_p (), false) <= 2) return false; + operands[2] = op2; + operands[3] = op3; + /* If one of the two operands is an interesting constant, load a constant with the above and mask it in with a logical operation. */ fixes the first and last 2 functions, now to look what's going on with the second and third one...
[Bug fortran/100813] Function of array of pointers to abstract class returning an array since r6-202-gf3b0bb7a560be0f0
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100813 Martin Liška changed: What|Removed |Added Known to work||12.0 CC||burnus at gcc dot gnu.org --- Comment #3 from Martin Liška --- Yes, it was fixed with r12-7526-gc0134b7383992aab. @Tobias: Is it a dup of any of the PRs referenced in the commit (PR99585, PR104430)?
[Bug rtl-optimization/105338] [12 Regression] Regression: jump or cmove generated for pattern (x ? CST : 0)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105338 --- Comment #8 from Jakub Jelinek --- Ok, so at least for the 2nd function, the problem is that we reject it from noce_try_cmove as well from noce_try_cmove_arith based on costs. That is the case for the NEXT_PASS (pass_sink_code, false /* unsplit edges */); compilation too, though it seems the cost is 4 higher in the vanilla trunk case. I think that can be perhaps fixed with: --- gcc/config/i386/i386-expand.cc.jj 2022-04-22 14:18:27.0 +0200 +++ gcc/config/i386/i386-expand.cc 2022-04-22 15:13:47.263829089 +0200 @@ -3224,8 +3224,7 @@ ix86_expand_int_movcc (rtx operands[]) } diff = ct - cf; - if (reg_overlap_mentioned_p (out, op0) - || reg_overlap_mentioned_p (out, op1)) + if (reg_overlap_mentioned_p (out, compare_op)) tmp = gen_reg_rtx (mode); if (mode == DImode) - at least I don't really see the point of using yet another temporary when we already emitted the comparison earlier and all we emit is compare_op and assignment to out. Anyway, with NEXT_PASS (pass_sink_code, false /* unsplit edges */); it succeeds then with cond_move_process_if_block. But it doesn't with vanilla trunk, because it punts on: 4060 /* Don't try to handle this if the condition uses the 4061 destination register. */ 4062 if (reg_overlap_mentioned_p (dest, cond)) 4063return FALSE; I'd say it is reasonable to punt on that, because the whole cond_move_process_if_block is meant to handle multiple cmoves, not just one, and we handle all of them with the same cond. The only case that could be handled is if it is the very last set in then_bb and else_bb is not present, or if it is the last set in else_bb. I must say I'm also quite surprised we don't really check any costs in the cond_move_process_if_block and just blindly assume it will always be a win, so it seems it happily handles even the cases of a single dest assignment that earlier noce_* routines attempt (but those do check the costs and in this case punt).
[Bug rtl-optimization/105338] [12 Regression] Regression: jump or cmove generated for pattern (x ? CST : 0)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105338 --- Comment #9 from Jakub Jelinek --- Note, in both the first and second function if_info->original_cost is smaller than seq_cost of the new sequence, but in the first function if_info->max_seq_cost is larger than seq_cost of the new sequence, in the second it is 0. And the reason for that difference is that predictable_p is true in the second function and not the first one, I presume because of the negative return value predictor that predicts returning -2 as unlikely. But if the negative value return heuristic is right (at least most of the time), then using conditional jump seems to be the right choice.
[Bug target/105338] [12 Regression] Regression: jump or cmove generated for pattern (x ? CST : 0)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105338 --- Comment #10 from Jakub Jelinek --- Created attachment 52850 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52850&action=edit gcc12-pr105338.patch Full untested patch for everything but the predictable cases.
[Bug c++/104631] Visibility of static member s yields duplicate symbols.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104631 Alexander Monakov changed: What|Removed |Added CC||amonakov at gcc dot gnu.org --- Comment #3 from Alexander Monakov --- Note that what matters is not the type of the member, but whether template parameters have hidden visibility, as the following example demonstrates: struct S { }; template struct TS { __attribute__((visibility("default"))) static int i; __attribute__((visibility("default"))) static S s; }; template int TS::i{}; template S TS::s{}; template struct TS; template struct TS;
[Bug c++/104470] internal compiler error: Segmentation fault compiling std::variant with -std=c++20
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104470 Marek Polacek changed: What|Removed |Added CC||mpolacek at gcc dot gnu.org --- Comment #5 from Marek Polacek --- #c3 started to ICE with r10-5020-g1a291106384cab.
[Bug c++/104470] [10/11/12 Regression] internal compiler error: Segmentation fault compiling std::variant with -std=c++20
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104470 Marek Polacek changed: What|Removed |Added Summary|internal compiler error:|[10/11/12 Regression] |Segmentation fault |internal compiler error: |compiling std::variant with |Segmentation fault |-std=c++20 |compiling std::variant with ||-std=c++20 Priority|P3 |P2 Target Milestone|--- |10.4
[Bug target/104723] [12 regression] Redundant usage of stack
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104723 --- Comment #10 from Jakub Jelinek --- (In reply to H.J. Lu from comment #8) > > DSE can remove redundant load/store for TI, but not OI/XI. DSE can remove redundant load/store for OI/XI just fine, just remove the last 7 from the string so that it is 48 bytes instead of 49 and all of sudden it works fine. It is indeed due to: > It is due to overlapping store. this. Wonder if we couldn't special case overlapping stores if they are loaded from constant pool and the overlapping bytes have the same values. And for the backend, the question is how big the penalty for the overlapping store is compared to doing multiple non-overlapping stores. Say for those 49 bytes one could do one OI, one TI/V1TI and one QI load/store as opposed to one aligned and one misaligned OI load/store. For say: void foo (void *p, void *q) { __builtin_memcpy (p, q, 49); } we emit the 2 overlapping loads/stores for -mavx512f and 4 non-overlapping loads/stores with say -mavx2.
[Bug c++/86193] Partial ordering of non-type template parameters with dependent types
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86193 Patrick Palka changed: What|Removed |Added CC||ppalka at gcc dot gnu.org See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=105289 --- Comment #3 from Patrick Palka --- I noticed GCC 8, 9, and 10 accept the testcase in C++17 mode ever since r8-1437-g3da557ec145823. GCC 11 began rejecting the testcase in C++17 mode ever since r11-6483-ge2e2f3f2c9400f.
[Bug sanitizer/105347] New: Failed to build from source on FreeBSD 11.* due to using nonexistent sha224.h
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105347 Bug ID: 105347 Summary: Failed to build from source on FreeBSD 11.* due to using nonexistent sha224.h Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: msl023508 at gmail dot com CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org Target Milestone: --- GCC version 12.0.1 20220417 ../../../../gcc-12-20220417/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp:73:10: fatal error: sha224.h: No such file or directory 73 | #include | ^~ compilation terminated. gmake[4]: *** [Makefile:616: sanitizer_platform_limits_freebsd.lo] Error 1 According to FreeBSD SVN (https://svnweb.freebsd.org/base/stable/12/sys/crypto/sha2/sha224.h?view=log), 'sha224.h' was made available on 12.0-RELEASE.
[Bug middle-end/105348] New: Overly aggressive -Warray-bounds after conditional
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105348 Bug ID: 105348 Summary: Overly aggressive -Warray-bounds after conditional Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: thiago at kde dot org Target Milestone: --- Testcase: #include char empty; void sink(int); bool cond(size_t); void f(const char *s, size_t l) { int n; if (cond(l)) { memcpy(&n, s, sizeof(n)); sink(n); } } void g() { f(&empty, 1); } #ifdef EXPAND bool cond(size_t l) { return l >= sizeof(int); } #endif $ gcc -DEXPAND -O3 -c -Wall -Wextra -Werror test.cpp && echo $? 0 $ gcc -O3 -c -Wall -Wextra -Werror test.cpp && echo $? In function ‘void f(const char*, size_t)’, inlined from ‘void f(const char*, size_t)’ at test.cpp:6:6, inlined from ‘void g()’ at test.cpp:17:6: test.cpp:10:15: error: array subscript ‘unsigned int[0]’ is partly outside array bounds of ‘char [1]’ [-Werror=array-bounds] 10 | memcpy(&n, s, sizeof(n)); | ~~^~ test.cpp: In function ‘void g()’: test.cpp:2:6: note: object ‘empty’ of size 1 2 | char empty; | ^ cc1plus: all warnings being treated as errors I've noticed this even when the other function was present and available for inlining. Unfortunately, for reasons outside of my direct control, GCC decided not to inline that function, which meant it considers the condition bad.
[Bug libstdc++/100070] Standard library container iterator-pair constructors should check C++20 iterator concepts
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100070 --- Comment #11 from Jonathan Wakely --- https://wg21.link/p2408 is in this area, but doesn't touch the containers. https://wg21.link/p1206 solves the problem, although it's not as convenient as Barry asked for. You can construct a subrange from the new-style iterators and then pass that to the new container members that accept ranges.
[Bug middle-end/105348] Overly aggressive -Warray-bounds after conditional
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105348 --- Comment #1 from Thiago Macieira --- Qt workaround: https://codereview.qt-project.org/c/qt/qtbase/+/407217
[Bug testsuite/105349] New: [12 regression] gcc.target/powerpc/bswap-brw.c fails after r12-8221
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105349 Bug ID: 105349 Summary: [12 regression] gcc.target/powerpc/bswap-brw.c fails after r12-8221 Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: testsuite Assignee: unassigned at gcc dot gnu.org Reporter: seurer at gcc dot gnu.org Target Milestone: --- g:26fa464f42622c60d6929720dd37143a21054ede, r12-8221-g26fa464f42622c make -k check-gcc RUNTESTFLAGS="--target_board=unix'{-m32,-m64}' powerpc.exp=gcc.target/powerpc/bswap-brw.c" FAIL: gcc.target/powerpc/bswap-brw.c scan-assembler \\mxxbrw\\M commit 26fa464f42622c60d6929720dd37143a21054ede Author: Segher Boessenkool Date: Sun Jan 2 14:08:35 2022 + rs6000: Disparage lfiwzx and similar Assembler output changed a bit on BE for this test case. Fails on power power 7 and 8 BE.
[Bug c++/105304] [10/11/12 Regression] ICE segfault using ad-hoc concept with -Wall since r10-7441-ga7ea3d2ced786c45
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105304 Patrick Palka changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |ppalka at gcc dot gnu.org Status|NEW |ASSIGNED
[Bug c++/105289] [11/12 Regression] ICE on partial specialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105289 --- Comment #2 from Michael Steinberg --- Created attachment 52851 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52851&action=edit Working modified partial specialization After the related issue was pointed out, it too made me curious whether my code is valid, that is whether the partial specialization is truly more specialized than the primary template. So I modified the specialization so that Arg is at least as constrained as in the primary template - et voila, the ICE is gone and the code is accepted. This makes me believe that the classification 'ice-on-valid-code' may not be true after all?
[Bug c++/105350] New: False constructor warning in case of [[depreacated]] field in class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105350 Bug ID: 105350 Summary: False constructor warning in case of [[depreacated]] field in class Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: fchelnokov at gmail dot com Target Milestone: --- In the following code the field (a) must not be initialized in the default constructor of A: ``` struct A { [[deprecated]] int a; A() noexcept {} }; ``` but GCC prints the warning: ``` 'A::a' is deprecated [-Wdeprecated-declarations] ``` Clang does not complain. Demo: https://gcc.godbolt.org/z/9s5dEr6jf
[Bug target/105334] [12 Regression] ICE in curr_insn_transform, at lra-constraints.cc:4168 (error: unable to generate reloads)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105334 --- Comment #6 from CVS Commits --- The master branch has been updated by Segher Boessenkool : https://gcc.gnu.org/g:493ae1a1680e2aebf394d8fe80faad745bc7 commit r12-8226-g493ae1a1680e2aebf394d8fe80faad745bc7 Author: Segher Boessenkool Date: Fri Apr 22 15:45:00 2022 + rs6000: Fix pack for soft-float (PR105334) For PR103623 I fixed unpack, but pack is broken as well, as reported in PR105334. Fixing that is a bit more code, but it is pretty simple code nonetheless. 2022-04-22 Segher Boessenkool PR target/105334 * config/rs6000/rs6000.md (pack for FMOVE128): New expander. (pack for FMOVE128): Rename and split the insn_and_split to... (pack_hard for FMOVE128): ... this... (pack_soft for FMOVE128): ... and this.
[Bug fortran/93256] Assumed-shape unlimited polymorphic variable passes values incorrectly
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93256 anlauf at gcc dot gnu.org changed: What|Removed |Added Resolution|--- |DUPLICATE Status|NEW |RESOLVED --- Comment #5 from anlauf at gcc dot gnu.org --- Looks pretty much like a dup of pr92785. *** This bug has been marked as a duplicate of bug 92785 ***
[Bug fortran/92785] expressions passed as real arguments to a dummy polymorphic argument fail with indexing error
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92785 anlauf at gcc dot gnu.org changed: What|Removed |Added CC||jman012345 at gmail dot com --- Comment #8 from anlauf at gcc dot gnu.org --- *** Bug 93256 has been marked as a duplicate of this bug. ***
[Bug target/105334] [12 Regression] ICE in curr_insn_transform, at lra-constraints.cc:4168 (error: unable to generate reloads)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105334 --- Comment #7 from Segher Boessenkool --- Should be fixed now. Testcase for this and PR103623 forthcoming, leaving this PR open until then.
[Bug c++/105351] New: [concepts] Constraint checking does correctly match static member attributes
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105351 Bug ID: 105351 Summary: [concepts] Constraint checking does correctly match static member attributes Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gawain.bolton at free dot fr Target Milestone: --- Created attachment 52852 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52852&action=edit Concept requirements violated when attr2 is not static The attached code is shows how a concept requiring a static attribute matches a structure which has the attribute with a non-static data member. The code also shows that the checking of static vs. non-static functions works as expected. Tested with https://godbolt.org/ using versions: x86-64 gcc v11.2 and trunk Compiler options: -std=c++20 -Wall -Wextra -O2
[Bug c++/105351] [concepts] Constraint checking does correctly match static member attributes
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105351 --- Comment #1 from Andrew Pinski --- Are you sure it should be == 2? Even clang is != 2. The expressions inside requires is not a normal expression and all.
[Bug other/105352] New: Building cross-compiler for host i686-w64-mingw32, target mips32-elf, fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105352 Bug ID: 105352 Summary: Building cross-compiler for host i686-w64-mingw32, target mips32-elf, fails Product: gcc Version: 11.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: dragorn421 at gmail dot com Target Milestone: --- Created attachment 52853 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52853&action=edit configure_log.txt, make_log.txt, make_g++_error_log.txt, libcody_config.log I am building in Ubuntu-22.04, in WSL2 in Windows 10 21H1. I want the compiled executable files to run natively on Windows 32-bits as .exe , hence the host `i686-w64-mingw32`. I want the target to be `mips32-elf` a.k.a. `mips64-unknown-elf`. Having downloaded `binutils-2.38.tar.gz` and `gcc-11.3.0.tar.gz`, I ran the following commands: ``` # install some packages, and build and install binutils sudo apt install build-essential libgmp-dev libmpfr-dev libmpc-dev sudo apt install gcc-mingw-w64-i686 tar -xvf binutils-2.38.tar.gz mkdir objdir_binutils cd objdir_binutils ../binutils-2.38/configure --host=i686-w64-mingw32 --target=mips32-elf --disable-nls sudo apt install texinfo make sudo make install tar -xvf gcc-11.3.0.tar.gz cd gcc-11.3.0 ./contrib/download_prerequisites cd .. mkdir objdir_gcc cd objdir_gcc ../gcc-11.3.0/configure --host=i686-w64-mingw32 --target=mips32-elf --disable-nls make ``` Building and installing binutils worked just fine (I don't know if it's required to build gcc or relevant here) However building gcc fails at `make` with the following error: ``` make[2]: Entering directory '/home/dragorn421/exe_build/objdir_gcc/libcpp' g++ -I../../gcc-11.3.0/libcpp -I. -I../../gcc-11.3.0/libcpp/../include -I../../gcc-11.3.0/libcpp/include -g -O2 -D__USE_MINGW_ACCESS -W -Wall -Wno-narrowing -Wwrite-strings -Wmissing-format-attribute -pedantic -Wno-long-long -fno-exceptions -fno-rtti -I../../gcc-11.3.0/libcpp -I. -I../../gcc-11.3.0/libcpp/../include -I../../gcc-11.3.0/libcpp/include-c -o charset.o -MT charset.o -MMD -MP -MF .deps/charset.Tpo ../../gcc-11.3.0/libcpp/charset.c In file included from ../../gcc-11.3.0/libcpp/system.h:374, from ../../gcc-11.3.0/libcpp/charset.c:21: ../../gcc-11.3.0/libcpp/../include/libiberty.h:112:14: error: ambiguating new declaration of ‘char* basename(const char*)’ 112 | extern char *basename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1); | ^~~~ In file included from ../../gcc-11.3.0/libcpp/system.h:205, from ../../gcc-11.3.0/libcpp/charset.c:21: /usr/include/string.h:524:26: note: old declaration ‘const char* basename(const char*)’ 524 | extern "C++" const char *basename (const char *__filename) | ^~~~ make[2]: *** [Makefile:226: charset.o] Error 1 ``` See attached `configure_log.txt` and `make_log.txt` for the full output of `../gcc-11.3.0/configure` and `make`. As suggested in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65863 , I tried passing `--build=i686-linux` to `../gcc-11.3.0/configure`, which didn't change the resulting error above. For what it's worth I also had the same issue on Ubuntu 18.04, also in WSL2, with gcc 10.3.0 and gcc 11.3.0 Out of curiosity, I tried to comment out the duplicate declaration of the symbol `extern char *basename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1);` (by prepending `//` before the line) in `gcc-11.3.0/include/libiberty.h`. This results in a scarier error (at least to me): ``` Configuring in ./libcody configure: creating cache ./config.cache checking build system type... x86_64-pc-linux-gnu checking host system type... i686-w64-mingw32 checking maintainer-mode... checking whether the C++ compiler works... no configure: error: in `/home/dragorn421/exe_build/objdir_gcc/libcody': configure: error: C++ compiler cannot create executables See `config.log' for more details make[1]: *** [Makefile:8759: configure-libcody] Error 1 ``` See attached `make_g++_error_log.txt` for the full output of this second make run. See attached `libcody_config.log` for the full content of `objdir_gcc/libcody/config.log`. I think the relevant bits are: 1) g++ is recent and "standard" ``` configure:2098: checking for C++ compiler version configure:2107: g++ --version >&5 g++ (Ubuntu 11.2.0-19ubuntu1) 11.2.0 Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. configure:2118: $? = 0 ``` 2) It gets passed a malformed argument? `-Wl,--stack,12582912` ``` configure:2138: checking whether the C++ compiler works configure:2160: g++ -g -O2 -D__USE_MINGW_ACCESS -static-libstdc++ -static-libgcc -Wl,--stack,12582912 co
[Bug fortran/102043] [9/10/11/12 Regression] Wrong array types used for negative stride accesses, gfortran.dg/vector_subscript_1.f90 FAILs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102043 --- Comment #44 from CVS Commits --- The master branch has been updated by Mikael Morin : https://gcc.gnu.org/g:89ca0fffa48b799b228beee48a16e26e24d8e199 commit r12-8227-g89ca0fffa48b799b228beee48a16e26e24d8e199 Author: Mikael Morin Date: Fri Apr 22 22:52:12 2022 +0200 fortran: Pre-evaluate string pointers. [PR102043] This avoids a regression on deferred_character_23.f90 later in the patch series when array references are rewritten to use pointer arithmetic. The problem is a SAVE_EXPR tree as TYPE_SIZE_UNIT of one array element type, which is used by the pointer arithmetic expressions. As these expressions appear in both branches of an if-then-else block, the tree is lowered to a variable in one of the branches but itâs used in both branches, which is invalid middle-end code. This change pre-evaluates the array references or pointer arithmetics to variables before the if-then-else block, so that the SAVE_EXPR are expanded to variables in the parent scope of the if-then-else block, and expressions referencing the variables remain valid in both branches. PR fortran/102043 gcc/fortran/ChangeLog: * trans-expr.cc: Pre-evaluate src and dest to variables before using them. gcc/testsuite/ChangeLog: * gfortran.dg/dependency_49.f90: Update variable occurence count.
[Bug fortran/102043] [9/10/11/12 Regression] Wrong array types used for negative stride accesses, gfortran.dg/vector_subscript_1.f90 FAILs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102043 --- Comment #45 from CVS Commits --- The master branch has been updated by Mikael Morin : https://gcc.gnu.org/g:e72fbb6915c1dd1a52ecef55e10329e353cc3072 commit r12-8228-ge72fbb6915c1dd1a52ecef55e10329e353cc3072 Author: Mikael Morin Date: Fri Apr 22 22:52:26 2022 +0200 fortran: Update index extraction code. [PR102043] This avoids a regression on hollerith4.f90 and hollerith6.f90 later in the patch series when code generation for array references is changed to use pointer arithmetic. The problem comes from the extraction of the array index from an ARRAY_REF tree, which doesnât work if the tree is not an ARRAY_REF any more. This updates the code generated for remaining size evaluation to work with a source tree that uses either array indexing or pointer arithmetic. PR fortran/102043 gcc/fortran/ChangeLog: * trans-io.cc: Add handling for the case where the array is referenced using pointer arithmetic.
[Bug fortran/102043] [9/10/11/12 Regression] Wrong array types used for negative stride accesses, gfortran.dg/vector_subscript_1.f90 FAILs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102043 --- Comment #46 from CVS Commits --- The master branch has been updated by Mikael Morin : https://gcc.gnu.org/g:761dda57482295f9c41fcf87e5defa2ac1959f03 commit r12-8229-g761dda57482295f9c41fcf87e5defa2ac1959f03 Author: Mikael Morin Date: Fri Apr 22 22:52:38 2022 +0200 fortran: Generate an array temporary reference [PR102043] This avoids regressing on char_cast_1.f90 and char_cast_2.f90 later in the patch series when the code generation for array references is changed to use pointer arithmetic. The regressing testcases match part of an array reference in the generated tree dump and itâs not clear how the pattern should be rewritten to match the equivalent with pointer arithmetic. This change uses a method specific to array temporaries to generate array-references, so that these array references are flagged as safe for array indexing and will not be updated to use pointer arithmetic. PR fortran/102043 gcc/fortran/ChangeLog: * trans-array.cc (gfc_conv_expr_descriptor): Use gfc_conv_tmp_array_ref.
[Bug fortran/102043] [9/10/11/12 Regression] Wrong array types used for negative stride accesses, gfortran.dg/vector_subscript_1.f90 FAILs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102043 --- Comment #47 from CVS Commits --- The master branch has been updated by Mikael Morin : https://gcc.gnu.org/g:7964ab6c364c410c34efe7ca2eba797d36525349 commit r12-8230-g7964ab6c364c410c34efe7ca2eba797d36525349 Author: Mikael Morin Date: Fri Apr 22 22:52:50 2022 +0200 fortran: Use pointer arithmetic to index arrays [PR102043] The code generated for array references used to be ARRAY_REF trees as could be expected. However, the middle-end may conclude from those trees that the indexes used are non-negative (more precisely not below the lower bound), which is a wrong assumption in the case of "reversed- order" arrays. The problematic arrays are those with a descriptor and having a negative stride for at least one dimension. The descriptor data points to the first element in array order (which is not the first in memory order in that case), and the negative stride(s) makes walking the array backwards (towards lower memory addresses), and we can access elements with negative index wrt data pointer. With this change, pointer arithmetic is generated by default for array references, unless we are in a case where negative indexes canât happen (array descriptorâs dim element, substrings, explicit shape, allocatable, or assumed shape contiguous). A new flag is added to choose between array indexing and pointer arithmetic, and itâs set if the context can tell array indexing is safe (descriptor dim element, substring, temporary array), or a new method is called to decide on whether the flag should be set for one given array expression. PR fortran/102043 gcc/fortran/ChangeLog: * trans.h (gfc_build_array_ref): Add non_negative_offset argument. * trans.cc (gfc_build_array_ref): Ditto. Use pointer arithmetic if non_negative_offset is false. * trans-expr.cc (gfc_conv_substring): Set flag in the call to gfc_build_array_ref. * trans-array.cc (gfc_get_cfi_dim_item, gfc_conv_descriptor_dimension): Same. (build_array_ref): Decide on whether to set the flag and update the call. (gfc_conv_scalarized_array_ref): Same. New argument tmp_array. (gfc_conv_tmp_array_ref): Update call to gfc_conv_scalarized_ref. (non_negative_strides_array_p): New function. gcc/testsuite/ChangeLog: * gfortran.dg/array_reference_3.f90: New. * gfortran.dg/negative_stride_1.f90: New. * gfortran.dg/vector_subscript_8.f90: New. * gfortran.dg/vector_subscript_9.f90: New. * gfortran.dg/c_loc_test_22.f90: Update dump patterns. * gfortran.dg/finalize_10.f90: Same. Co-Authored-By: Richard Biener
[Bug other/105352] Building cross-compiler for host i686-w64-mingw32, target mips32-elf, fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105352 Andrew Pinski changed: What|Removed |Added Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED --- Comment #1 from Andrew Pinski --- >../gcc-11.3.0/configure --host=i686-w64-mingw32 --target=mips32-elf >--disable-nls >I want the compiled executable files to run natively on Windows 32-bits as >.exe , hence the host `i686-w64-mingw32`. You don't have a i686-w64-mingw32 cross compiler installed though. So you are just doing something which won't work until you get a cross compiler on the machine.
[Bug c++/97296] [10/11 Regression] g++ accepts-invalid after DR2352 fix
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97296 --- Comment #6 from CVS Commits --- The releases/gcc-11 branch has been updated by Marek Polacek : https://gcc.gnu.org/g:47c74508116cb5959686b183374dfe97a5e4fb37 commit r11-9929-g47c74508116cb5959686b183374dfe97a5e4fb37 Author: Marek Polacek Date: Tue Apr 12 17:30:30 2022 -0400 c++: ambiguous call not diagnosed after DR2352 [PR97296] DR 2352 changed the definitions of reference-related (so that it uses "similar type" instead of "same type") and of reference-compatible (use a standard conversion sequence). That means that reference-related is now more broad, which means that we will be binding more things directly. The original patch for DR 2352 caused some problems, which were fixed in r276251 by creating a "fake" ck_qual in direct_reference_binding, so that in void f(int *); // #1 void f(const int * const &); // #2 int *x; int main() { f(x); // call #1 } we call #1. The extra ck_qual in #2 causes compare_ics to select #1, which is a better match for "int *" because then we don't have to do a qualification conversion. Let's turn to the problem in this PR. We have void f(const int * const &); // #1 void f(const int *); // #2 int *x; int main() { f(x); } We arrive in compare_ics to decide which one is better. The ICS for #1 looks like ck_ref_bind <-ck_qual <- ck_identity const int *const & const int *const int * and the ICS for #2 is ck_qual <- ck_rvalue <- ck_identity const int * int * int * We strip the reference and then comp_cv_qual_signature when comparing two ck_quals sees that "const int *" is a proper subset of "const int *const" and we return -1. But that's wrong; presumably the top-level "const" should be ignored and the call should be ambiguous. This patch adjust the type of the "fake" ck_qual so that this problem doesn't arise. PR c++/97296 gcc/cp/ChangeLog: * call.c (direct_reference_binding): strip_top_quals when creating a ck_qual. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/ref-bind4.C: Add dg-error. * g++.dg/cpp0x/ref-bind8.C: New test. (cherry picked from commit 85ae54e18b9a3cbe4feda921ecd77cf275177edf)
[Bug c++/97296] [10/11 Regression] g++ accepts-invalid after DR2352 fix
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97296 Marek Polacek changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --- Comment #7 from Marek Polacek --- Fixed.
[Bug other/105352] Building cross-compiler for host i686-w64-mingw32, target mips32-elf, fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105352 Dragorn421 changed: What|Removed |Added Resolution|INVALID |FIXED Build||x86_64-pc-linux-gnu Host||i686-w64-mingw32 Target||mips64-unknown-elf See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=65863 --- Comment #2 from Dragorn421 --- (In reply to Andrew Pinski from comment #1) > >../gcc-11.3.0/configure --host=i686-w64-mingw32 --target=mips32-elf > >--disable-nls > > > >I want the compiled executable files to run natively on Windows 32-bits as > >.exe , hence the host `i686-w64-mingw32`. > > You don't have a i686-w64-mingw32 cross compiler installed though. > So you are just doing something which won't work until you get a cross > compiler on the machine. Doesn't `sudo apt install gcc-mingw-w64-i686` take care of that? It seems to be detected correctly going by the configure output: ``` checking for i686-w64-mingw32-gcc... i686-w64-mingw32-gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.exe checking for suffix of executables... .exe checking whether we are cross compiling... no checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether i686-w64-mingw32-gcc accepts -g... yes checking for i686-w64-mingw32-gcc option to accept ISO C89... none needed ```
[Bug c++/105321] [9/10/11 Regression] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321 --- Comment #9 from CVS Commits --- The releases/gcc-11 branch has been updated by Marek Polacek : https://gcc.gnu.org/g:afec66b054a7603ef394dc712ccbba37ae645fd9 commit r11-9930-gafec66b054a7603ef394dc712ccbba37ae645fd9 Author: Marek Polacek Date: Wed Apr 20 16:02:52 2022 -0400 c++: wrong error with constexpr COMPOUND_EXPR [PR105321] Here we issue a bogus error for the first assert in the test. Therein we have = (void) (VIEW_CONVERT_EXPR(yes) || handle_error ());, VIEW_CONVERT_EXPR(value); which has a COMPOUND_EXPR, so we get to cxx_eval_constant_expression . The problem here is that we call 7044 /* Check that the LHS is constant and then discard it. */ 7045 cxx_eval_constant_expression (ctx, op0, 7046 true, non_constant_p, overflow_p, 7047 jump_target); where lval is always true, so the PARM_DECL 'yes' is not evaluated into its value. Fixed by always passing false for 'lval' in cxx_eval_logical_expression; there's no case where we actually expect an lvalue from a TRUTH_*. PR c++/105321 gcc/cp/ChangeLog: * constexpr.c (cxx_eval_logical_expression): Always pass false for lval to cxx_eval_constant_expression. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-105321.C: New test. (cherry picked from commit 93b65ed9706e2ceb4be7b28c9ff9be759e68a614)
[Bug c++/105321] [9/10/11 Regression] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321 Marek Polacek changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --- Comment #10 from Marek Polacek --- Fixed in GCC 11.3 too.
[Bug c++/105353] New: __builtin_shufflevector with template parameter fails to compile on GCC 12 but compiles on clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105353 Bug ID: 105353 Summary: __builtin_shufflevector with template parameter fails to compile on GCC 12 but compiles on clang Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: john_platts at hotmail dot com Target Milestone: --- The following code fails to compile with GCC 12 but compiles successfully on clang (with the -std=c++17 flag): #include typedef std::uint8_t Simd128U8VectT __attribute__((__vector_size__(16))); template static inline Simd128U8VectT ShufFunc(Simd128U8VectT vect) noexcept { if constexpr(unsigned(ShuffleIndex) >= 16) return Simd128U8VectT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; else if constexpr(ShuffleIndex == 0) return vect; else return __builtin_shufflevector(vect, vect, ShuffleIndex, ShuffleIndex + 1, ShuffleIndex + 2, ShuffleIndex + 3, ShuffleIndex + 4, ShuffleIndex + 5, ShuffleIndex + 6, ShuffleIndex + 7, ShuffleIndex + 8, ShuffleIndex + 9, ShuffleIndex + 10, ShuffleIndex + 11, ShuffleIndex + 12, ShuffleIndex + 13, ShuffleIndex + 14, ShuffleIndex + 15); } auto func1(Simd128U8VectT vect) noexcept { return ShufFunc<5>(vect); } Here is the assembly output when the above code is compiled on clang 14.0.0 with the -O2 -std=c++17 flags: func1(unsigned char __vector(16)): # @func1(unsigned char __vector(16)) movdqa xmm1, xmm0 psrldq xmm1, 5 # xmm1 = xmm1[5,6,7,8,9,10,11,12,13,14,15],zero,zero,zero,zero,zero pslldq xmm0, 11# xmm0 = zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,xmm0[0,1,2,3,4] por xmm0, xmm1 ret The below code compiles successfully with GCC 11 and GCC 12 (which uses __builtin_shuffle instead of __builtin_shufflevector): #include typedef std::uint8_t Simd128U8VectT __attribute__((__vector_size__(16))); template static inline Simd128U8VectT ShufFunc(Simd128U8VectT vect) noexcept { if constexpr(unsigned(ShuffleIndex) >= 16) return Simd128U8VectT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; else if constexpr(ShuffleIndex == 0) return vect; else return __builtin_shuffle(vect, vect, (Simd128U8VectT){ ShuffleIndex, ShuffleIndex + 1, ShuffleIndex + 2, ShuffleIndex + 3, ShuffleIndex + 4, ShuffleIndex + 5, ShuffleIndex + 6, ShuffleIndex + 7, ShuffleIndex + 8, ShuffleIndex + 9, ShuffleIndex + 10, ShuffleIndex + 11, ShuffleIndex + 12, ShuffleIndex + 13, ShuffleIndex + 14, ShuffleIndex + 15 }); } auto func1(Simd128U8VectT vect) noexcept { return ShufFunc<5>(vect); }
[Bug c++/105353] __builtin_shufflevector with value dependent constant
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105353 Andrew Pinski changed: What|Removed |Added Summary|__builtin_shufflevector |__builtin_shufflevector |with template parameter |with value dependent |fails to compile on GCC 12 |constant |but compiles on clang | Ever confirmed|0 |1 Last reconfirmed||2022-04-22 Status|UNCONFIRMED |NEW --- Comment #1 from Andrew Pinski --- Confirmed, it is all value dependent constants really. e.g. even sizeof fails: #include typedef std::uint8_t Simd128U8VectT __attribute__((__vector_size__(16))); #define ShuffleIndex sizeof(T) template static inline Simd128U8VectT ShufFunc(Simd128U8VectT vect) noexcept { if constexpr(unsigned(ShuffleIndex) >= 16) return Simd128U8VectT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; else if constexpr(ShuffleIndex == 0) return vect; else return __builtin_shufflevector(vect, vect, ShuffleIndex, ShuffleIndex + 1, ShuffleIndex + 2, ShuffleIndex + 3, ShuffleIndex + 4, ShuffleIndex + 5, ShuffleIndex + 6, ShuffleIndex + 7, ShuffleIndex + 8, ShuffleIndex + 9, ShuffleIndex + 10, ShuffleIndex + 11, ShuffleIndex + 12, ShuffleIndex + 13, ShuffleIndex + 14, ShuffleIndex + 15); }
[Bug c++/105353] __builtin_shufflevector with value dependent constant
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105353 Marek Polacek changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |mpolacek at gcc dot gnu.org Status|NEW |ASSIGNED CC||mpolacek at gcc dot gnu.org --- Comment #2 from Marek Polacek --- Right. I have a fix.
[Bug target/105354] New: __builtin_shuffle for alignr generates suboptimal code unless SSSE3 is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105354 Bug ID: 105354 Summary: __builtin_shuffle for alignr generates suboptimal code unless SSSE3 is enabled Product: gcc Version: 11.2.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: john_platts at hotmail dot com Target Milestone: --- The below code generates suboptimal code if SSE2 is enabled but SSSE3 is not enabled: #include typedef std::uint8_t Simd128U8VectT __attribute__((__vector_size__(16))); template static inline Simd128U8VectT RotateRightByByteAmt(Simd128U8VectT vect) noexcept { constexpr int NormalizedRotateAmt = RotateAmt & 15; if constexpr(NormalizedRotateAmt == 0) return vect; else return __builtin_shuffle(vect, vect, (Simd128U8VectT){ NormalizedRotateAmt, NormalizedRotateAmt + 1, NormalizedRotateAmt + 2, NormalizedRotateAmt + 3, NormalizedRotateAmt + 4, NormalizedRotateAmt + 5, NormalizedRotateAmt + 6, NormalizedRotateAmt + 7, NormalizedRotateAmt + 8, NormalizedRotateAmt + 9, NormalizedRotateAmt + 10, NormalizedRotateAmt + 11, NormalizedRotateAmt + 12, NormalizedRotateAmt + 13, NormalizedRotateAmt + 14, NormalizedRotateAmt + 15 }); } auto func1(Simd128U8VectT vect) noexcept { return RotateRightByByteAmt<5>(vect); } Here is the code that is generated on GCC 11 if the -O2 -mssse3 options are specified: func1(unsigned char __vector(16)): palignr xmm0, xmm0, 5 ret Here is the code that is generated on GCC 11 if the -O2 option is specified but the -mssse3 option is not specified on 64-bit x86 platforms: func1(unsigned char __vector(16)): sub rsp, 144 movdecx, xmm0 movaps XMMWORD PTR [rsp+8], xmm0 movzx edx, BYTE PTR [rsp+20] movzx ecx, cl movaps XMMWORD PTR [rsp+24], xmm0 movzx eax, BYTE PTR [rsp+35] sal rdx, 8 movaps XMMWORD PTR [rsp+40], xmm0 or rdx, rax movzx eax, BYTE PTR [rsp+50] movaps XMMWORD PTR [rsp+56], xmm0 sal rdx, 8 movaps XMMWORD PTR [rsp+72], xmm0 or rdx, rax movzx eax, BYTE PTR [rsp+65] movaps XMMWORD PTR [rsp+88], xmm0 sal rdx, 8 movaps XMMWORD PTR [rsp+104], xmm0 or rdx, rax movzx eax, BYTE PTR [rsp+80] movaps XMMWORD PTR [rsp-104], xmm0 sal rdx, 8 movaps XMMWORD PTR [rsp-88], xmm0 movzx edi, BYTE PTR [rsp-85] or rdx, rax movzx eax, BYTE PTR [rsp+95] movaps XMMWORD PTR [rsp-72], xmm0 sal rdx, 8 movaps XMMWORD PTR [rsp-56], xmm0 or rdx, rax movzx eax, BYTE PTR [rsp+110] movaps XMMWORD PTR [rsp-40], xmm0 sal rdx, 8 movaps XMMWORD PTR [rsp-24], xmm0 or rdx, rax movzx eax, BYTE PTR [rsp-100] movaps XMMWORD PTR [rsp+120], xmm0 movzx esi, BYTE PTR [rsp+125] movaps XMMWORD PTR [rsp-8], xmm0 sal rdx, 8 sal rax, 8 or rdx, rsi or rax, rdi movzx edi, BYTE PTR [rsp-70] sal rax, 8 or rax, rdi movzx edi, BYTE PTR [rsp-55] sal rax, 8 or rax, rdi sal rax, 8 or rax, rcx movzx ecx, BYTE PTR [rsp-25] sal rax, 8 or rax, rcx movzx ecx, BYTE PTR [rsp-10] sal rax, 8 or rax, rcx movzx ecx, BYTE PTR [rsp+5] mov QWORD PTR [rsp-120], rdx sal rax, 8 or rax, rcx mov QWORD PTR [rsp-112], rax movdqa xmm0, XMMWORD PTR [rsp-120] add rsp, 144 ret Here is a more optimal implementation of the above code on 64-bit x86 platforms when SSE2 is enabled but SSSE3 is not enabled: func1(unsigned char __vector(16)): movdqa xmm1, xmm0 psrldq xmm1, 5 pslldq xmm0, 11 por xmm0, xmm1 ret
[Bug c++/105353] __builtin_shufflevector with value dependent constant
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105353 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #3 from Jakub Jelinek --- As c_build_shufflevector requires that the 3rd+ args are all INTEGER_CSTs that fit into shwi, I think we need to avoid calling that function if any of those isn't such and processing_template_decl. Perhaps we can fold_non_dependent_expr them first.
[Bug target/105354] __builtin_shuffle for alignr generates suboptimal code unless SSSE3 is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105354 Andrew Pinski changed: What|Removed |Added Severity|normal |enhancement Target||x86_64-linux-gnu
[Bug c++/105353] __builtin_shufflevector with value dependent constant
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105353 --- Comment #4 from Marek Polacek --- My fix is just --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -6315,7 +6315,7 @@ build_x_shufflevector (location_t loc, vec *args, if (processing_template_decl) { for (unsigned i = 0; i < args->length (); ++i) - if (type_dependent_expression_p ((*args)[i])) + if (instantiation_dependent_expression_p ((*args)[i])) { tree exp = build_min_nt_call_vec (NULL, args); CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR; so what we leave the IFN_SHUFFLEVECTOR to be processed when instantiating. fold_non_dependent_expr wouldn't know what to substitute T with yet.
[Bug c++/105353] __builtin_shufflevector with value dependent constant
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105353 --- Comment #5 from Jakub Jelinek --- Maybe, but for i <= 1 IMHO type_dependent_expression_p is right, that is why we build_non_dependent_expr, c_build_shufflevector oesn't care about those exact values.
[Bug c++/105353] __builtin_shufflevector with value dependent constant
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105353 --- Comment #6 from Marek Polacek --- Good point, I suppose this is better: --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -6315,7 +6315,9 @@ build_x_shufflevector (location_t loc, vec *args, if (processing_template_decl) { for (unsigned i = 0; i < args->length (); ++i) - if (type_dependent_expression_p ((*args)[i])) + if (i <= 1 + ? type_dependent_expression_p ((*args)[i]) + : instantiation_dependent_expression_p ((*args)[i])) { tree exp = build_min_nt_call_vec (NULL, args); CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
[Bug libstdc++/102994] std::atomic::wait is not marked const
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102994 --- Comment #16 from CVS Commits --- The master branch has been updated by Thomas Rodgers : https://gcc.gnu.org/g:7c21556daf385fe9ece37319f574776dd7d8ab1c commit r12-8231-g7c21556daf385fe9ece37319f574776dd7d8ab1c Author: Thomas W Rodgers Date: Fri Apr 22 15:46:19 2022 -0700 libstdc++: Make atomic notify_one and notify_all non-const PR102994 "atomics: std::atomic::wait is not marked const" raises the issue that the current libstdc++ implementation marks the notify members const, the implementation strategy used by libstdc++, as well as libc++ and the Microsoft STL, do not require the atomic to be mutable (it is hard to conceive of a desirable implementation approach that would require it). The original paper proposing the wait/notify functionality for atomics (p1185) also had these members marked const for the first three revisions, but that was changed without explanation in r3 and subsequent revisions of the paper. After raising the issue to the authors of p1185 and the author of the libc++ implementation, the consensus seems to be "meh, it's harmless" so there seems little appetite for an LWG issue to revisit the subject. This patch changes the libstdc++ implementation to be in agreement with the standard by removing const from those notify_one/notify_all members. libstdc++-v3/ChangeLog: PR libstdc++/102994 * include/bits/atomic_base.h (atomic_flag::notify_one, notify_all): Remove const qualification. (__atomic_base::notify_one, notify_all): Likewise. * include/std/atomic (atomic::notify_one, notify_all): Likewise. (atomic::notify_one, notify_all): Likewise. (atomic::notify_one, notify_all): Likewise. (atomic_notify_one, atomic_notify_all): Likewise. * testsuite/29_atomics/atomic/wait_notify/102994.cc: Adjust test to account for change in notify_one/notify_all signature.
[Bug libstdc++/102994] std::atomic::wait is not marked const
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102994 --- Comment #17 from CVS Commits --- The releases/gcc-11 branch has been updated by Thomas Rodgers : https://gcc.gnu.org/g:977cbabeb1c1a9a28cc45655bdc693e1594642f0 commit r11-9931-g977cbabeb1c1a9a28cc45655bdc693e1594642f0 Author: Thomas W Rodgers Date: Fri Apr 22 15:46:19 2022 -0700 libstdc++: Make atomic notify_one and notify_all non-const PR102994 "atomics: std::atomic::wait is not marked const" raises the issue that the current libstdc++ implementation marks the notify members const, the implementation strategy used by libstdc++, as well as libc++ and the Microsoft STL, do not require the atomic to be mutable (it is hard to conceive of a desirable implementation approach that would require it). The original paper proposing the wait/notify functionality for atomics (p1185) also had these members marked const for the first three revisions, but that was changed without explanation in r3 and subsequent revisions of the paper. After raising the issue to the authors of p1185 and the author of the libc++ implementation, the consensus seems to be "meh, it's harmless" so there seems little appetite for an LWG issue to revisit the subject. This patch changes the libstdc++ implementation to be in agreement with the standard by removing const from those notify_one/notify_all members. libstdc++-v3/ChangeLog: PR libstdc++/102994 * include/bits/atomic_base.h (atomic_flag::notify_one, notify_all): Remove const qualification. (__atomic_base::notify_one, notify_all): Likewise. * include/std/atomic (atomic::notify_one, notify_all): Likewise. (atomic::notify_one, notify_all): Likewise. (atomic::notify_one, notify_all): Likewise. (atomic_notify_one, atomic_notify_all): Likewise. * testsuite/29_atomics/atomic/wait_notify/102994.cc: Adjust test to account for change in notify_one/notify_all signature. (cherry picked from commit 7c21556daf385fe9ece37319f574776dd7d8ab1c)
[Bug other/105352] Building cross-compiler for host i686-w64-mingw32, target mips32-elf, fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105352 --- Comment #3 from Dragorn421 --- Ah, I was missing the g++ cross compiler, I see. Thanks :)
[Bug driver/105355] New: -msmall-data-limit= unexpectedly accepts a separate argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105355 Bug ID: 105355 Summary: -msmall-data-limit= unexpectedly accepts a separate argument Product: gcc Version: 10.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: driver Assignee: unassigned at gcc dot gnu.org Reporter: izbyshev at ispras dot ru Target Milestone: --- Target: riscv64-linux-gnu "msmall-data-limit=" is marked as both Joined and Separate at https://gcc.gnu.org/git?p=gcc.git;a=blob;f=gcc/config/riscv/riscv.opt;h=492aad1232404c2711811c3d04f2e02902d1b740;hb=7964ab6c364c410c34efe7ca2eba797d36525349#l95. This is inconsistent with other "-m" options (which permit only joined spelling) and allows strange commands like "riscv64-linux-gnu-gcc -msmall-data-limit= 0 test.c". Note that even if joined spelling is used by the user, GCC driver splits it for the frontend: riscv64-linux-gnu-gcc -msmall-data-limit=0 test.c -### [...] /usr/lib/gcc-cross/riscv64-linux-gnu/10/cc1 -quiet -imultilib . -imultiarch riscv64-linux-gnu test.c -quiet -dumpbase test.c "-mno-small-data-limit=" 0 "-march=rv64imafdc" "-mabi=lp64d" -auxbase test -fstack-protector-strong -Wformat -Wformat-security -o /tmp/ccIJvDDO.s [...] This inconsistency unnecessarily complicates life of tools that parse compiler commands (e.g. for static analysis).
[Bug c/105356] New: Segfault in compiled program caused by premature ternary clause evaluation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105356 Bug ID: 105356 Summary: Segfault in compiled program caused by premature ternary clause evaluation Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: junk at sigpwr dot com Target Milestone: --- Created attachment 52854 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52854&action=edit .i file for poc Seeing a segfault in what I believe to be valid C, related to premature evaluation of one of the branches of a ternary expression. Works on GCC8, fails on GCC9+. Godbolt version: https://godbolt.org/z/1sTG67n8W Works on: 8.5 Segfaults on: 9.4 10.3 11.2 trunk $ x86_64-unknown-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu-gcc COLLECT_LTO_WRAPPER=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu/libexec/gcc/x86_64-unknown-linux-gnu/11.2.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: /home/danielnelson/toolchain_ng/x86_new/.build/x86_64-unknown-linux-gnu/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-build_pc-linux-gnu --target=x86_64-unknown-linux-gnu --prefix=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu --exec_prefix=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu --with-sysroot=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot --enable-languages=c,c++,fortran,go --with-pkgversion='crosstool-NG 1.25.0_rc1' --enable-__cxa_atexit --enable-libmudflap --disable-libgomp --enable-libssp --enable-libquadmath --enable-libquadmath-support --disable-libsanitizer --enable-libmpx --disable-libstdcxx-verbose --with-gmp=/home/danielnelson/toolchain_ng/x86_new/.build/x86_64-unknown-linux-gnu/buildtools --with-mpfr=/home/danielnelson/toolchain_ng/x86_new/.build/x86_64-unknown-linux-gnu/buildtools --with-mpc=/home/danielnelson/toolchain_ng/x86_new/.build/x86_64-unknown-linux-gnu/buildtools --with-isl=/home/danielnelson/toolchain_ng/x86_new/.build/x86_64-unknown-linux-gnu/buildtools --disable-lto --without-zstd --enable-threads=posix --enable-target-optspace --disable-plugin --disable-nls --with-system-zlib --disable-multilib --with-local-prefix=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot --enable-long-long Thread model: posix Supported LTO compression algorithms: zlib gcc version 11.2.0 (crosstool-NG 1.25.0_rc1) Command line: x86_64-unknown-linux-gnu-gcc --sysroot=/home/danielnelson/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot -O2 -static --save-temps -o test poc.c No errors in GCC output. C file contents: typedef long unsigned int size_t; struct hmap_node { size_t hash; struct hmap_node *next; }; struct hmap { struct hmap_node **buckets; struct hmap_node *one; size_t mask; size_t n; }; struct parent { char *name; struct hmap children; }; struct child { char *name; struct hmap_node hmap_node; }; static inline struct hmap_node * hmap_next__(const struct hmap *hmap, size_t start) { size_t i; for (i = start; i <= hmap->mask; i++) { struct hmap_node *node = hmap->buckets[i]; if (node) { return node; } } return ((void *)0); } static inline struct hmap_node * hmap_first(const struct hmap *hmap) { return hmap_next__(hmap, 0); } static inline struct hmap_node * hmap_next(const struct hmap *hmap, const struct hmap_node *node) { return (node->next ? node->next : hmap_next__(hmap, (node->hash & hmap->mask) + 1)); } void parent_set_children(struct parent *prnt) { struct child *child, *next_child; size_t i; for (((child) = ((typeof(child)) (void *) ((char *) (hmap_first(&prnt->children)) - __builtin_offsetof ( typeof(*(child)) , hmap_node))), 1); (&(child)->hmap_node != ((void *)0) ? ((next_child) = ((typeof(next_child)) (void *) ((char *) (hmap_next(&prnt->children, &(child)->hmap_node)) - __builtin_offsetof ( typeof(*(next_child)) , hmap_node))), 1) : 0); (child) = (next_child)) { asm volatile("nop\r\n"); } } struct parent m; int main(int argc, char** argv) { m.name = "foo"; m.children.buckets = &m.children.one; parent_set_children(&m); return 0; }
[Bug middle-end/105356] Segfault in compiled program caused by premature ternary clause evaluation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105356 Andrew Pinski changed: What|Removed |Added Component|c |middle-end --- Comment #1 from Andrew Pinski --- clang has the same behavior at -O1 and above.
[Bug middle-end/105356] Segfault in compiled program caused by premature ternary clause evaluation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105356 Andrew Pinski changed: What|Removed |Added Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED --- Comment #2 from Andrew Pinski --- (&(child)->hmap_node != ((void *)0) Is always true and not the same as child != null.
[Bug c/90181] Feature request: provide a way to explicitly select specific named registers in constraints
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90181 --- Comment #11 from Elliott M --- (In reply to Andreas Schwab from comment #1) > x86 doesn't support this either. It just happens to have a few register > classes that consist of a single register, but only because of ISA > constraints. That is a *gross* mischaracterization. Constraint list for x86 includes: 'a', 'b', 'c', 'd', 'S', 'D'. Indeed, that doesn't include bp or sp, but does include *all* the registers which get used for interesting purposes (register-passing calling conventions). Perhaps people writing GCC haven't felt pressure to implement this since they're primarily dealing with x86 and x86 effectively already has this? I'm tempted to propose this to people involved with Clang, then come back here and suggest GCC should copy the feature...
[Bug c/90181] Feature request: provide a way to explicitly select specific named registers in constraints
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90181 --- Comment #12 from Andrew Pinski --- (In reply to Elliott M from comment #11) > (In reply to Andreas Schwab from comment #1) > > x86 doesn't support this either. It just happens to have a few register > > classes that consist of a single register, but only because of ISA > > constraints. > > That is a *gross* mischaracterization. Constraint list for x86 includes: > 'a', 'b', 'c', 'd', 'S', 'D'. Indeed, that doesn't include bp or sp, but > does include *all* the registers which get used for interesting purposes > (register-passing calling conventions). Actually this is NOT a gross mischaracterization of GCC's x86 inline-asm and not understanding that is misrepresenting the history of GCC's inline-asm and how it just exposes internal details of GCC to the user. GCC's x86 constraints are exactly this way because of instructions requirements (ISA constraints) and all of these constraints are used internally too. It just happens that x86_64 register calling convention matches up with the instruction requirements.