https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123351
Bug ID: 123351
Summary: [14/15 regression] mingw32 cross compile determinism
is architecture dependent
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: ipa
Assignee: unassigned at gcc dot gnu.org
Reporter: gnu.ojxq8 at dralias dot com
Target Milestone: ---
Created attachment 63186
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=63186&action=edit
Reproduce cross-compilation on two different architectures via podman and qemu
For reproducible builds, it is beneficial to have deterministic
cross-compilation even if the host architecture changes.
This works fine with x86_64-w64-mingw32-g++ version 13. However, since version
14, it looks regressed.
The issue originally happened in a module using std::filesystem, but the code
can be reduced to plain C++11:
==== Reproducer Code ====
#include <cstring> // Unused, but removing this makes it deterministic
#include <string>
#include <utility>
#include <vector>
struct Item {
Item(std::wstring path, std::string value)
: path(std::move(path)), value(std::move(value)) {}
std::wstring path;
std::string value;
};
bool has_new_paths();
std::vector<Item> Func() {
std::vector<Item> paths;
if (has_new_paths()) {
paths.emplace_back(std::wstring(), "a");
paths.emplace_back(std::wstring(), "aa");
paths.emplace_back(std::wstring(), "a");
paths.emplace_back(std::wstring(), "aa");
}
return paths;
}
==== End Reproducer ====
The reproducer command to be run on two different architectures (e.g.
linux/aarch64 and linux/amd64):
x86_64-w64-mingw32-g++ -Werror -O2 -g \
-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 \
-std=c++11 -fdump-tree-all -save-temps \
-ffile-prefix-map=/tmp=. -o /tmp/bar.o -c /tmp/bar.cpp \
&& sha256sum /tmp/bar.o
Reducing the optimization level, the debug level, or the fortify level makes
the non-determinism go away.
A bisect first leads to commit 1d82fc2e6824bf83159389729c31a942f7b91b04, which
changes the stdlib.
Since, I wanted to bisect GCC and not the stdlib, I ported the change over, and
ran bisect again. Then, it pointed to commit
53ba8d669550d3a1f809048428b97ca607f95cf5 from the day before.
This seems to indicate the non-determinism is triggered by IPA-VRP return value
propagation. Setting -fno-ipa-vrp makes the object file fully reproducible
again on different architectures.
Since it may be a bit tedious to reproduce, or port the interesting portion of
the vector change, I've uploaded:
* podman-reproduce.sh to use qemu instead of real harware.
* test.cpp the reproducer code with the vector changes ported.