[TBAA][GVN] Miscompile due to incorrectly replacing pointer with undef #122537
Labels
llvm:GVN
GVN and NewGVN stages (Global value numbering)
miscompilation
TBAA
Type-Based Alias Analysis / Strict Aliasing
This is a relatively intertwinding bug and I think the best way to describe it is through chronological order:
At this moment RISC-V LLVM miscompiles 482.sphinx3 (and potentially 445.gobmk) when we enable VLS vectorization + LTO:
If we remove the
-mrvv-vector-bits=zvl
flag (i.e. not using VLS vectorization), the issue goes away. Here are what happened:-mrvv-vector-bits=zvl
, since we use a fixed VLEN all thellvm.vscale
intrinsic calls will go away. All kinds of code simplifications then kick in and make some of the functions smallerallocate2D
) that allocates and returns a 2D array. This is effectively how it got called and used:allocate2D
got inlinedb2, and b3 both originally belong to
allocate2D
: b3 mallocs the memory for row pointers in this 2D array and b2 initializes them (the code showed here is NOT what it actually did but merely demonstrating that it's using a loop to initialize the row pointers memory). b1 and b0, on the other hand, grab the first row from this 2D array and pass it tobar
.%r = call i32 @bar(ptr noundef %p)
will be turned into%r = call i32 @bar(ptr noundef undef)
. Which is of course incorrect.%p = load ptr, ptr %p0, align 8, !tbaa !6
. And for some reasons it only returns%p0 = call noalias ptr @malloc(i64 noundef %num)
as the only Def dependency and (incorrectly) ignoresstore ptr %src, ptr %p2, align 8, !tbaa !4
which might clobber%p0
. And sincemalloc
has theallockind("uninitialized")
attribute, loading unintialized content is, to my best understandingss, undefined behavior so the optimizer can replace it with whatever it wants, hence the undef value.store ptr %src, ptr %p2
and%p = load ptr, ptr %p0
have NoAlias, which is rare considered 90% of the time we expected MayAlias and also wrong -- it should return MayAlias for the potential clobber.and this is load instruction's tree:
And based on TBAA's rule, these two type descriptor graphs are indeed not alias.
Personally I think the TBAA tags are wrong.
: the tag for store instructions -- which represents storingvoid *
tovoid **
-- should probably be any pointer.The text was updated successfully, but these errors were encountered: