Hi everyone,
I suppose this sub-category is the right one to post my question. If something misunderstanding, please correct me.
I am trying to use LLVM Compiler to re-build one embedded C project. A few of RISC-V “V” Extension instructions are used in it.
I built clang/llc from latest source code in master successfully. But meet some build error, when I try to use the self-build clang to re-build my project.
Below is two issues I meet.
Issue 1:
Source Code:
int main()
{
int vl;
int size = 1024;
asm volatile("vsetvli %0, %1," "e32" "," "m4" : "=r" (vl) : "r" (size));
asm volatile("vadd.vv" " " "v8" ", " "v0" ", " "v4");
return 0;
}
Error info:
rvv_test.c:5:18: error: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
asm volatile("vsetvli %0, %1," "e32" "," "m4" : "=r" (vl) : "r" (size));
<inline asm>:1:17: note: instantiated into assembly here
vsetvli a1, a1,e32,m4
Issue 2:
Source Code:
int main()
{
int vl;
int* x_ptr;
int size = 1024;
asm volatile("vsetvli %0, %1," "e32" "," "m4" : "=r" (vl) : "r" (size));
asm volatile("vle32.v" " " "v0" ", %0" :: "A" (*(x_ptr)));
return 0;
}
Error info:
rvv_test.c:7:18: error: invalid operand for instruction
asm volatile("vle32.v" " " "v0" ",%0" :: "A" (*(x_ptr)));
<inline asm>:1:14: note: instantiated into assembly here
vle32.v v0, 0(a1)
The command which I used,
clang --sysroot=./riscv/riscv64-unknown-elf --gcc-toolchain=./riscv -march=rv64gv rvv_test.c -o rvv_test
After I checking the source code of RISCV CodeGen, it seems that current code cannot support RVV inline assembly very well.
Issue 1’s cause:
In RISCVAsmParser.cpp,
OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
... ...
if (VTypeIElements.size() == 7) {
... ...
}
// If NoMatch, unlex all the tokens that comprise a vtypei operand
MatchFail:
while (!VTypeIElements.empty())
getLexer().UnLex(VTypeIElements.pop_back_val());
return MatchOperand_NoMatch;
}
So it means I need to use the full instruction as below,
vsetvli a1, t0, e8, m8, ta, ma
But cannot use the simplified instruction as below,
vsetvli a1, a1,e32,m4
Issue 2’s cause:
In tablegen’s output, vle32.v’s instruction format as below,
static const MatchEntry MatchTable[0] = {
... ...
{ 5662 /* vle32.v */, RISCV::VLE32_V, Convert_Reg1_0__Reg1_2__RVVMaskRegOpOperand1_4, AMFBS_HasVInstructions, { MCK_VM, MCK__40_, MCK_GPR, MCK__41_, MCK_RVVMaskRegOpOperand }, },
... ...
}
So I suppose the machine instruction after ISel should be “vle32.v v0, (a1)
”, but not “vle32.v v0, 0(a1)
”.
Could you please kindly help to check whether my understanding is right, but not some wrong operation from my side. Or maybe there is some development branch which there is no such issue in, and I can use it to continue my work?
Thanks a lot