Description
Issue
Today we scatter/gather all extract values of struct return types. Thats out of lock step with how we split the call. The fix is to check if the call was trivially vectorizable before. handling the extract element case.
Background
This is rather assert while we are doing
Scatterer::operator[]
and we are creatingCreateExtractElement
but Type is not a Vector but a Structure. Addinguadd.with.overflow
toisTriviallyScalarizable
is 'fixing' this.
Thats a bug. Adding to
isTriviallyScalarizable
is not the right fix. Whats going on is becauseuadd.with.overflow
isn't inisTriviallyScalarizable
we aren't splitting the calls so when we callScatterer Op0
it isn't operating on the right type. A correct fix wouldn't replace extract element unless we scalarized the call.
Test case:
define <3 x i32> @test_(<3 x i32> %a, <3 x i32> %b) {
%r = call { <3 x i32>, <3 x i1> } @llvm.uadd.with.overflow.v3i32(<3 x i32> %b, <3 x i32> %b)
%el = extractvalue { <3 x i32>, <3 x i1> } %r, 0
ret <3 x i32> %el
}
./build/bin/opt -passes='function(scalarizer)' ./build/test_fail.ll -S
opt: ./llvm-project/llvm/include/llvm/Support/Casting.h:578: decltype(auto) llvm::cast(From *) [To = llvm::VectorType, From = llvm::Type]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
Originally posted by @farzonl in #111569 (comment)