Index: llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp =================================================================== --- llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -411,6 +411,20 @@ return MCDisassembler::Success; } +// This function checks some corner cases that the instruction binary code +// matches legal instruction pattern but actually is illegal. The default +// return value flase means that the input InstCode does not fall into any +// of such corner cases. +static bool isIllegalInstruction(unsigned InstCode) { + if ((InstCode & 0x7f) == 0x57 && (InstCode & 0x7000) == 0x7000 && + ((InstCode & 0x80000000) == 0 || (InstCode & 0xc0000000) == 0xc0000000)) { + // For vsetvli and vsetivli, the LMUL field can not be 4. + if ((InstCode & 0x700000) == 0x400000) + return true; + } + return false; +} + DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, ArrayRef Bytes, uint64_t Address, @@ -427,6 +441,10 @@ return MCDisassembler::Fail; } Insn = support::endian::read32le(Bytes.data()); + if (isIllegalInstruction(Insn)) { + Size = 4; + return MCDisassembler::Fail; + } LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n"); Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); Size = 4; Index: llvm/test/tools/llvm-objdump/RISCV/vsetvli.s =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objdump/RISCV/vsetvli.s @@ -0,0 +1,16 @@ +# RUN: llvm-mc -filetype=obj -triple=riscv64 %s \ +# RUN: | llvm-objdump -D --mattr=+experimental-v - | FileCheck %s + +# CHECK: vsetvli a1, a0, e64, m1, tu, mu +# CHECK-NEXT: +# CHECK-NEXT: vsetvli a1, a0, e64, mf8, tu, mu +# CHECK-NEXT: vsetivli a1, 16, e8, m4, tu, mu +# CHECK-NEXT: +# CHECK-NEXT: vsetivli a1, 16, e8, mf4, tu, mu + +.word 0x018575d7 +.word 0x01c575d7 +.word 0x01d575d7 +.word 0xc02875d7 +.word 0xc04875d7 +.word 0xc06875d7