https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115033

            Bug ID: 115033
           Summary: Incorrect optimization of by-reference closure fields
                    by fre1 pass
           Product: gcc
           Version: 12.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sleepy.iron2888 at fastmail dot com
  Target Milestone: ---

## Description

I am seeing a wrong answer produced by code involving a by-reference captured
boolean value in a lambda. The code looks like the following:

```cpp
// Compute result shape
bool resultIsStatic = true;
auto resultShape = llvm::map_to_vector(newShape, [&](int64_t size) {
    // This branch is taken, but the update to resultIsStatic is not
    // propagated to the usage outside of the lambda.
    if (!inputIsStatic) {
      resultIsStatic = false;
      return ShapedType::kDynamic;
    }

        // do something else
});

// This branch is never taken
if (resultIsStatic) {
    // do the right thing
    return;
}

// do the wrong thing
return;
```

In the failing example, a lambda is mapped across a range of values, producing
a new vector-like container. During the map, the `resultIsStatic` value
captured by reference is updated in the lambda, and that updated value is not
reflected in the later usage of `resultIsStatic`.

## Analysis

The attached pre-processed source file is still large, so I just want to narrow
down where I think the problem is. The mal-optimization occurs in the
`inferReshapeExpandedType` function at the end of the pre-processed source
file.

Looking at the dumped IR, I believe the bug is introduced by the `fre1` pass. I
see between `ealias` and `fre1` that the branch on the value of
`resultIsStatic` is eliminated. This seems a likely cause for the bug I am
seeing, but I am not very familiar with GCC's IR.

## GCC Invocation

Full command producing the issue:

```
g++ -O2 -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden
-Werror=date-time -fno-lifetime-dse -Wall -Wextra -Wno-unused-parameter
-Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic
-Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-nonnull
-Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move
-Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment
-Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color
-ffunction-sections -fdata-sections -Wundef -O2 -std=c++17  -fno-exceptions
-funwind-tables -fno-rtti -c <source-file>
```

For reference, this bug is affecting parts of LLVM, the pull request with the
workaround and description of the problem can be found here:
https://github.com/llvm/llvm-project/pull/91521

## GCC -v and System Information

This bug is reproducible in GCC 12 and GCC 13. I was unable to reproduce in GCC
11.

The GCC versions below are taken from a NixOS machine used to reproduce the bug
and track it down. It also reproduces on Debian with GCC 12. I can provide that
information as well if it will be helpful.

GCC 12 `-v` output:

```
Using built-in specs.
COLLECT_GCC=/nix/store/7b2bbh09d569jb60j3vc5icjr3wdhw3m-gcc-12.3.0/bin/gcc
COLLECT_LTO_WRAPPER=/nix/store/7b2bbh09d569jb60j3vc5icjr3wdhw3m-gcc-12.3.0/libexec/gcc/x86_64-unknown-linux-gnu/12.3.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-12.3.0/configure
--prefix=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gcc-12.3.0
--with-gmp-include=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gmp-with-cxx-6.3.0-dev/include
--with-gmp-lib=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gmp-with-cxx-6.3.0/lib
--with-mpfr-include=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-mpfr-4.2.1-dev/include
--with-mpfr-lib=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-mpfr-4.2.1/lib
--with-mpc=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-libmpc-1.3.1
--with-native-system-header-dir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-glibc-2.39-31-dev/include
--with-build-sysroot=/
--with-gxx-include-dir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gcc-12.3.0/include/c++/12.3.0/
--program-prefix= --enable-lto --disable-libstdcxx-pch
--without-included-gettext --with-system-zlib --enable-static
--enable-languages=c,c++ --disable-multilib --enable-plugin
--with-isl=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-isl-0.20
--disable-bootstrap --build=x86_64-unknown-linux-gnu
--host=x86_64-unknown-linux-gnu --target=x86_64-unknown-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 12.3.0 (GCC)
```

GCC 13 `-v` output:

```
Using built-in specs.
COLLECT_GCC=/nix/store/9hgsinpfgyvsd92v0wlvmxv9wnaal68r-gcc-13.2.0/bin/gcc
COLLECT_LTO_WRAPPER=/nix/store/9hgsinpfgyvsd92v0wlvmxv9wnaal68r-gcc-13.2.0/libexec/gcc/x86_64-unknown-linux-gnu/13.2.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-13.2.0/configure
--prefix=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gcc-13.2.0
--with-gmp-include=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gmp-6.3.0-dev/include
--with-gmp-lib=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gmp-6.3.0/lib
--with-mpfr-include=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-mpfr-4.2.1-dev/include
--with-mpfr-lib=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-mpfr-4.2.1/lib
--with-mpc=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-libmpc-1.3.1
--with-native-system-header-dir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-glibc-2.39-31-dev/include
--with-build-sysroot=/
--with-gxx-include-dir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gcc-13.2.0/include/c++/13.2.0/
--program-prefix= --enable-lto --disable-libstdcxx-pch
--without-included-gettext --with-system-zlib --enable-static
--enable-languages=c,c++ --disable-multilib --enable-plugin --disable-libcc1
--with-isl=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-isl-0.20
--disable-bootstrap --build=x86_64-unknown-linux-gnu
--host=x86_64-unknown-linux-gnu --target=x86_64-unknown-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 13.2.0 (GCC)
```

Reply via email to