[Bug c++/70796] [DR 1030] Initialization order with braced-init-lists still broken
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70796 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #3 from Matthijs van Duin --- This specifically appears to happen when the constructor has parameters of trivially copyable non-reference types, e.g. this fails: #include struct IntWrap { int x = 0; IntWrap ++() { ++x; return *this; } }; struct Pair { IntWrap first, second; Pair( IntWrap x, IntWrap y ) : first{ x }, second{ y } { } }; int main() { IntWrap i; Pair p{ ++i, ++i }; assert( p.first.x == 1 && p.second.x == 2 ); // FAIL (p.first.x is 2) } but adding a destructor to IntWrap suffices to make it pass. Interestingly, when using simple ints there also appear to be very narrow constraints on the initializer arguments to trigger the bug: #include struct IntPair { int first, second; IntPair( int x, int y ) : first{ x }, second{ y } { } }; void testcase_fail() { int i = 0; IntPair p{ ++i, ++i }; assert( p.first == 1 && p.second == 2 ); // FAIL (p.first is 2) } void testcase_ok_1() { int i = 0; IntPair p{ ++i, ++i }; assert( p.first == 1 && p.second == 2 ); // ok int = i; IntPair q{ ++j, ++j }; assert( q.first == 3 && q.second == 4 ); // ok } void testcase_ok_2() { int i = 0; IntPair p{ (int &)++i, (int &)++i }; assert( p.first == 1 && p.second == 2 ); // ok } int main() { testcase_ok_1(); testcase_ok_2(); testcase_fail(); } even though the analogous testcases for IntWrap all fail. Related: bug 51253 (was supposed to have fixed this but evidently missed some cases) bug 65866 (incorrect -Wsequence-point diagnostic still being emitted) bug 70792 (dup of bug 65866 but discussion in comments covered this case)
[Bug c++/65866] Wrong warning when using list-initialization: operation on 'b' may be undefined [-Wsequence-point]
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65866 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #6 from Matthijs van Duin --- (In reply to Jonathan Wakely from comment #4) Note that this testcase, where the constructor takes trivially copyable prvalue arguments, actually still generates wrong code (so the diagnostic is technically still appropriate), while the original testcase in this bug generates correct code but emits a wrong diagnostic.
[Bug c++/70792] Incorrect sequence point warning with uniform initializer syntax
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70792 --- Comment #12 from Matthijs van Duin --- (In reply to Jonathan Wakely from comment #11) > (In reply to Matthijs van Duin from comment #10) > > I'm assuming this means a new bug should be opened > > about the wrong code generation? > > Yes please. This one is too confusing now. Found an existing one, bug 70796.
[Bug c++/70792] Incorrect sequence point warning with uniform initializer syntax
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70792 --- Comment #10 from Matthijs van Duin --- (In reply to Jonathan Wakely from comment #9) > (In reply to Matthijs van Duin from comment #4) > > Also bug 65866 exists for the warning itself. > > I think this is an exact dup. > > *** This bug has been marked as a duplicate of bug 65866 *** Well, this bug was amended to be about incorrect code generation (although the reporter did not update the title), while bug 65866 is purely about incorrect diagnostics. I'm assuming this means a new bug should be opened about the wrong code generation? (assuming one hasn't been created for it yet)
[Bug c++/89695] unexpected copying of trivially copyable prvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89695 --- Comment #5 from Matthijs van Duin --- So for reference, the Itanium C++ ABI says: "A type which is trivial for the purposes of the ABI will be passed and returned according to the rules of the base C ABI, e.g. in registers; often this has the effect of performing a trivial copy of the type." It is not clear to me what the justification is for that last remark, can someone quote what's in the base C ABI that forbids this optimization? Eliding the trivial copy should be permitted under the as-if rule anyway, there's no way to detect its elision that doesn't involve undefined behaviour.
[Bug c++/102942] Implicit copy constructor not elided
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102942 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #4 from Matthijs van Duin --- This is indeed a duplicate of 89695. The copy constructor isn't being "elided", there's no semantic expectation of it being invoked at all, you're simply initializing the parameter of take(T) with a prvalue T(). As special exception however C++ permits parameters and return values of trivially-copyable types (such as int and StructWithImplicitCpyCtr) to be copied superfluously, which is what you're observing. This exception exists to allow C++ ABIs to pass such types in a C-ABI-compatible way, which may sometimes require copying (notably when passing small types in register for efficiency), though gcc seems to make a superfluous copy whenever it is _allowed_ rather than whenever it is _needed_.
[Bug tree-optimization/83234] Aggressive loop optim warning for loop iteration that cannot happen
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83234 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #2 from Matthijs van Duin --- Probably same as bug 100801 ?
[Bug tree-optimization/100801] Aggressive loop optimizations cause incorrect warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100801 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #3 from Matthijs van Duin --- Simpler testcase: /* compiler flags required to trigger warning: -O1 -ftree-vrp */ static void foo(int *x, long n) { long i = 0; for (; i + 4 <= n; i += 4) { } for (; i < n; i++) { x[i]++; } } void bar(int *x) { foo(x, 128); } A workaround with no runtime overhead is adding the following check between the loops: if (__builtin_constant_p(n % 4 == 0) && n % 4 == 0) return;
[Bug target/92075] New: extracting element from NEON float-vector moves to/from integer register
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92075 Bug ID: 92075 Summary: extracting element from NEON float-vector moves to/from integer register Product: gcc Version: 9.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: matthijsvanduin at gmail dot com Target Milestone: --- On ARM, when extracting an element from a float32x2_t expression, i.e.: float32x2_t v = (...); float v0 = v[0]; In most cases, gcc moves the element to an general-purpose register and back to a VFP/Neon register, even at -Ofast. It doesn't seem to happen when v is an argument or the return value of a non-inline function, but it does happen e.g. when v is an arithmetic expression or produced by a NEON intrinsic or inline asm. It doesn't seem to matter how v0 is consumed (i.e. by returning it, passing it as argument to a function, or consuming it by inline asm). Some test-cases: #include float test1( float32x2_t v ) { return (v + v)[0]; } void test2() { float32x2_t v; asm( "" : "=w"(v) ); float v0 = v[0]; asm( "" :: "w"(v0) ); } void foo( float ); void test3( uint32x2_t v ) { foo( vcvt_n_f32_u32( v, 32 )[0] ); } output produced by "arm-linux-gnueabihf-gcc-9 (Debian 9.2.1-8) 9.2.1 20190909" with -Ofast -mcpu=cortex-a8 -mfpu=neon, reformatted for readability: test1: vadd.f32 d0, d0, d0 vmov.32 r3, d0[0] vmov s0, r3 bxlr test2: vmov.32 r3, d16[0] vmov s15, r3 bx lr test3: vcvt.f32.u32 d0, d0, #32 vmov.32 r3, d0[0] vmov s0, r3 b foo(PLT) This is especially bad on the cortex-A8, where moving from a VFP/Neon register to an general purpose register causes a severe pipeline stall. Note btw how in test1 and test3 no move is needed at all: the final move destination is the register it originally came from, and a different choice of register allocation can make this also true in test2.
[Bug c++/89695] unexpected copying of trivially copyable prvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89695 --- Comment #4 from Matthijs van Duin --- (In reply to Jonathan Wakely from comment #3) > I believe this is required by the ABI for trivially copyable types. I don't see how that's possible, the callee can't tell the difference.
[Bug c++/89695] unexpected copying of trivially copyable prvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89695 Matthijs van Duin changed: What|Removed |Added Summary|inappropriate copying of|unexpected copying of |trivially copyable prvalue |trivially copyable prvalue |arguments |arguments --- Comment #2 from Matthijs van Duin --- (In reply to Richard Biener from comment #1) > So not really inappropriate but fails to optimize it? Yes. Changing title to avoid implying the copying is not permitted.
[Bug c++/89695] New: inappropriate copying of trivially copyable prvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89695 Bug ID: 89695 Summary: inappropriate copying of trivially copyable prvalue arguments Product: gcc Version: 8.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: matthijsvanduin at gmail dot com Target Milestone: --- When a function that has a non-reference parameter of a trivially copyable class-type is invoked with a prvalue expression as argument, e.g.: #include struct Foo { int data[32]; Foo() { printf( "%p (constructor)\n", this ); } }; Foo make_foo() { return Foo{}; } void f( Foo x ) { printf( "%p (parameter)\n", ); } int main() { f( Foo{} ); f( make_foo() ); return 0; } g++ initializes a temporary from this expression and then copy-constructs the parameter from it: 0x7fffce1caa80 (constructor) 0x7fffce1cab00 (parameter) 0x7fffce1caa80 (constructor) 0x7fffce1cab00 (parameter) This appears to happen whenever C++17 permits it and at any optimization level, even though Foo is large and expensive to copy. For example on armhf at -O2, g++ produces this particularly silly-looking output: mov r1, r5 mov r0, r7 bl printf(PLT) mov r2, r8 mov r1, r5 mov r0, r4 bl memcpy(PLT) mov r1, r4 mov r0, r6 bl printf(PLT) mov r1, r5 mov r0, r7 bl printf(PLT) mov r2, r8 mov r1, r5 mov r0, r4 bl memcpy(PLT) mov r1, r4 mov r0, r6 bl printf(PLT) If a user-provided destructor, copy-constructor, or move-constructor is added to the class, no copying is done even at -O0 (as expected due to C++17 requirements): mov r3, r7 mov r0, r3 bl _ZN3FooC1Ev(PLT) mov r3, r7 mov r0, r3 bl _Z1f3Foo(PLT) add r3, r7, #128 mov r0, r3 bl _Z8make_foov(PLT) add r3, r7, #128 mov r0, r3 bl _Z1f3Foo(PLT)
[Bug c++/86521] [8/9 Regression] GCC 8 selects incorrect overload of ref-qualified conversion operator template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #3 from Matthijs van Duin --- First off, your example is more complicated than it needs to be. A more minimal test case would be: #include struct Dest { Dest() = default; Dest( Dest && ) = default; Dest( Dest const & ) = delete; }; struct Source { Dest val; operator Dest () && { return std::move( val ); } operator Dest const & () const & { return val; } }; int main() { Source x; static_cast( std::move( x ) ); } Second, notice that the two conversions are not really directly comparable since one converts to directly Dest while the other converts to an expression used to invoke a constructor of Dest. While it seems desirable for the former to take preference over the latter, I'm not enough of a language lawyer to be able to figure out what the C++ standard actually requires overload resolution to do in this situation. Replacing operator Dest () && { by operator Dest && () && { fixes the problem, and has the additional benefit of avoiding unnecessary temporary materialization in situations like: void foo( Dest && ); int main() { Source x; foo( std::move( x ) ); }
[Bug c++/51253] [C++11][DR 1030] Evaluation order (sequenced-before relation) among initializer-clauses in braced-init-list
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253 --- Comment #25 from Matthijs van Duin --- I wasn't referring to the warnings though but incorrect code generation. Since is exhibited by pretty trivial test cases (testsuite/g++.dg/cpp0x/initlist86.C confirms that { i++, i++ } works but the analogous test for { ++i, ++i } fails) yet was first reported long after this bug was marked "FIXED" I kind of assumed it was a regression, but apparently it was just never really fixed to begin with.
[Bug c++/70792] Incorrect sequence point warning with uniform initializer syntax
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70792 --- Comment #8 from Matthijs van Duin --- (In reply to Matthijs van Duin from comment #4) > return std::pair{ ++i, ++i }.first; My bad! This isn't an exhibit of the bug. I simply forgot that std::pair is not really a struct, and this isn't aggregate initialization: the constructor takes references, so correct code is generated in this case. And in fact, if you do use an aggregate, the test works correctly. However, if you replace std::pair by a class whose constructor takes (int, int), similar to the one used in the existing testcase (g++.dg/cpp0x/initlist86.C) then it fails again. Looking at the disassembly (on ARM since I don't know x86 asm) shows that gcc loads both arguments from the storage allocated for i, after both increments have been done. Effectively it's copy-constructing the first argument too late. The more general issue appears to be that if the arguments are trivially copyable lvalues, then gcc keeps these as lvalues and copy-constructs the actual arguments way too late. If I look at this disassembly of this code: struct Foo { char x[64]; // too big to pass in register Foo( Foo const ) = default; // but still trivially copyable Foo (); }; struct Pair { Pair( Foo x, Foo y ); }; void test( Foo ) { Pair{ foo.mutate(), foo.mutate() }; } Then test() effectively does: Foo = foo.mutate(); Foo = foo.mutate(); Pair{ temp1, temp2 } // copy-construct arguments and call Pair constructor (Also, interestingly, temp2 is copy-constructed before temp1 is!) If Foo is not trivially copyable, even if merely due to the presence of a destructor, then the problem disappears.
[Bug c++/83028] Incorrect -Wsequence-point warning in correct C++17 code with new evaluation order rules
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83028 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #1 from Matthijs van Duin --- There are many such cases which are well-defined in C++17 yet trigger a sequence-point warning in g++ 8.2, such as: (x+i)[i++] i = i++ (funcs[i++])(i) This incorrect behaviour is actually documented: "The C++17 standard will define the order of evaluation of operands in more cases: in particular it requires that the right-hand side of an assignment be evaluated before the left-hand side, so the above examples are no longer undefined. But this warning will still warn about them, to help people avoid writing code that is undefined in C and earlier revisions of C++." This reasoning here is of course complete garbage. Plenty of valid C++17 code is invalid in earlier revisions of the standard. When compiling code with -std=c++17 or -std=gnu++17, the compiler should only concern itself with whether the code is valid C++17 code. Since I think habitually ignoring warnings is very bad practice and compile with -Werror to ensure this won't happen, I consider these warnings to be nearly as bad as miscompilation, as the end result is the same: I still cannot rely on this feature of the C++17 standard.
[Bug c++/70792] Incorrect sequence point warning with uniform initializer syntax
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70792 --- Comment #7 from Matthijs van Duin --- Ah! I should have checked the actual tests of 51253 before calling it a regression, apologies. I just kinda assumed that these simple cases would be covered by the work done back then.
[Bug c++/51253] [C++11][DR 1030] Evaluation order (sequenced-before relation) among initializer-clauses in braced-init-list
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #23 from Matthijs van Duin --- There appears to be a regression of this bug. See bug 70792.
[Bug c++/70792] Incorrect sequence point warning with uniform initializer syntax
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70792 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #4 from Matthijs van Duin --- It seems bug 51253 previously addressed this, which means this is a regression. Also bug 65866 exists for the warning itself. I can confirm incorrect code generation using g++ 8.2.0 on this simpler testcase: #include int main() { int i = -1; return std::pair{ ++i, ++i }.first; } $ g++ -Wall -std=c++17 -o list-init-sequence{,.cc} list-init-sequence.cc: In function ‘int main()’: list-init-sequence.cc:6:20: warning: operation on ‘i’ may be undefined [-Wsequence-point] return std::pair{ ++i, ++i }.first; ^~~ $ ./list-init-sequence || echo fail fail Interestingly, this variation does not produce a warning but still produces incorrect code: #include int main() { int i = 0; return std::pair{ i, ++i }.first; } $ g++ -Wall -std=c++17 -o list-init-sequence{,.cc} $ ./list-init-sequence || echo fail fail
[Bug target/82989] [7/8 regression] Inexplicable use of NEON for 64-bit math
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82989 --- Comment #15 from Matthijs van Duin --- (In reply to Wilco from comment #14) > Yes on older cores it can be a bad idea to allow accidental use of Neon > instructions. The simplest workaround is to switch off Neon, just use > -mfpu=vfp. Sure, though that's not exactly ideal since it is very desirable for the Neon unit to be used for single-precision floats. (9-10 cycles for add/sub in VFP, 10-12 cycles for mul in VFP, 1 cycle for two add/sub/mul ops in Neon)
[Bug target/82989] [7/8 regression] Inexplicable use of NEON for 64-bit math
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82989 --- Comment #13 from Matthijs van Duin --- In case it's of interest, I did a quick benchmark of my testcase executed in a loop on a cortex-a8: Without neon: 12 instructions/iteration 14 cycles/iteration With neon: 14 instructions/iteration 35.2-35.3 cycles/iteration (This includes 4 instructions for the loop itself.) When using neon, the majority of the time is spent in a nasty pipeline stall for moving data from neon registers to arm registers, which takes a minimum of 20 cycles according to the cortex-a8 TRM.
[Bug target/82989] [7/8 regression ] Inexplicable use of NEON for 64-bit math
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82989 --- Comment #9 from Matthijs van Duin --- I can still reproduce the same test case with: arm-linux-gnueabihf-gcc-8 (Debian 8-20180207-2) 8.0.1 20180207 (experimental) [trunk revision 257435] -mfloat-abi=hard is implicit for arm-linux-gnueabihf, although overriding that to -mfloat-abi=softfp produces exactly the same result for me. (-mfloat-abi=soft completely disables all use of VFP/Neon hence obviously suppresses this problem.)
[Bug target/49526] extra move instruction for smmul
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49526 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #5 from Matthijs van Duin --- So... what happened to this patch? Why was it never applied?
[Bug target/82989] New: Inexplicable use of NEON for 64-bit math
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82989 Bug ID: 82989 Summary: Inexplicable use of NEON for 64-bit math Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: matthijsvanduin at gmail dot com Target Milestone: --- The following function: void foo( uint64_t *a ) { *a += *a >> 32; } compiled with arm-linux-gnueabihf-gcc -mcpu=cortex-a8 -mfpu=neon -O2 produces the following code: push {r4, r5} ldrd r4, [r0] vmov d16, r4, r5 vshr.u64 d16, d16, #32 vmov r2, r3, d16 adds r2, r2, r4 adcs r3, r3, r5 strd r2, [r0] pop {r4, r5} bxlr Since -mneon-for-64bits is not enabled (I double-checked using -Q just to be sure), the use of neon instructions here is highly unexpected. (Moreover, shifting right by 32 bits should of course not involve any actual arithmetic whatsoever. Ideally this function would compile to ldrd r2, [r0] adds r2, r2, r3 adcs r3, r3, #0 strd r2, [r0] bxlr )
[Bug c++/80061] error on constexpr function with an unevaluated throw
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80061 --- Comment #2 from Matthijs van Duin --- > void foo( bool ok ) { ^constexpr
[Bug c++/80061] error on constexpr function with an unevaluated throw
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80061 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #1 from Matthijs van Duin --- Simpler test case: void foo( bool ok ) { if( ok ) return; throw; } fails to compile with g++ 6.3.0 and g++ 7.1.0
[Bug c++/67371] Never executed "throw" in constexpr function fails to compile
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67371 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #13 from Matthijs van Duin --- This is still not working for me in g++ 6 and 7: constexpr void foo( bool ok ) { if( ok ) return; throw; } In function ‘constexpr void foo(bool)’: error: expression ‘’ is not a constant-expression Rewriting the code as: constexpr void foo( bool ok ) { if( ok ) return; else throw; } gets rid of the error, but this can be really awkward to do in more complicated functions.
[Bug c++/59832] [c++11] ICE in reshape_init_class with initializer list
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59832 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #13 from Matthijs van Duin --- I also just ran into this one with g++ 6.2.1. Here are some interesting cases: union Foo { union { int x; char y; } u; union { int x; char y; } v; int n; }; std::vector foo = { {}, // ok { .u = {} },// ok { .u = { .x = {} } }, // ok { .u = { .x = 0 } },// ok { .u = { .y = {} } }, // ICE in reshape_init_class { .u = { .y = 0 } },// ICE in reshape_init_class { .v = {} },// ok { .v = { .x = {} } }, // ICE in reshape_init_class { .v = { .x = 0 } },// ICE in reshape_init_class { .v = { .y = {} } }, // ICE in reshape_init_class { .v = { .y = 0 } },// ICE in reshape_init_class { .n = {} },// ok { .n = 0 }, // error: could not convert }; Some more observations: - Replacing the inner unions by structs results in the same errors (in addition to some warnings for missing initializers) - No errors occur if a C-style array is initialized instead of std::vector - It doesn't matter if the inner aggregates are anonymous or not. Similar things with an outer struct: struct Bar { union { int x; char y; } u; union { int x; char y; } v; }; std::vector bar = { { .u = {}, .v = {} }, // ok { .u = {}, .v = { .x = 0 } }, // ok // { .u = {}, .v = { .y = 0 } }, // ICE in reshape_init_class { .u = { .x = 0 }, .v = {} }, // ok // { .u = { .y = 0 }, .v = {} }, // ICE in reshape_init_class // { .v = { .x = 0 }, .u = {} }, // ICE in reshape_init_class // { .v = {}, .u = { .x = 0 } }, // ICE in reshape_init_class // { .v = {}, .u = {} }, // sorry, unimplemented };
[Bug middle-end/50481] builtin to reverse the bit order
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50481 Matthijs van Duin changed: What|Removed |Added CC||matthijsvanduin at gmail dot com --- Comment #3 from Matthijs van Duin --- Bump! Proper intrinsics for bitreverse would be much appreciated! A plain C implementation is ugly and results in equally awful code output, while using inline asm breaks portability and can't be constant-folded or used in constexpr. What makes the continued lack of a __builtin_arm_rbit() in gcc a bit bizarre is that the (identically named) Neon versions of this instruction on AArch64 actually *did* receive proper intrinsics! [1] It's worth mentioning that clang does support __builtin_arm_rbit(), and they've actually generalized this to a full set of target-independent bitreverse builtins [2]. [1] https://gcc.gnu.org/ml/gcc-patches/2014-08/msg01913.html [2] http://clang.llvm.org/docs/LanguageExtensions.html#builtin-bitreverse
[Bug c++/67625] New: some constexpr expressions rejected as enumerator value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67625 Bug ID: 67625 Summary: some constexpr expressions rejected as enumerator value Product: gcc Version: 5.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: matthijsvanduin at gmail dot com Target Milestone: --- GCC 5.2.1 rejects the following code (with -std=gnu++11 or later): constexpr uint16_t bswap16( uint16_t x ) { return __builtin_bswap16( x ); } constexpr int foo_1 = bswap16(1); enum { foo_2 = foo_1 }; enum { foo_3 = __builtin_bswap16(1) }; enum { foo_4 = bswap16(1) }; with the error message "enumerator value for ‘foo_4’ is not an integer constant", while the other three definitions of the same constant are accepted. This is a regression w.r.t. 4.9.3