BUG: Using Eigen::DenseBase::Replicate and Eigen::exp together produce unexpected results

Summary

  • Calling Replicate on rvalue objects produces unexpected results.
  • Calling Eigen::exp produces side effects on unrelated code.

Environment

  • Operating System : Linux
  • Architecture : x64
  • Eigen Version : trunk
  • Compiler Version : GCC trunk / Clang trunk
  • Compile Flags : -Os -std=c++20 -Wall -Wextra -Werror -pedantic -pedantic-errors

Minimal Example

Trying to use Replicate and exp on rvalue objects

Compiler Explorer

#include <Eigen/Dense>
#include <iostream>

int main() {
  {
    std::cout << "The following works:\n";
    auto v = Eigen::Vector<float, 1>{1.f};
    std::cout << v << '\n';
    auto vec = Eigen::exp(v.replicate(3, 1).array());
    std::cout << vec << '\n';
  }
  {
    std::cout << "And the following doesn't work:\n";
    auto v = Eigen::Vector<float, 1>{1.f}.replicate(3, 1);
    std::cout << v << '\n';
    auto vec = Eigen::exp(v.array());
    std::cout << vec << '\n';
  }
  {
    std::cout << "And the following doesn't work also:\n";
    const auto getVector = [] { return Eigen::Vector<float, 1>{1.f}; };
    auto vec = Eigen::exp(getVector().replicate(3, 1).array());
    std::cout << vec << '\n';
  }
}

Commenting out some lines fixes the problem

Compiler Explorer

#include <Eigen/Dense>
#include <iostream>

int main() {
  {
    std::cout << "The following works:\n";
    auto v = Eigen::Vector<float, 1>{1.f};
    std::cout << v << '\n';
    auto vec = Eigen::exp(v.replicate(3, 1).array());
    std::cout << vec << '\n';
  }
  {
    std::cout << "And if I comment out the call to Eigen::exp, the following works:\n";
    auto v = Eigen::Vector<float, 1>{1.f}.replicate(3, 1);
    std::cout << v << '\n';
    // auto vec = Eigen::exp(v.array());
    // std::cout << vec << '\n';
  }
  {
    std::cout << "And the following starts to work also:\n";
    const auto getVector = [] { return Eigen::Vector<float, 1>{1.f}; };
    auto vec = Eigen::exp(getVector().replicate(3, 1).array());
    std::cout << vec << '\n';
  }
}

Steps to reproduce

  1. Open compiler explorer
  2. Select the latest version either GCC or Clang C++ compiler
  3. Apply compilation flags from the issue description
  4. Select Eigen trunk in the Libraries
  5. Paste code snippets from the issue

What is the current bug behavior?

  • The result of Replicate seems to be random when called on the rvalue object.
  • The behavior of Replicate depends on whether there are calls to Eigen::exp.
  • Eigen::exp produces side effects.

What is the expected correct behavior?

  • In all three cases Replicate should return the column-vector (3x1 matrix) where each element is equal to 1.
  • In all three cases the call to Eigen::exp should return the column-vector (3x1 matrix) where each element is equal to e (2.71828).

Relevant logs

The output of the first code snippet compiled with GCC

ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
The following works:
1
2.71828
2.71828
2.71828
And the following doesn't work:
-2.43781e+17
-2.43781e+17
-2.43781e+17
0
0
0
And the following doesn't work also:
0
0
0

The output of the first code snippet compiled with Clang

ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
The following works:
1
2.71828
2.71828
2.71828
And the following doesn't work:
7.47528e+19
7.47528e+19
7.47528e+19
inf
inf
inf
And the following doesn't work also:
inf
inf
inf

The output of the second code snippet (same of both compilers)

ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
The following works:
1
2.71828
2.71828
2.71828
And if I comment out the call to Eigen::exp, the following works:
1
1
1
And the following starts to work also:
2.71829
2.71829
2.71829