This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] Custom type legalize i8/i16 UDIV/UREM/SDIV on RV64 so we can use divuw/remuw/divw.
ClosedPublic

Authored by craig.topper on Jan 24 2021, 4:16 PM.

Details

Summary

This makes our i8/i16 codegen more similar to the i32 codegen.

I've also added computeKnownBits support for DIVUW/REMUW so
that we can remove zero extending ANDs from the output. Without
this we end up turning DIVUW/REMUW back into DIVU/REMU via some
isel patterns.

Diff Detail

Event Timeline

craig.topper created this revision.Jan 24 2021, 4:16 PM
craig.topper requested review of this revision.Jan 24 2021, 4:16 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 24 2021, 4:16 PM
Herald added a subscriber: MaskRay. · View Herald Transcript
frasercrmck accepted this revision.Jan 25 2021, 2:17 AM

LGTM, though I'd prefer the linter's suggestion over that manually-formatted code. You might be able to improve it somewhat with choice use of parens?

This revision is now accepted and ready to land.Jan 25 2021, 2:17 AM
jrtc27 added inline comments.Jan 25 2021, 8:02 AM
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
2187

Do these do the right thing for 0 (which RISC-V defines as saturating)? Or do we not care because it's UB in the IR?

LGTM, though I'd prefer the linter's suggestion over that manually-formatted code. You might be able to improve it somewhat with choice use of parens?

Weirdly that came from clang-format. I just rebuilt it and double checked. Not sure if that means phabricator is using an older version of clang-format?

This revision was landed with ongoing or failed builds.Jan 25 2021, 10:57 AM
This revision was automatically updated to reflect the committed changes.
craig.topper added inline comments.Jan 25 2021, 11:05 AM
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
2187

I think they do the right thing, but I've added a note that the behavior is undefined so we don't have to worry about someone changing the KnownBits implementation in the future. If we find a use case for making them not undefined, we can revisit.

This patch causes issues with building the Linux kernel. cvise spits out:

$ cat pci.i
char pci_cache_line_size, pci_set_cacheline_size_dev_cacheline_size;
pci_set_cacheline_size_dev() {
  if (pci_set_cacheline_size_dev_cacheline_size % pci_cache_line_size)
    return 0;
  return 2;
}

$ clang -O2 --target=riscv64-linux-gnu -c -o /dev/null pci.i
clang: /home/nathan/cbl/github/tc-build/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:5744: llvm::SDValue llvm::SelectionDAG::getNode(unsigned int, const llvm::SDLoc &, llvm::EVT, llvm::SDValue, llvm::SDValue, llvm::SDValue, const llvm::SDNodeFlags): Assertion `N1.getValueType() == N2.getValueType() && "SETCC operands must have the same type!"' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: /home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang -O2 --target=riscv64-linux-gnu -c -o /dev/null pci.i
1.      <eof> parser at end of file
2.      Code generation
3.      Running pass 'Function Pass Manager' on module 'pci.i'.
4.      Running pass 'RISCV DAG->DAG Pattern Instruction Selection' on function '@pci_set_cacheline_size_dev'
 #0 0x00000000029a6673 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x29a6673)
 #1 0x00000000029a443e llvm::sys::RunSignalHandlers() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x29a443e)
 #2 0x00000000029a5a0d llvm::sys::CleanupOnSignal(unsigned long) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x29a5a0d)
 #3 0x0000000002935ea3 (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2935ea3)
 #4 0x0000000002935fde CrashRecoverySignalHandler(int) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2935fde)
 #5 0x00007f27c68973c0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x153c0)
 #6 0x00007f27c635c18b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4618b)
 #7 0x00007f27c633b859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x25859)
 #8 0x00007f27c633b729 (/lib/x86_64-linux-gnu/libc.so.6+0x25729)
 #9 0x00007f27c634cf36 (/lib/x86_64-linux-gnu/libc.so.6+0x36f36)
#10 0x0000000003855672 llvm::SelectionDAG::getNode(unsigned int, llvm::SDLoc const&, llvm::EVT, llvm::SDValue, llvm::SDValue, llvm::SDValue, llvm::SDNodeFlags) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3855672)
#11 0x00000000038e3ac1 llvm::DAGTypeLegalizer::PromoteIntRes_SETCC(llvm::SDNode*) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x38e3ac1)
#12 0x00000000038e04ca llvm::DAGTypeLegalizer::PromoteIntegerResult(llvm::SDNode*, unsigned int) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x38e04ca)
#13 0x0000000003892b61 llvm::DAGTypeLegalizer::run() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3892b61)
#14 0x0000000003898985 llvm::SelectionDAG::LegalizeTypes() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3898985)
#15 0x0000000003880a97 llvm::SelectionDAGISel::CodeGenAndEmitDAG() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3880a97)
#16 0x000000000387f5c9 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x387f5c9)
#17 0x000000000387c287 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x387c287)
#18 0x0000000001ec42dd llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x1ec42dd)
#19 0x0000000002300ba8 llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2300ba8)
#20 0x0000000002307381 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2307381)
#21 0x00000000023011cc llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x23011cc)
#22 0x0000000002bdff36 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::DataLayout const&, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream> >) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2bdff36)
#23 0x000000000343d5fc clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x343d5fc)
#24 0x0000000003b62a24 clang::ParseAST(clang::Sema&, bool, bool) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3b62a24)
#25 0x00000000033a15f0 clang::FrontendAction::Execute() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x33a15f0)
#26 0x00000000032fd85a clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x32fd85a)
#27 0x00000000034375b8 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x34375b8)
#28 0x000000000183851b cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x183851b)
#29 0x0000000001836432 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x1836432)
#30 0x00000000031abbd2 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::$_1>(long) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x31abbd2)
#31 0x0000000002935db7 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2935db7)
#32 0x00000000031ab2e7 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x31ab2e7)
#33 0x0000000003172495 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&) const (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3172495)
#34 0x0000000003172787 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) const (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3172787)
#35 0x000000000318bb38 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x318bb38)
#36 0x0000000001835d8d main (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x1835d8d)
#37 0x00007f27c633d0b3 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b3)
#38 0x000000000183325e _start (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x183325e)
clang-12: error: clang frontend command failed with exit code 134 (use -v to see invocation)
ClangBuiltLinux clang version 12.0.0 (https://github.com/llvm/llvm-project b208e5bcd0be5ffb6346b1eab30ad372782bbe4b)
Target: riscv64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/nathan/cbl/github/tc-build/build/llvm/stage1/bin
clang-12: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.

This patch causes issues with building the Linux kernel. cvise spits out:

$ cat pci.i
char pci_cache_line_size, pci_set_cacheline_size_dev_cacheline_size;
pci_set_cacheline_size_dev() {
  if (pci_set_cacheline_size_dev_cacheline_size % pci_cache_line_size)
    return 0;
  return 2;
}

$ clang -O2 --target=riscv64-linux-gnu -c -o /dev/null pci.i
clang: /home/nathan/cbl/github/tc-build/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:5744: llvm::SDValue llvm::SelectionDAG::getNode(unsigned int, const llvm::SDLoc &, llvm::EVT, llvm::SDValue, llvm::SDValue, llvm::SDValue, const llvm::SDNodeFlags): Assertion `N1.getValueType() == N2.getValueType() && "SETCC operands must have the same type!"' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: /home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang -O2 --target=riscv64-linux-gnu -c -o /dev/null pci.i
1.      <eof> parser at end of file
2.      Code generation
3.      Running pass 'Function Pass Manager' on module 'pci.i'.
4.      Running pass 'RISCV DAG->DAG Pattern Instruction Selection' on function '@pci_set_cacheline_size_dev'
 #0 0x00000000029a6673 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x29a6673)
 #1 0x00000000029a443e llvm::sys::RunSignalHandlers() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x29a443e)
 #2 0x00000000029a5a0d llvm::sys::CleanupOnSignal(unsigned long) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x29a5a0d)
 #3 0x0000000002935ea3 (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2935ea3)
 #4 0x0000000002935fde CrashRecoverySignalHandler(int) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2935fde)
 #5 0x00007f27c68973c0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x153c0)
 #6 0x00007f27c635c18b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4618b)
 #7 0x00007f27c633b859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x25859)
 #8 0x00007f27c633b729 (/lib/x86_64-linux-gnu/libc.so.6+0x25729)
 #9 0x00007f27c634cf36 (/lib/x86_64-linux-gnu/libc.so.6+0x36f36)
#10 0x0000000003855672 llvm::SelectionDAG::getNode(unsigned int, llvm::SDLoc const&, llvm::EVT, llvm::SDValue, llvm::SDValue, llvm::SDValue, llvm::SDNodeFlags) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3855672)
#11 0x00000000038e3ac1 llvm::DAGTypeLegalizer::PromoteIntRes_SETCC(llvm::SDNode*) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x38e3ac1)
#12 0x00000000038e04ca llvm::DAGTypeLegalizer::PromoteIntegerResult(llvm::SDNode*, unsigned int) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x38e04ca)
#13 0x0000000003892b61 llvm::DAGTypeLegalizer::run() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3892b61)
#14 0x0000000003898985 llvm::SelectionDAG::LegalizeTypes() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3898985)
#15 0x0000000003880a97 llvm::SelectionDAGISel::CodeGenAndEmitDAG() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3880a97)
#16 0x000000000387f5c9 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x387f5c9)
#17 0x000000000387c287 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x387c287)
#18 0x0000000001ec42dd llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x1ec42dd)
#19 0x0000000002300ba8 llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2300ba8)
#20 0x0000000002307381 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2307381)
#21 0x00000000023011cc llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x23011cc)
#22 0x0000000002bdff36 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::DataLayout const&, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream> >) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2bdff36)
#23 0x000000000343d5fc clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x343d5fc)
#24 0x0000000003b62a24 clang::ParseAST(clang::Sema&, bool, bool) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3b62a24)
#25 0x00000000033a15f0 clang::FrontendAction::Execute() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x33a15f0)
#26 0x00000000032fd85a clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x32fd85a)
#27 0x00000000034375b8 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x34375b8)
#28 0x000000000183851b cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x183851b)
#29 0x0000000001836432 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x1836432)
#30 0x00000000031abbd2 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::$_1>(long) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x31abbd2)
#31 0x0000000002935db7 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x2935db7)
#32 0x00000000031ab2e7 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x31ab2e7)
#33 0x0000000003172495 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&) const (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3172495)
#34 0x0000000003172787 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) const (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x3172787)
#35 0x000000000318bb38 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x318bb38)
#36 0x0000000001835d8d main (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x1835d8d)
#37 0x00007f27c633d0b3 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b3)
#38 0x000000000183325e _start (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang+0x183325e)
clang-12: error: clang frontend command failed with exit code 134 (use -v to see invocation)
ClangBuiltLinux clang version 12.0.0 (https://github.com/llvm/llvm-project b208e5bcd0be5ffb6346b1eab30ad372782bbe4b)
Target: riscv64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/nathan/cbl/github/tc-build/build/llvm/stage1/bin
clang-12: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.

Thanks for the report. Should be fixed after f9d7f77267bca055c6cc480065ca7dd9f768b948

Jim added inline comments.May 23 2021, 3:12 AM
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
2201

I met a bug that removes a and mask.

typedef unsigned char uint8x2_t __attribute__((vector_size(2)));

uint8x2_t udiv(uint8x2_t *a, uint8x2_t *b) {
  return *a / *b;
}

Assembly look like:
divu a1, a3, a1
divu a0, a0, a2
slli a1, a1, 8
or a0, a0, a1 >> missing "and a0, a0, 256" before or operation

If element 0 of *b is zero, it a division by zero. a0 would be 0xffffffff.
So the result of or operation is incorrect.
Is it a undefined behavior?

jrtc27 added inline comments.May 23 2021, 7:06 AM
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
2201

For vectors, if any element of the divisor is zero, the operation has undefined behavior.

From LangRef.