llvm / llvm-project

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

[RISC-V] Assertion "FP not reserved" failed with -mabi=lp64e and -mabi=ilp32e #100822

Open patrick-rivos opened 2 months ago

patrick-rivos commented 2 months ago

Testcase:

int main()
{
    __builtin_printf("Hello World");
    return 0;
}

With -march=rv64iv -mabi=lp64e

Reduced LLVM IR:

target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64"
target triple = "riscv64-unknown-linux-gnu"

define i32 @main() #0 {
entry:
  %call = tail call i32 (ptr, ...) null(ptr null)
  ret i32 0
}

attributes #0 = { "target-features"="+64bit,+d,+f,+relax,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b,-a,-b,-c,-e,-experimental-smmpm,-experimental-smnpm,-experimental-ssnpm,-experimental-sspm,-experimental-ssqosid,-experimental-supm,-experimental-zacas,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-h,-m,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smepmp,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-ztso,-zvbb,-zvbc,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl4096b,-zvl512b,-zvl65536b,-zvl8192b" }

!llvm.module.flags = !{!0}

!0 = !{i32 1, !"target-abi", !"lp64e"}

Command/backtrace:

> /scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc reduced.ll
llc: /scratch/tc-testing/tc-compiler-fuzz-trunk/llvm/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp:667: virtual void llvm::RISCVFrameLowering::emitPrologue(llvm::MachineFunction&, llvm::MachineBasicBlock&) const: Assertion `MF.getRegInfo().isReserved(FPReg) && "FP not reserved"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: /scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc reduced.ll
1.      Running pass 'Function Pass Manager' on module 'reduced.ll'.
2.      Running pass 'Prologue/Epilogue Insertion & Frame Finalization' on function '@main'
 #0 0x00005e421fee75f0 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x1dcf5f0)
 #1 0x00005e421fee4a0f llvm::sys::RunSignalHandlers() (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x1dcca0f)
 #2 0x00005e421fee4b65 SignalHandler(int) Signals.cpp:0:0
 #3 0x00007e4d0e442520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007e4d0e4969fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007e4d0e4969fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x00007e4d0e4969fc pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x00007e4d0e442476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007e4d0e4287f3 abort ./stdlib/abort.c:81:7
 #9 0x00007e4d0e42871b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x00007e4d0e439e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#11 0x00005e421e7f724d llvm::RISCVFrameLowering::emitPrologue(llvm::MachineFunction&, llvm::MachineBasicBlock&) const (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x6df24d)
#12 0x00005e421efaecb8 (anonymous namespace)::PEI::runOnMachineFunction(llvm::MachineFunction&) PrologEpilogInserter.cpp:0:0
#13 0x00005e421edfee97 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) MachineFunctionPass.cpp:0:0
#14 0x00005e421f41d616 llvm::FPPassManager::runOnFunction(llvm::Function&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x1305616)
#15 0x00005e421f41d869 llvm::FPPassManager::runOnModule(llvm::Module&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x1305869)
#16 0x00005e421f41e1c5 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x13061c5)
#17 0x00005e421e700b06 compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#18 0x00005e421e645aee main (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x52daee)
#19 0x00007e4d0e429d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#20 0x00007e4d0e429e40 call_init ./csu/../csu/libc-start.c:128:20
#21 0x00007e4d0e429e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#22 0x00005e421e6f73d5 _start (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x5df3d5)
zsh: IOT instruction (core dumped)  /scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc

The same assert can also be triggered on ilp32e with -march=rv32i_xsfvcp -mabi=ilp32e

Godbolt: https://godbolt.org/z/3j4j8eGMz

Found via fuzzer.

llvmbot commented 2 months ago

@llvm/issue-subscribers-backend-risc-v

Author: Patrick O'Neill (patrick-rivos)

Testcase: ```c int main() { __builtin_printf("Hello World"); return 0; } ``` With `-march=rv64iv -mabi=lp64e` Reduced LLVM IR: ```llvm ir target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64" target triple = "riscv64-unknown-linux-gnu" define i32 @main() #0 { entry: %call = tail call i32 (ptr, ...) null(ptr null) ret i32 0 } attributes #0 = { "target-features"="+64bit,+d,+f,+relax,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b,-a,-b,-c,-e,-experimental-smmpm,-experimental-smnpm,-experimental-ssnpm,-experimental-sspm,-experimental-ssqosid,-experimental-supm,-experimental-zacas,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-h,-m,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smepmp,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-ztso,-zvbb,-zvbc,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl4096b,-zvl512b,-zvl65536b,-zvl8192b" } !llvm.module.flags = !{!0} !0 = !{i32 1, !"target-abi", !"lp64e"} ``` Command/backtrace: ``` > /scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc reduced.ll llc: /scratch/tc-testing/tc-compiler-fuzz-trunk/llvm/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp:667: virtual void llvm::RISCVFrameLowering::emitPrologue(llvm::MachineFunction&, llvm::MachineBasicBlock&) const: Assertion `MF.getRegInfo().isReserved(FPReg) && "FP not reserved"' failed. PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace. Stack dump: 0. Program arguments: /scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc reduced.ll 1. Running pass 'Function Pass Manager' on module 'reduced.ll'. 2. Running pass 'Prologue/Epilogue Insertion & Frame Finalization' on function '@main' #0 0x00005e421fee75f0 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x1dcf5f0) #1 0x00005e421fee4a0f llvm::sys::RunSignalHandlers() (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x1dcca0f) #2 0x00005e421fee4b65 SignalHandler(int) Signals.cpp:0:0 #3 0x00007e4d0e442520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520) #4 0x00007e4d0e4969fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76 #5 0x00007e4d0e4969fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10 #6 0x00007e4d0e4969fc pthread_kill ./nptl/pthread_kill.c:89:10 #7 0x00007e4d0e442476 gsignal ./signal/../sysdeps/posix/raise.c:27:6 #8 0x00007e4d0e4287f3 abort ./stdlib/abort.c:81:7 #9 0x00007e4d0e42871b _nl_load_domain ./intl/loadmsgcat.c:1177:9 #10 0x00007e4d0e439e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96) #11 0x00005e421e7f724d llvm::RISCVFrameLowering::emitPrologue(llvm::MachineFunction&, llvm::MachineBasicBlock&) const (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x6df24d) #12 0x00005e421efaecb8 (anonymous namespace)::PEI::runOnMachineFunction(llvm::MachineFunction&) PrologEpilogInserter.cpp:0:0 #13 0x00005e421edfee97 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) MachineFunctionPass.cpp:0:0 #14 0x00005e421f41d616 llvm::FPPassManager::runOnFunction(llvm::Function&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x1305616) #15 0x00005e421f41d869 llvm::FPPassManager::runOnModule(llvm::Module&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x1305869) #16 0x00005e421f41e1c5 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x13061c5) #17 0x00005e421e700b06 compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0 #18 0x00005e421e645aee main (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x52daee) #19 0x00007e4d0e429d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16 #20 0x00007e4d0e429e40 call_init ./csu/../csu/libc-start.c:128:20 #21 0x00007e4d0e429e40 __libc_start_main ./csu/../csu/libc-start.c:379:5 #22 0x00005e421e6f73d5 _start (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc+0x5df3d5) zsh: IOT instruction (core dumped) /scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/llc ``` The same assert can also be triggered on ilp32e with `-march=rv32i_xsfvcp -mabi=ilp32e` Godbolt: https://godbolt.org/z/3j4j8eGMz Found via fuzzer.
wangpc-pp commented 2 months ago

The root cause is:

  1. We don't reserve FP in RISCVRegisterInfo::getReservedRegs because RISCVFrameLowering::hasFP (hasStackRealignment returns false) returns false.
  2. We set MaxAlignment to RVVStackAlign(which is 16B) in RISCVFrameLowering::processFunctionBeforeFrameFinalized: https://github.com/llvm/llvm-project/blob/13d39cb6f7b20e596b66f59ebf4dba766451398b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp#L1229-L1239
  3. hasFP returns true as MachineFrameInfo::shouldRealignStack returns true (MaxAlignment > StackAlignment, in which MaxAlignment is 16B and StackAlignment is 4B(ilp32e) or 8B(lp64e)): https://github.com/llvm/llvm-project/blob/13d39cb6f7b20e596b66f59ebf4dba766451398b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp#L661-L667
  4. But we didn't reserve FP before, so an assertion occurs.

A potential fix (#101002) is to make RVV stack alignment decided by ABI just like the default stack alignment, but I think this can be ABI incompatiblity. cc @kito-cheng