Bug type: crash
Component: VectorCombine
Bug location: llvm/lib/Transforms/Vectorize/VectorCombine.cpp: VectorCombine::foldShuffleToIdentity
Issue title: A/F: isa<To>(Val) && "cast<Ty>() argument of incompatible type!" after commit a4d1026
Labels: vectorizers
crash
Reported by: dyung

A few of our internal tests started hitting an assertion failure which I bisected back to commit a4d10266d20bfe5930dfed77e17832af341ed66e. 

Consider the following code:
```c++
template <typename a> a b(a);
typedef float c __attribute__((__vector_size__(32)));
typedef float __attribute__((ext_vector_type(8))) d;
typedef float __attribute__((ext_vector_type(4))) e;
c f;
#define g(h) (b(h))
d i;
void j() {
  c k = __builtin_ia32_rsqrtps256(f);
  d l(k);
  d m g(i);
  volatile e n = __builtin_shufflevector(l, m, 15, 2, 0, 1);
}
```
When compiled with optimizations and `-mavx` it hits an assertion failure:
```
$ ~/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang -c -O2 -mavx repro2.cpp                                                                                                                                                                                                                                                                                                                                                                                                             
clang: /home/dyung/src/upstream/llvm_clean_git/llvm/include/llvm/Support/Casting.h:578: decltype(auto) llvm::cast(From*) [with To = llvm::IntrinsicInst; From = llvm::Value]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.                                                                                                                                                                                                                                                                                                    
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: /home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang -c -O2 -mavx repro2.cpp
1.      <eof> parser at end of file
2.      Optimizer
 #0 0x0000557d533cfe2f llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x4055e2f)
 #1 0x0000557d533cd96c llvm::sys::CleanupOnSignal(unsigned long) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x405396c)
 #2 0x0000557d5331a4e8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f0ccbb8b420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007f0ccb65800b raise /build/glibc-e2p3jK/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #5 0x00007f0ccb637859 abort /build/glibc-e2p3jK/glibc-2.31/stdlib/abort.c:81:7
 #6 0x00007f0ccb637729 get_sysdep_segment_value /build/glibc-e2p3jK/glibc-2.31/intl/loadmsgcat.c:509:8
 #7 0x00007f0ccb637729 _nl_load_domain /build/glibc-e2p3jK/glibc-2.31/intl/loadmsgcat.c:970:34
 #8 0x00007f0ccb648fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #9 0x0000557d54cd0f88 (anonymous namespace)::VectorCombine::foldShuffleToIdentity(llvm::Instruction&)::'lambda3'(std::pair<llvm::Value*, int>)::operator()(std::pair<llvm::Value*, int>) const (.isra.0) VectorCombine.cpp:0:0
#10 0x0000557d54cdac11 (anonymous namespace)::VectorCombine::foldShuffleToIdentity(llvm::Instruction&) VectorCombine.cpp:0:0
#11 0x0000557d54ce56f1 (anonymous namespace)::VectorCombine::run()::'lambda'(llvm::Instruction&)::operator()(llvm::Instruction&) const (.isra.0) VectorCombine.cpp:0:0
#12 0x0000557d54ce695d llvm::VectorCombinePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x596c95d)
#13 0x0000557d547ca386 llvm::detail::PassModel<llvm::Function, llvm::VectorCombinePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x5450386)
#14 0x0000557d50a03b4c llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x1689b4c)
#15 0x0000557d52d96d0d llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x3a1cd0d)
#16 0x0000557d509e66d6 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x166c6d6)
#17 0x0000557d52d94b9d llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x3a1ab9d)
#18 0x0000557d5366aa28 (anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>&, std::unique_ptr<llvm::ToolOutputFile, std::default_delete<llvm::ToolOutputFile>>&, clang::BackendConsumer*) BackendUtil.cpp:0:0
#19 0x0000557d5366dd85 (anonymous namespace)::EmitAssemblyHelper::EmitAssembly(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) BackendUtil.cpp:0:0
#20 0x0000557d5366e449 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x42f4449)
#21 0x0000557d53cc97ca clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x494f7ca)
#22 0x0000557d55a3f65c clang::ParseAST(clang::Sema&, bool, bool) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x66c565c)
#23 0x0000557d53cc8278 clang::CodeGenAction::ExecuteAction() (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x494e278)
#24 0x0000557d53f56729 clang::FrontendAction::Execute() (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x4bdc729)
#25 0x0000557d53edc48e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x4b6248e)
#26 0x0000557d54040e86 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x4cc6e86)
#27 0x0000557d505e1bbc cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x1267bbc)
#28 0x0000557d505dacca ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#29 0x0000557d53d0d8ed void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#30 0x0000557d5331a9f0 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x3fa09f0)
#31 0x0000557d53d0df0f clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
#32 0x0000557d53cd2a4c clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x4958a4c)
#33 0x0000557d53cd34dd clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x49594dd)
#34 0x0000557d53cdb8f5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x49618f5)
#35 0x0000557d505defab clang_main(int, char**, llvm::ToolContext const&) (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x1264fab)
#36 0x0000557d504db96b main (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x116196b)
#37 0x00007f0ccb639083 __libc_start_main /build/glibc-e2p3jK/glibc-2.31/csu/../csu/libc-start.c:342:3
#38 0x0000557d505da79e _start (/home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin/clang+0x126079e)
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
clang version 19.0.0 (https://github.com/llvm/llvm-project.git a4d10266d20bfe5930dfed77e17832af341ed66e)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/dyung/src/upstream/a4d10266d20bfe5930dfed77e17832af341ed66e-linux/bin
Build config: +assertions
```


Fix patch:
commit d145f40963f15e94c4aefcc406a365fbe779e934
Author: David Green <david.green@arm.com>
Date:   Sun May 5 10:47:11 2024 +0100

    [VectorCombine] shuffleToIdentity - guard against call instructions.
    
    The shuffleToIdentity fold needs to be a bit more careful about the difference
    between call instructions and intrinsics. The second can be handled, but the
    first should result in bailing out. This patch also adds some extra intrinsic
    tests from #91000.
    
    Fixes #91078

diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 04d2ff594bf5..bbb70134870a 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -1755,10 +1755,13 @@ bool VectorCombine::foldShuffleToIdentity(Instruction &I) {
             return false;
           if (IL.first->getValueID() != Item[0].first->getValueID())
             return false;
+          if (isa<CallInst>(IL.first) && !isa<IntrinsicInst>(IL.first))
+            return false;
           auto *II = dyn_cast<IntrinsicInst>(IL.first);
           return !II ||
-                 II->getIntrinsicID() ==
-                     cast<IntrinsicInst>(Item[0].first)->getIntrinsicID();
+                 (isa<IntrinsicInst>(Item[0].first) &&
+                  II->getIntrinsicID() ==
+                      cast<IntrinsicInst>(Item[0].first)->getIntrinsicID());
         }))
       return false;
 


Regression tests:
file: llvm/test/Transforms/VectorCombine/AArch64/shuffletoidentity.ll
commands: opt -passes=vector-combine -S %s
tests: test_name: callinst
test_body: target triple = "aarch64"

define <8 x half> @callinst(<8 x half> %a) {
  %ab = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
  %at = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
  %abt = call <4 x half> @othercall(<4 x half> %at)
  %abb = call <4 x half> @llvm.fabs.v4f16(<4 x half> %ab)
  %r = shufflevector <4 x half> %abt, <4 x half> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
  ret <8 x half> %r
}

declare <4 x half> @othercall(<4 x half>)

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <4 x half> @llvm.fabs.v4f16(<4 x half>) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

test_name: callinst2
test_body: target triple = "aarch64"

define <8 x half> @callinst2(<8 x half> %a) {
  %ab = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
  %at = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
  %abt = call <4 x half> @llvm.fabs.v4f16(<4 x half> %at)
  %abb = call <4 x half> @othercall(<4 x half> %ab)
  %r = shufflevector <4 x half> %abt, <4 x half> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
  ret <8 x half> %r
}

declare <4 x half> @othercall(<4 x half>)

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <4 x half> @llvm.fabs.v4f16(<4 x half>) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

test_name: lrint
test_body: target triple = "aarch64"

define <8 x i32> @lrint(<8 x half> %a) {
  %ab = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
  %at = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
  %abt = call <4 x i32> @llvm.lrint.v4i32.v4f16(<4 x half> %at)
  %abb = call <4 x i32> @llvm.lrint.v4i32.v4f16(<4 x half> %ab)
  %r = shufflevector <4 x i32> %abt, <4 x i32> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
  ret <8 x i32> %r
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <4 x i32> @llvm.lrint.v4i32.v4f16(<4 x half>) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

test_name: abs_different
test_body: target triple = "aarch64"

define <8 x i8> @abs_different(<8 x i8> %a) {
  %ab = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
  %at = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
  %abt = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %at, i1 true)
  %abb = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %ab, i1 false)
  %r = shufflevector <4 x i8> %abt, <4 x i8> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
  ret <8 x i8> %r
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <4 x i8> @llvm.abs.v4i8(<4 x i8>, i1 immarg) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

test_name: powi
test_body: target triple = "aarch64"

define <8 x half> @powi(<8 x half> %a) {
  %ab = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
  %at = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
  %abt = call <4 x half> @llvm.powi.v4f16.i32(<4 x half> %at, i32 10)
  %abb = call <4 x half> @llvm.powi.v4f16.i32(<4 x half> %ab, i32 10)
  %r = shufflevector <4 x half> %abt, <4 x half> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
  ret <8 x half> %r
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <4 x half> @llvm.powi.v4f16.i32(<4 x half>, i32) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

test_name: abs
test_body: target triple = "aarch64"

define <8 x i8> @abs(<8 x i8> %a) {
  %ab = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
  %at = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
  %abt = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %at, i1 false)
  %abb = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %ab, i1 false)
  %r = shufflevector <4 x i8> %abt, <4 x i8> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
  ret <8 x i8> %r
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <4 x i8> @llvm.abs.v4i8(<4 x i8>, i1 immarg) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }