[Bug libstdc++/51850] debug mode for std::array and tr1::array
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51850 --- Comment #1 from Edward Rosten 2012-01-18 16:35:40 UTC --- Created attachment 26368 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26368 Adds bounds checking to std::array and tr1::array in debug mode. I've attached a patch which adds bounds checking to std::array (C++0x) and std::tr1::array. The std::array patch keeps operator[] as constexpr.
[Bug c++/108537] New: constexpr UB pointer dereference compiles if the dereferenced value is not used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108537 Bug ID: 108537 Summary: constexpr UB pointer dereference compiles if the dereferenced value is not used Product: gcc Version: 12.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at edwardrosten dot com Target Milestone: --- The following code compiles successfully: constexpr int a(){ int* b = new int[1]; int r= &b[100]-b; //UB b[100]; //UB delete[] b; return r; } template int N=0; int foo(){ return N; } b[100] is unconditionally undefined behaviour, even though the value is never used. Tested on a scattering of versions (10.3, 11.2, 12.2) with -std=c++2a -O2
[Bug c++/103429] New: Optimization of Auto-generated condition chain is not giving good lookup tables.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103429 Bug ID: 103429 Summary: Optimization of Auto-generated condition chain is not giving good lookup tables. Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at edwardrosten dot com Target Milestone: --- I've got come generated condition chains (using recursive templates) and am getting some odd/suboptimal optimization results. Code is provided below and with a godbolt link. In the first case (without a force inline), the compiler inlines the functions but does not perform condition chain optimization. In the second case (identical code but with force inline), it will optimize condition chains but only with exactly 5 elements. Otherwise it will end up with an if-else structure indexing optimized 5 element condition chains, and an if-else chain for anything spare. It only attempts the optimization from gcc 11 onwards, I checked on trunk too. Example: https://godbolt.org/z/c9xbPqq7r Here's the code: template void f(); constexpr int N=5; template static inline void f_dispatch(int i){ if constexpr (I == N) return; else if(i == I) f(); else f_dispatch(i); } template __attribute__((always_inline)) static inline void f_dispatch_always_inline(int i){ if constexpr (I == N) return; else if(i == I) f(); else f_dispatch_always_inline(i); } void run(int i){ f_dispatch<>(i); } void run_inline(int i){ f_dispatch_always_inline<>(i); }
[Bug tree-optimization/103429] Optimization of Auto-generated condition chain is not giving good lookup tables.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103429 --- Comment #2 from Edward Rosten --- It is doing if-to-switch, but only really with N=5, and only if force-inline is set. I think this are two problems, one is that you need to force-inline in order to trigger if-to-switch. The other problem is that the if-to-switch conversion triggered only works well for exactly 5 conditions, otherwise it uses a mix of converted and unconverted. It doesn't appear to be doing binary tree generation, more like linear search Here's the asm for N=7: run(int): ret run_inline(int): testedi, edi je .L13 cmp edi, 1 je .L14 cmp edi, 6 ja .L3 mov edi, edi jmp [QWORD PTR .L8[0+rdi*8]] .L8: .quad .L3 .quad .L3 .quad .L12 .quad .L11 .quad .L10 .quad .L9 .quad .L7 .L13: jmp void f<0>() .L7: jmp void f<6>() .L12: jmp void f<2>() .L11: jmp void f<3>() .L10: jmp void f<4>() .L9: jmp void f<5>() .L14: jmp void f<1>() .L3: ret Note, it's essentially doing: if(i==0) f<0>(); else if(i==1) f<1>(); else if(i > 6) return; else switch(i){ case 0: case 1: return; case 2: f<2>(); return; case 3: f<3>(); return; case 4: f<4>(); return; case 5: f<5>(); return; case 6: f<6>(); return; } It's not doing binary searches. For, e.g. N%5 == 1, the structure is more like: if(i==0) f<0>(); else if(i > 5){ if(i-5 > 4){ if(i-11>4){ if(i-16 > 4){ // and so on, linearly } else switch(i-16){ //... } } else switch(i-11){ //... } } else switch(i-6){ //... } } else switch(i){ case 0: return; case 1: f<1>(); return; case 2: f<2>(); return; case 3: f<3>(); return; case 4: f<4>(); return; case 5: f<5>(); return; }