This patch adds peephole optimizations for the following patterns:
(load (add base, (addi src, off1)), off2) -> (load (add base, src), off1+off2) (store val, (add base, (addi src, off1)), off2) -> (store val, (add base, src), off1+off2)
Differential D124231
[RISCV] Merge addi into load/store as there is a ADD between them HsiangKai on Apr 21 2022, 10:58 PM. Authored by
Details This patch adds peephole optimizations for the following patterns: (load (add base, (addi src, off1)), off2) -> (load (add base, src), off1+off2) (store val, (add base, (addi src, off1)), off2) -> (store val, (add base, src), off1+off2)
Diff Detail
Event Timeline
Comment Actions I bisected a crash while building the Linux kernel for RISC-V to this change: # bad: [68ee5ad0082c0a72ff16a6571c9db7054afd6ea3] [flang] Update Google Doc link for Flang Biweekly Sync call notes # good: [981ed72a17e4302dfd77ac54d742c08dfb6b35bb] [NFC][SCEV] Refactor `createNodeForSelectViaUMinSeq()` out of `createNodeForSelectOrPHIViaUMinSeq()` git bisect start '68ee5ad0082c0a72ff16a6571c9db7054afd6ea3' '981ed72a17e4302dfd77ac54d742c08dfb6b35bb' # bad: [f8463da4a329b839cfd01d7f80ae72e18f3c061e] [lldb] Allow EXE or exe in toolchain-msvc.test git bisect bad f8463da4a329b839cfd01d7f80ae72e18f3c061e # bad: [cf90233a67eb513930880ff1b49e80af18de5d5c] [InstCombine] Add additional test for icmp of two ranges (NFC) git bisect bad cf90233a67eb513930880ff1b49e80af18de5d5c # bad: [eaca933c59fd61b3df4697b5fae0eeec67acfaeb] [Clang][CodeGen]Fix __builtin_dump_struct missing record type field name git bisect bad eaca933c59fd61b3df4697b5fae0eeec67acfaeb # good: [52ce95a1a55424256f0d56e32392396896ed7f76] [NFC] Prevent shadowing a variable declared in `if` git bisect good 52ce95a1a55424256f0d56e32392396896ed7f76 # good: [78582194361e4454e95d3af23367b81dd63b7943] [asan] Enable detect_stack_use_after_return=1 by default on Linux git bisect good 78582194361e4454e95d3af23367b81dd63b7943 # bad: [c62b014db97953bee25d17b46730f05eea6a3430] [RISCV] Merge addi into load/store as there is a ADD between them git bisect bad c62b014db97953bee25d17b46730f05eea6a3430 # good: [9fc58f1820e3b0883c9759945bca1aa1f1df8e8d] [PowerPC] Support of ppc_fp128 in lowering of llvm.is_fpclass git bisect good 9fc58f1820e3b0883c9759945bca1aa1f1df8e8d # first bad commit: [c62b014db97953bee25d17b46730f05eea6a3430] [RISCV] Merge addi into load/store as there is a ADD between them I see there was a related follow up change in D124693 but that change does not resolve the issue. A simplified reproducer: struct autofs_packet_missing { int len; char name[] }; autofs_notify_daemon_wq_0, autofs_notify_daemon_type; memcpy(); autofs_wait() { struct autofs_packet_missing pkt; switch (autofs_notify_daemon_type) case 0: { struct autofs_packet_missing *mp = &pkt; memcpy(mp->name); mp->name[autofs_notify_daemon_wq_0] = '\0'; } } $ clang --target=riscv64-linux-gnu -O2 -c -o /dev/null waitq.i ... clang: /home/nathan/cbl/src/llvm-project/llvm/include/llvm/CodeGen/MachineInstr.h:506: llvm::MachineOperand &llvm::MachineInstr::getOperand(unsigned int): Assertion `i < getNumOperands() && "getOperand() out of range!"' 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: clang --target=riscv64-linux-gnu -O2 -c -o /dev/null waitq.i 1. <eof> parser at end of file 2. Code generation 3. Running pass 'Function Pass Manager' on module 'waitq.i'. 4. Running pass 'Prologue/Epilogue Insertion & Frame Finalization' on function '@autofs_wait' #0 0x0000aaaac0ce0e8c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x34e0e8c) #1 0x0000aaaac0cdf098 llvm::sys::RunSignalHandlers() (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x34df098) #2 0x0000aaaac0c64214 (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) CrashRecoveryContext.cpp:0:0 #3 0x0000aaaac0c643c4 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0 #4 0x0000ffff9d84d854 (linux-vdso.so.1+0x854) #5 0x0000ffff9d3626a8 __pthread_kill_implementation (/lib64/libc.so.6+0x826a8) #6 0x0000ffff9d31ab40 gsignal (/lib64/libc.so.6+0x3ab40) #7 0x0000ffff9d3070f8 abort (/lib64/libc.so.6+0x270f8) #8 0x0000ffff9d314208 __assert_fail_base (/lib64/libc.so.6+0x34208) #9 0x0000ffff9d314270 __assert_perror_fail (/lib64/libc.so.6+0x34270) #10 0x0000aaaabfd84c00 llvm::RISCVRegisterInfo::eliminateFrameIndex(llvm::MachineInstrBundleIterator<llvm::MachineInstr, false>, int, unsigned int, llvm::RegScavenger*) const RISCVRegisterInfo.cpp:0:0 #11 0x0000aaaac040db24 (anonymous namespace)::PEI::replaceFrameIndices(llvm::MachineBasicBlock*, llvm::MachineFunction&, int&) PrologEpilogInserter.cpp:0:0 #12 0x0000aaaac040b5d4 (anonymous namespace)::PEI::runOnMachineFunction(llvm::MachineFunction&) PrologEpilogInserter.cpp:0:0 #13 0x0000aaaac0187f0c llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x2987f0c) #14 0x0000aaaac060cdbc llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x2e0cdbc) #15 0x0000aaaac06146d8 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x2e146d8) #16 0x0000aaaac060d708 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x2e0d708) #17 0x0000aaaac1433268 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> >) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x3c33268) #18 0x0000aaaac178f150 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) CodeGenAction.cpp:0:0 #19 0x0000aaaac1fb094c clang::ParseAST(clang::Sema&, bool, bool) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x47b094c) #20 0x0000aaaac16d49e4 clang::FrontendAction::Execute() (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x3ed49e4) #21 0x0000aaaac1662438 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x3e62438) #22 0x0000aaaac17895ac clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x3f895ac) #23 0x0000aaaabfb36754 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x2336754) #24 0x0000aaaabfb34b80 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0 #25 0x0000aaaac153d6e4 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) Job.cpp:0:0 #26 0x0000aaaac0c640bc llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x34640bc) #27 0x0000aaaac153d1a4 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/tmp/build/llvm/stage1/bin/clang-15+0x3d3d1a4) #28 0x0000aaaac150aa0c clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&) const (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x3d0aa0c) #29 0x0000aaaac150ac78 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) const (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x3d0ac78) #30 0x0000aaaac151de28 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x3d1de28) #31 0x0000aaaabfb34310 main (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x2334310) #32 0x0000ffff9d3073c8 __libc_start_call_main (/lib64/libc.so.6+0x273c8) #33 0x0000ffff9d3074a0 __libc_start_main@GLIBC_2.17 (/lib64/libc.so.6+0x274a0) #34 0x0000aaaabfb31d30 _start (/home/nathan/tmp/build/llvm/stage1/bin/clang-15+0x2331d30) clang-15: error: clang frontend command failed with exit code 134 (use -v to see invocation) ClangBuiltLinux clang version 15.0.0 (https://github.com/llvm/llvm-project 02aa795785379b34f1f82d1c4d852b915c5bfb4a) Target: riscv64-unknown-linux-gnu Thread model: posix InstalledDir: /home/nathan/tmp/build/llvm/stage1/bin clang-15: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs. Comment Actions Thanks Nathan I'll take a look. The followup was an enhancement not a bug fix so I wouldn't expect it to resolve anything. If I don't see a quick fix I'll revert. |
I don't think this is safe for W instructions. We would need to prove the sign extend done by the ADD*W doesn't alter the result of the addition.