[Bug tree-optimization/113676] [12 Regression] Miscompilation tree-vrp __builtin_unreachable

2024-01-31 Thread magnus.hegdahl at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113676

--- Comment #2 from Magnus Hokland Hegdahl  ---
Hi, here's a version that doesn't need -std=c++20 or argv:

https://godbolt.org/z/Y9ooY998e

#include 

constexpr auto bit_ceil(unsigned x) -> unsigned {
if (x <= 1) return 1U;
int w = 32 - __builtin_clz(x - 1);
return 1U << w;
}

int main(int argc, char **) {
auto rounded_n = bit_ceil(static_cast(argc + 1));
auto a = std::vector(2UL * rounded_n);

for (std::size_t i = rounded_n; i-- > 1;) {
if (!(0 < i && i < rounded_n)) __builtin_unreachable();
a[i] = 0;
}
}

Exact compile command used with g++-12 (GCC) 12.3.0 on arch linux, x86_64:
g++-12 -O1 -ftree-vrp main.cpp

[Bug tree-optimization/113676] New: Miscompilation tree-vrp __builtin_unreachable

2024-01-30 Thread magnus.hegdahl at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113676

Bug ID: 113676
   Summary: Miscompilation tree-vrp __builtin_unreachable
   Product: gcc
   Version: 12.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: magnus.hegdahl at gmail dot com
  Target Milestone: ---

Compiling the following code with -O1 -ftree-vrp or higher on GCC 10 or 12
results in a program that segfaults when argc >= 2.

#include 
#include 

auto main(int argc, char **) -> int {
auto rounded_n = std::bit_ceil(static_cast(argc));
auto a = std::vector(2UL * rounded_n);

for (std::size_t i = rounded_n; i-- > 1;) {
if (!(0 < i && i < rounded_n)) __builtin_unreachable();
a[i] = 0;
}
}

If __builtin_unreachable is replaced by for example __builtin_trap, there is no
bug.
I could not reproduce this in GCC 11 or 13.

https://godbolt.org/z/dvEWKzWTh

Disassembly of the loop body:
.L6:
mov DWORD PTR [rdi+rdx*4], 0
sub rdx, 1
jmp .L6

[Bug c++/112795] [C++>=14] ICE pragma GCC unroll (n) cxx_eval_constant_expression

2023-11-30 Thread magnus.hegdahl at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112795

--- Comment #1 from Magnus Hokland Hegdahl  ---
Full output:
// Target: x86_64-pc-linux-gnu
// Configured with: /build/gcc/src/gcc/configure
--enable-languages=ada,c,c++,d,fortran,go,lto,objc,obj-c++ --enable-bootstrap
--prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/
--with-build-config=bootstrap-lto --with-linker-hash-style=gnu
--with-system-zlib --enable-__cxa_atexit --enable-cet=auto
--enable-checking=release --enable-clocale=gnu --enable-default-pie
--enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object
--enable-libstdcxx-backtrace --enable-link-serialization=1
--enable-linker-build-id --enable-lto --enable-multilib --enable-plugin
--enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch
--disable-werror
// Thread model: posix
// Supported LTO compression algorithms: zlib zstd
// gcc version 13.2.1 20230801 (GCC) 
// 
// mwe.cpp: In function ‘void f()’:
// mwe.cpp:5:21: internal compiler error: in cxx_eval_constant_expression, at
cp/constexpr.cc:7619
// 5 | #pragma GCC unroll(n)
//   | ^
// 0x1ad33c8 internal_error(char const*, ...)
//  ???:0
// 0x6b7b63 fancy_abort(char const*, int, char const*)
//  ???:0
// 0x711364 maybe_constant_value(tree_node*, tree_node*, mce_value)
//  ???:0
// 0x9443d0 c_common_parse_file()
//  ???:0
// Please submit a full bug report, with preprocessed source.
// Please include the complete backtrace with any bug report.
// See  for instructions.

// /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/cc1plus -quiet -D_GNU_SOURCE mwe.cpp
-quiet -dumpbase mwe.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -Wall
-Wextra -Wpedantic -freport-bug -o - -frandom-seed=0 -fdump-noaddr

# 0 "mwe.cpp"
# 0 ""
# 0 ""
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "" 2
# 1 "mwe.cpp"
constexpr int n = 1;

template 
void f() {
#pragma GCC unroll(n)
for (int i = 0; i != n; ++i) {
}
}

[Bug c++/112795] New: [C++>=14] ICE pragma GCC unroll (n) cxx_eval_constant_expression

2023-11-30 Thread magnus.hegdahl at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112795

Bug ID: 112795
   Summary: [C++>=14] ICE pragma GCC unroll (n)
cxx_eval_constant_expression
   Product: gcc
   Version: 8.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: magnus.hegdahl at gmail dot com
  Target Milestone: ---

Compiling the following code with GCC >= 8.1 (when #pragma GCC unroll was
added), and -std=c++14 or higher results in an internal compiler error:
```
constexpr int n = 1;
template 
void f() {
#pragma GCC unroll(n)
for (int i = 0; i != n; ++i) {
}
}
```

It does not fail if f is not a template, if n is not parenthesized, or if using
-std=c++11.

[Bug c++/110258] New: Undefined reference to intrinsic when taking function reference at namespace scope

2023-06-14 Thread magnus.hegdahl at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110258

Bug ID: 110258
   Summary: Undefined reference to intrinsic when taking function
reference at namespace scope
   Product: gcc
   Version: 13.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: magnus.hegdahl at gmail dot com
  Target Milestone: ---

Tested on g++ (GCC) 13.1.1 20230429 on Linux

```
#include 

// this doesn't work in GCC (but does in clang)
constexpr auto set1 = _mm_set1_epi32;

// this works
struct S {
  static constexpr auto set1 = _mm_set1_epi32;
};

int main() {
  // and this works
  _mm_set1_epi32(1);
}
```

output:
/usr/bin/ld: /tmp/ccaN0gLC.o:(.data.rel.ro+0x0): undefined reference to
`_mm_set1_epi32(int)'
collect2: error: ld returned 1 exit status

The code seems to work as expected with other function pointers,
even when defined in other translation units.
I've only seen the problem with intrinsics.

[Bug c++/109753] New: pragma GCC target stops std::vector from compiling

2023-05-05 Thread magnus.hegdahl at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109753

Bug ID: 109753
   Summary: pragma GCC target stops std::vector from compiling
   Product: gcc
   Version: 13.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: magnus.hegdahl at gmail dot com
  Target Milestone: ---

Tested on g++ (GCC) 13.1.1 20230429 on x86-64 Linux

The following code doesn't compile without also enabling the target using
compile flags (like -mavx2). It did compile in GCC 12.2.0.

#pragma GCC target("avx2")

#include 

int main() {
  std::vector a;
}

[Bug tree-optimization/109746] New: Fails removing redundant comparison in for loop over multiple variables, unless members of struct

2023-05-05 Thread magnus.hegdahl at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109746

Bug ID: 109746
   Summary: Fails removing redundant comparison in for loop over
multiple variables, unless members of struct
   Product: gcc
   Version: 13.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: magnus.hegdahl at gmail dot com
  Target Milestone: ---

Compiled with g++ (GCC) 13.1.1 20230429 on x86-64 Linux, with -O2 or higher.

In the code below, the comparisons with i are redundant because j is increasing
much faster.
GCC manages to optimize this away when i and j are members of some struct, but
not when they are just integers.

struct S {
  unsigned x;
};

unsigned f() {
  unsigned N = 1e9, x = 0;
  for (unsigned i = 3, j = 1; i < N && j < N; i += 2, j += 3)
x ^= i * j;
  return x;
}

unsigned g() {
  unsigned N = 1e9, x = 0;
  for (S i {3}, j {1}; i.x < N && j.x < N; i.x += 2, j.x += 3)
x ^= i.x * j.x;
  return x;
}

int main() {
  return f();
}