ucb-bar / esp-llvm

UCB-BAR fork of LLVM! NOT UPSTREAM RISCV LLVM
Other
123 stars 55 forks source link

Invalid branch condition code / UNREACHABLE executed at [...]/RISCVInstrInfo.cpp:383 #11

Closed svenstucki closed 8 years ago

svenstucki commented 9 years ago

Hi, I ran into the error from the title when playing around a bit with clang.

Here's a minimal testcase:

extern void f(void);

void f2(int test) {
    switch (test) {
    case 1:
        f();
        break;
    case 2:
        f();
        break;
    case 3:
        f();
        break;
    case 4:
        f();
        break;
    }
}

This is the compile command I used (autogenerated from a Makefile with a different target architecture in mind, so not everything makes sense :):

/[...]/riscv-env/bin/clang -cc1 -triple riscv -S -disable-free -main-file-name cvp.c -mrelocation-model static -mdisable-fp-elim -fmath-errno -mconstructor-aliases -target-feature +rv32 -target-feature -rv64 -target-linker-version 2.20.51.0.2 -ffunction-sections -fdata-sections -D "NDEBUG" -O3 -Wextra -Wall -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -fno-dwarf-directory-asm -ferror-limit 19 -fmessage-length 237 -mstackrealign -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -x c cvp-8xKHIQ.c

Here's the full error message:

Invalid branch condition code!
UNREACHABLE executed at /[...]/riscv-tools/riscv-llvm/lib/Target/RISCV/RISCVInstrInfo.cpp:383!
0  clang           0x0000000002e77b25 llvm::sys::PrintStackTrace(_IO_FILE*) + 38
1  clang           0x0000000002e77da2
2  clang           0x0000000002e7781b
3  libpthread.so.0 0x00000035b5e0f710
4  libc.so.6       0x00000035b5632625 gsignal + 53
5  libc.so.6       0x00000035b5633e05 abort + 373
6  clang           0x0000000002e60964 llvm::FoldingSetNodeIDRef::ComputeHash() const + 0
7  clang           0x00000000020b415b llvm::RISCVInstrInfo::InsertBranchAtInst(llvm::MachineBasicBlock&, llvm::MachineInstr*, llvm::MachineBasicBlock*, llvm::SmallVectorImpl<llvm::MachineOperand> const&, llvm::DebugLoc) const + 1625
8  clang           0x00000000020b318d llvm::RISCVInstrInfo::InsertBranch(llvm::MachineBasicBlock&, llvm::MachineBasicBlock*, llvm::MachineBasicBlock*, llvm::SmallVectorImpl<llvm::MachineOperand> const&, llvm::DebugLoc) const + 329
9  clang           0x00000000028f88a1 llvm::BranchFolder::OptimizeBlock(llvm::MachineBasicBlock*) + 2177
10 clang           0x00000000028f7bf7 llvm::BranchFolder::OptimizeBranches(llvm::MachineFunction&) + 135
11 clang           0x00000000028f4b79 llvm::BranchFolder::OptimizeFunction(llvm::MachineFunction&, llvm::TargetInstrInfo const*, llvm::TargetRegisterInfo const*, llvm::MachineModuleInfo*) + 707
12 clang           0x00000000028f4370
13 clang           0x00000000027e2459 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 95
14 clang           0x0000000002dfce9e llvm::FPPassManager::runOnFunction(llvm::Function&) + 290
15 clang           0x0000000002dfd00e llvm::FPPassManager::runOnModule(llvm::Module&) + 84
16 clang           0x0000000002dfd362 llvm::MPPassManager::runOnModule(llvm::Module&) + 556
17 clang           0x0000000002dfd958 llvm::PassManagerImpl::run(llvm::Module&) + 244
18 clang           0x0000000002dfdb63 llvm::PassManager::run(llvm::Module&) + 39
19 clang           0x0000000000ebcbd2
20 clang           0x0000000000ebccad clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::Module*, clang::BackendAction, llvm::raw_ostream*) + 136
21 clang           0x0000000000eb8ca0
22 clang           0x0000000001090568 clang::ParseAST(clang::Sema&, bool, bool) + 783
23 clang           0x0000000000c834dc clang::ASTFrontendAction::ExecuteAction() + 298
24 clang           0x0000000000eb81d7 clang::CodeGenAction::ExecuteAction() + 1007
25 clang           0x0000000000c83063 clang::FrontendAction::Execute() + 205
26 clang           0x0000000000c571ac clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 720
27 clang           0x0000000000c27724 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1074
28 clang           0x0000000000c17ae6 cc1_main(char const**, char const**, char const*, void*) + 636
29 clang           0x0000000000c21ef7 main + 508
30 libc.so.6       0x00000035b561ed5d __libc_start_main + 253
31 clang           0x0000000000c17219
Stack dump:
0.  Program arguments: /[...]/riscv-env/bin/clang -cc1 -triple riscv -S -disable-free -main-file-name cvp.c -mrelocation-model static -mdisable-fp-elim -fmath-errno -mconstructor-aliases -target-feature +rv32 -target-feature -rv64 -target-linker-version 2.20.51.0.2 -ffunction-sections -fdata-sections -D NDEBUG -O3 -Wextra -Wall -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -fno-dwarf-directory-asm -ferror-limit 19 -fmessage-length 237 -mstackrealign -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -x c cvp-8xKHIQ.c
1.  <eof> parser at end of file
2.  Code generation
3.  Running pass 'Function Pass Manager' on module 'cvp-8xKHIQ.c'.
4.  Running pass 'Control Flow Optimizer' on function '@f2'
ievans commented 9 years ago

I'm attempting to use riscv-llvm to compile some larger projects and noticing this error a lot. I just wanted to add that it's only apparent for me on -O1 and above; -O0 works just fine.

svenstucki commented 9 years ago

That seems to be the problem indeed. I've only noticed now, because I was trying to run some benchmarks, no problems with -O0 otherwise. I basically cannot compile any of my code with -O1 or better.

The problem above can also be triggered with those arguments only:

clang -cc1 -triple riscv -S -O1 cvp-8xKHIQ.c

(Or -O2 and -O3 of course.)

svenstucki commented 9 years ago

I think I fixed it or at least found a workaround.

The RISCVInstrInfo::InsertBranchAtInst function switch only has cases for branch condition codes, which have a corresponding instruction. Branches like BGTU (which it tried to generate in my case) aren't supported. After I added that, I noticed that the RISCVInstrInfo::InsertConstBranchAtInst function had cases for them and copied them over.

Now I suppose the root cause for this could be different, e.g. if the llvm optimizer isn't supposed to generate those branch conditions at all.

@ievans Have a look at my fork: https://github.com/svenstucki/riscv-llvm

Do you want me to send a pull request?

By the way, the example above results in quite inefficient assembly code. The result is basically the same for -O1 up to -O3. There are always 5 branches generated, while 2 would suffice.

colinschmidt commented 8 years ago

This appears to be fixed as far as I can tell.

I compared the assembly to the riscv-gcc output(which has 5 branches btw) and there is an extraneous jump in the llvm version due to a missed fall through opportunity. I'll close this issue and refile the performance issue.