https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128085
--- Comment #2 from Yongqiang Tian <yqtian668 at gmail dot com> ---
Here is a reduced testcase for a related IPA mod-ref failure that does not
require tree DSE.
```cpp
#include <cstdint>
static volatile std::uint32_t in[] = {3930904508u, 794715835u, 3605755973u,
2030568436u, 3735579456u, 739780077u, 1244048879u, 3501940365u};
static std::uint32_t checksum = 0, trace = 0;
static void mix(std::uint32_t v) { checksum = checksum * 31u + v; }
static void event(std::uint32_t e) { trace = trace * 31u + e; }
struct C0 {
std::uint32_t x0 = in[5] ^ 307410468u;
C0() { mix(static_cast<C0&>(*this).f0(in[2])); }
virtual ~C0() {}
virtual std::uint32_t f0(std::uint32_t a) { return x0 * 573u + 357u + a; }
virtual C0* s1() { return this; }
};
struct C1 : virtual C0 {
std::uint32_t x1 = 636967657u;
std::uint32_t x2 = 2467334473u;
C1() { event(257u); }
C1* s1() override { return this; }
};
namespace {
struct C3 final : virtual C0, virtual C1 {
C3* s1() override { return this; }
};
}
int main() {
C1* o2 = new C3;
std::uint32_t v = static_cast<C1&&>(C3()).s1()->f0(0u);
mix(v);
delete o2;
}
```
```text
g++ -std=c++14 -O2 testcase.cpp -o test
./test
```
**Actual behavior:** The executable terminates with SIGSEGV. Adding
`-fno-tree-dse` does not
change the result.
**Expected behavior:** The executable should exit normally. The `C3()` prvalue
remains alive for
the full expression, and the virtual calls operate on its constructed `C1` and
`C0` subobjects.
Adding `-fno-ipa-modref` or `-fno-strict-aliasing` makes the executable exit
normally. GCC 10 also
exits normally; GCC 11 through GCC 16 and the trunk compiler below fail at
`-O2`.
The exact first bad commit is r11-3308-gd119f34c952f, "New modref/ipa_modref
optimization passes".
Its parent `2fe5b7d1f664` exits normally, while `d119f34c952f` segfaults.
Immediately before `fre3`, `main` still contains the zero-initialization,
constructor call, and
vptr read in the correct order:
```text
D.3112 = {};
C3::C3 (&D.3112);
vtableaddr = MEM[&D.3112 + 24B];
```
During `fre3`, GCC reports that `C3::C3(&D.3112)` does not clobber the vptr
read because the read
has alias sets `10->10`. The propagated constructor summary records the vptr
store at bit offset
192 under alias sets `9->2`. FRE then replaces `vtableaddr` with the
zero-initialization value and
produces this load:
```text
MEM[(int (*)()) *)0B + -32B]
```
The preprocessed attachment reproduces the same SIGSEGV. Verified with GCC
trunk commit
`8cc6e7178c2e3b6156d7992bd18285be0da3c92c`.