Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project Proposal: Support LLVM GlobalISel for RISC-V Vector Extension #410

Open
jiahanxie353 opened this issue Oct 27, 2023 · 4 comments · May be fixed by #423
Open

Project Proposal: Support LLVM GlobalISel for RISC-V Vector Extension #410

jiahanxie353 opened this issue Oct 27, 2023 · 4 comments · May be fixed by #423
Labels
proposal course project proposals

Comments

@jiahanxie353
Copy link
Contributor

What will you do?

Support LLVM Global Instruction Selection for a subset of RISC-V Vector Extension, namely vector integer add and sub and basic vector load/store.

How will you do it?

  1. For scalars, Apple has been working on it to support GlobalISel for AArch64 for years: post and source code.
  2. For vectors, although GlobalISel does not fully support them, SelectionDAG does.

Therefore, I will leverage these two, combined with the semantic meaning of LLVM Generic Opcodes and RISC-V Vector Extension Spec to support the aforementioned basic RISC-V Vector Extension instructions.

For the actual implementation, I will support the full pipeline:

The beginning of the pipeline should be straightfoward and interesting things will happen downstream.

How will you empirically measure success?

I will use LLVM IR as inputs and inspect the RISCV-V Vector Extension assembly outputs.

First, I need to make sure the assembly is doing the correct thing as expected.

Then, I will compare my GlobalISel outputs with the outputs from SelectionDAG, which will be used as the ground truth. If these two are equal, that means I have an "optimal" GlobalISel implementation.

Team members:

I will do the implementation job individually, but will ask @michaelmaitland for guidance if necessary.

@jiahanxie353 jiahanxie353 added the proposal course project proposals label Oct 27, 2023
@michaelmaitland
Copy link
Contributor

michaelmaitland commented Oct 27, 2023

The beginning of the pipeline should be straightforward

Don't forget about CallLowering for vectors, which is part of IR Translation. I think this may be needed so you obey the vector ABI. For example, to lower the function below, we need to know how to lower the vector argument and where to place the vector return value.

define <vscale x 8 x i32> @intrinsic_vadd_vi_nxv8i32_nxv8i32_i32(<vscale x 8 x i32> %0, i64 %1) nounwind {
entry:
  %a = call <vscale x 8 x i32> @llvm.riscv.vadd.nxv8i32.i32(
    <vscale x 8 x i32> undef,
    <vscale x 8 x i32> %0,
    i32 9,
    i64 %1)

  ret <vscale x 8 x i32> %a
}

to

intrinsic_vadd_vi_nxv8i32_nxv8i32_i32:
# %bb.0: # %entry
vsetvli zero, a0, e32, m4, ta, ma
vadd.vi v8, v8, 9
ret

I think the SDAG equivalent is in LowerCall, RISCV::CC_RISCV, RISCVTargetLowering::analyzeInputArgs, and analyzeOutputArgs. It may be better to implement the CC_RISCV_FAST_CC if it is simpler.

@sampsyo
Copy link
Owner

sampsyo commented Oct 30, 2023

This sounds really cool, and quite ambitious, @jiahanxie353! I'm interested to see where this goes.

Can you please expand on your evaluation plan to make it as explicit as possible? In particular:

  • Exactly which benchmarks/tests will you use? (Please include a link.) How many of these tests do you expect to pass?
  • I am a little concerned about using manual inspection as the test oracle. Is there any emulator you could use to try actually running these programs, to make sure they at least don't crash with SIGILL? (Checking actual correctness would be even better.) I'm not sure if the official emulator, Spike, can do this but it seems useful to find out. If this is strictly impossible, that's OK, but I think it is at least worth a try to search for a workable emulator.

@jiahanxie353
Copy link
Contributor Author

Sure! Let me expand on my evaluation plan!

Exactly which benchmarks/tests will you use? (Please include a link.) How many of these tests do you expect to pass?

After some research, I found there's no benchmarks/comprehensive test suites for GlobalIsel (I also went to an LLVM office hour today, and the developer confirmed this unfortunate reality). Mostly the tests for GlobalISel tests are just MIR tests that are crafted by the contributers and are submitted with their PR patches.

I plan to use

  1. This vvadd test case in the riscv-tests repository, and
  2. I will hand craft MIR tests for each pass, namely Legalize, RegBankSelect, and InstrSelect (thanks to @michaelmaitland he will help me with CallLower). The rule of thumb is to take motivating examples and common cases, as suggested by @qcolombet in the office hour. Therefore, I will be making the .mir test files to include common uses for testing for these three passes, respectively. And I will use RUN command and the LLVM FileCheck utility in the .mir files to test. For example, if I were to test InstrSelect, I will have llc -march=riscv64 -run-pass=instruction-select in the test file, and similarly for other passes as well. Thanksfully, FileCheck is powerful that it can check between two files, check specific patterns, etc. so I don't need to manual inspect (though manually come up with test cases is still required).
  3. With the individual pass working, I will then make integrated test cases, in which I will have LLVM IR as inputs and run the whole pass to RISC-V instructions. And I plan to use SelectionDAG as the ground truth for comparison.

How many of these tests do you expect to pass?

I expect all test cases to pass for the instructions I plan to support (vadd, vsub, vle, and vse as they have unit-stride and should be the easiest to implement for vector load/store; this is probably already ambitious enough, but I can look at strided and indexed vector load/store as well after I have the easiest load/store supported). As explained above, I will make a number of the most common cases for the testing purpose, both individual-pass-wise and integration-wise.

Is there any emulator you could use to try actually running these programs, to make sure they at least don't crash with SIGILL?

I looked into Spike and it claim to support RISC-V Vector Extension, as stated in the README:

V extension, v1.0 (requires a 64-bit host)

but I think it is at least worth a try to search for a workable emulator.

Totally agree! I was trying to install the simulator and run the actual vector code today, but was stuck on some issues with pk. I can get back and post anything I find out after I fix it.

@sampsyo
Copy link
Owner

sampsyo commented Nov 2, 2023

Excellent! All sounds good; thanks!!

@jiahanxie353 jiahanxie353 linked a pull request Dec 11, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal course project proposals
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants