NewGVN optimizes: define i1 @test({}** %arg, i1 %arg2) { br i1 %arg2, label %bb1, label %bb2 bb1: %load1 = load {}*, {}** %arg %cmp1 = icmp eq {}* %load1, null ret i1 %cmp1 bb2: %load2 = load {}*, {}** %arg, !nonnull !1 %cmp2 = icmp eq {}* %load2, null ret i1 %cmp2 } !1 = !{} into: define i1 @test({}** %arg, i1 %arg2) { br i1 %arg2, label %bb1, label %bb2 bb1: ; preds = %0 ret i1 false bb2: ; preds = %0 ret i1 false } The reason is that %load1 and %load2 are found congruent with %load2 chosen as leader. Thus %cmp1 in bb1 calls SimplifyCmp with icmp eq {}* %load2, null, which is simplified to i1 false based on the !nonnull metadata of %load2. However, this metadata is not applicable in this branch. This bug prevents bootstrapping of rustc under newgvn.
Proposed simple fix https://reviews.llvm.org/D47143
PR37660 covers a related case, where we have `shl i64 %1, 32` and `shl nsw i64 %1, 32` in a congruence class and we later simplify based on nsw, which does not hold for all members. Eli also indicated at https://reviews.llvm.org/D47143 that it would be good to fix those issues there too.
*** Bug 37660 has been marked as a duplicate of this bug. ***
Created attachment 20613 [details] IR case from PR37660, where nsw causes miscompile
*** Bug 38260 has been marked as a duplicate of this bug. ***
*** Bug 38214 has been marked as a duplicate of this bug. ***
*** Bug 38304 has been marked as a duplicate of this bug. ***
Thanks Florian for fixing this!