This is a fix for PR 28418.
opt never finishes compiling test/Transforms/GVN/fold-const-expr.ll when -gvn option is passed.
I added fold-const-expr.ll to the llvm regression test suite.
The problem is caused by the fact that GVN fails to fold a constant expression.
That expression gets expanded multiple times and ends up as a huge, exponentially growing (relative to the number of instructions in the BB) constant expression. This expression is too big for GVN to analyze, so this optimization pass never finishes.
For more details, see the analysis in the PR 28418.
Here is concise version:
The expression (i32 trunc (i128 bitcast (<4 x i32> <i32 234567891, i32 345678912, i32 456789123, i32 0> to i128) to i32) is the result of a GVN expansion, when a previously stored constant vector is partially reloaded (note that the store size does not match the load size).
We have a store of a full <4 x i32> vector;
// (<4 x i32> <i32 234567891, i32 345678912, i32 456789123, i32 0> to i128
later on we reload the first element of the vector.
// i32 234567891
The lack of knowledge about constant expressions currently forces GVN to canonicalize a partial reload into a sequence of `trunc + bitcast`.
The aforementioned expression should be constant folded to i32 234567891 by GVN.
Special thanks to Andrea DiBiagio for his help with the analysis/fix and to Rafael for his help with reducing an immense reproducer.