Heap corruption when allocating vectors consecutively under RVV

Summary

When compiling with RVV (-march=rv64gcv) and enabling Eigen’s RVV path (-DEIGEN_RISCV64_USE_RVV10), allocating a SparseMatrix followed by two VectorXd instances results in silent heap corruption: the first vector reports the wrong size (e.g., x.size() == -1) after the second is created.

Environment

  • Compiler: Clang 20.1
  • Operating System : Ubuntu
  • RISC-V 64-bit RVV
  • Eigen: MR !1687 (closed)
  • Compile Flags : -O1 -march=rv64gcv -mabi=lp64d -mrvv-vector-bits=128 -DEIGEN_RISCV64_USE_RVV10

Minimal Example


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

using namespace Eigen;
using namespace std;

int main() {
    constexpr int rows = 1138;
    constexpr int cols = 1138;

    // Step 1: Create an empty sparse matrix
    SparseMatrix<double> mat;
    mat.resize(rows, cols);
    mat.makeCompressed();  // nothing inserted — this still triggers RVV paths

    // Step 2: Allocate vector x
    VectorXd x = VectorXd::Ones(cols);
    cout << "After x allocation: x.size() = " << x.size() << endl;

    // Step 3: Allocate vector y
    VectorXd y(rows);
    cout << "After y allocation: y.size() = " << y.size() << endl;

    // Step 4: Check if x is still okay
    cout << "Checking x again: x.size() = " << x.size() << endl;
    assert(x.size() == cols);  // May fail under RVV if heap is corrupted
}

Steps to reproduce

  1. first step - compile: clang++ -O1 -march=rv64gcv -mabi=lp64d -mrvv-vector-bits=128 -DEIGEN_RISCV64_USE_RVV10 -I $HOME/eigen-rvv/ test.cpp -o test
  2. run: ./test

What is the current bug behavior?

when compiling with optimization (O1 or more) then when allocating two vectors consecutively, the value of the size of the first is ran over. the output is this: After x allocation: x.size() = 1138 After y allocation: y.size() = 1138 Checking x again: x.size() = 1138

What is the expected correct behavior?

the output should be this: After x allocation: x.size() = 1138 After y allocation: y.size() = 1138 Checking x again: x.size() = 1138

Edited by Or Avivi