llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.41k stars 12.15k forks source link

llvm.vscale.i64 not lowered to a constant #56207

Open programmerjake opened 2 years ago

programmerjake commented 2 years ago

iirc the call to llvm.vscale.i64 should be lowered to a constant as part of legalization since x86_64 doesn't support scalable vectors, instead, instruction selection fails: https://llvm.godbolt.org/z/q987oTf94

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i64 @f() {
  %1 = call i64 @llvm.vscale.i64()
  ret i64 %1
}

declare i64 @llvm.vscale.i64()
# Compilation provided by Compiler Explorer at https://godbolt.org/
<Compilation failed>
# Compiler exited with result code 70
Standard error:
fatal error: error in backend: Cannot select: t2: i64 = vscale Constant:i64<1>
  t1: i64 = Constant<1>
In function: f
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: /opt/compiler-explorer/clang-assertions-trunk/bin/clang++ -g -o /app/output.s -masm=intel -S -x ir -fcolor-diagnostics -fno-crash-diagnostics <source>
1.  Code generation
2.  Running pass 'Function Pass Manager' on module '<source>'.
3.  Running pass 'X86 DAG->DAG Instruction Selection' on function '@f'
 #0 0x000056254f40801f PrintStackTraceSignalHandler(void*) Signals.cpp:0:0
 #1 0x000056254f405d44 llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3c05d44)
 #2 0x000056254f3437ff llvm::CrashRecoveryContext::HandleExit(int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3b437ff)
 #3 0x000056254f3fe61e llvm::sys::Process::Exit(int, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3bfe61e)
 #4 0x000056254cc55123 LLVMErrorHandler(void*, char const*, bool) cc1_main.cpp:0:0
 #5 0x000056254f34c15f llvm::report_fatal_error(llvm::Twine const&, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3b4c15f)
 #6 0x00005625503a90f4 llvm::SelectionDAGISel::CannotYetSelect(llvm::SDNode*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4ba90f4)
 #7 0x00005625503a98f2 llvm::SelectionDAGISel::SelectCodeCommon(llvm::SDNode*, unsigned char const*, unsigned int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4ba98f2)
 #8 0x000056254df1bdd7 (anonymous namespace)::X86DAGToDAGISel::Select(llvm::SDNode*) X86ISelDAGToDAG.cpp:0:0
 #9 0x00005625503a755a llvm::SelectionDAGISel::DoInstructionSelection() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4ba755a)
#10 0x00005625503b02d7 llvm::SelectionDAGISel::CodeGenAndEmitDAG() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4bb02d7)
#11 0x00005625503b3a4a llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4bb3a4a)
#12 0x00005625503b59e2 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (.part.1063) SelectionDAGISel.cpp:0:0
#13 0x000056254df280e5 (anonymous namespace)::X86DAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) X86ISelDAGToDAG.cpp:0:0
#14 0x000056254e663026 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x2e63026)
#15 0x000056254eb557c6 llvm::FPPassManager::runOnFunction(llvm::Function&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x33557c6)
#16 0x000056254eb55b19 llvm::FPPassManager::runOnModule(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3355b19)
#17 0x000056254eb56479 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3356479)
#18 0x000056254f77ce25 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f7ce25)
#19 0x00005625504dcd3b clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4cdcd3b)
#20 0x000056254fe506c9 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x46506c9)
#21 0x000056254fdea53a clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x45ea53a)
#22 0x000056254ff1de73 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x471de73)
#23 0x000056254cc564b1 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x14564b1)
#24 0x000056254cc4f639 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
#25 0x000056254fc7d145 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#26 0x000056254f343643 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3b43643)
#27 0x000056254fc7f4d6 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x447f4d6)
#28 0x000056254fc4deb3 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x444deb3)
#29 0x000056254fc4eb13 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x444eb13)
#30 0x000056254fc592cc clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x44592cc)
#31 0x000056254cc5477c clang_main(int, char**) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x145477c)
#32 0x00007f23bf7ce0b3 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b3)
#33 0x000056254cc4eeaa _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x144eeaa)
clang-15: error: clang frontend command failed with exit code 70 (use -v to see invocation)
llvmbot commented 2 years ago

@llvm/issue-subscribers-backend-x86

phoebewang commented 2 years ago

Do you mean such code: https://github.com/llvm/llvm-project/blob/main/llvm/lib/CodeGen/CodeGenPrepare.cpp#L2252-L2267 ?

It looks to me the lower to constant still requires the target supports scalable vectors. In a word, this intrinsic should be called at all on X86.

programmerjake commented 2 years ago

Do you mean such code: https://github.com/llvm/llvm-project/blob/main/llvm/lib/CodeGen/CodeGenPrepare.cpp#L2252-L2267 ?

Yes, something like that.

It looks to me the lower to constant still requires the target supports scalable vectors. In a word, this intrinsic should be called at all on X86.

Well, @rust-lang/project-portable-simd will most likely want a way to use scalable vectors on any target (since we're trying to make completely portable simd viable), with llvm and/or rustc converting it to some fallback code on targets that don't natively support scalable vectors.

workingjubilee commented 2 years ago

I think we can work around it, but it requires us to change our IR generation to get a lot more target-specific if/when we introduce scalable vector types, which is going to hurt our ability to diagnose optimization problems. And Vector Predication roadmap says that they intend to replace the masked intrinsics entirely, eventually, with VP intrinsics, and those are designed to work with vscale and an effective vector length. Though they don't require the former, and the latter notes, somewhat cryptically (to me):

Some targets, such as AVX512, do not support the %evl parameter in hardware. The use of an effective %evl is discouraged for those targets. The function TargetTransformInfo::hasActiveVectorLength() returns true when the target has native support for %evl.