Hi,
As you know, I've been improving testing for stackmaps.
The LLVM test suite contains static stackmap tests: static in the sense that they only check that the emitted stackmap section looks somewhat feasible.
I wanted to add tests that check that the locations described in the stackmap section do in fact hold the correct data *at runtime*.
This diff is a start at that. It needs more work (test more types and location kinds) but I wanted to raise a "draft" for early comments.
OK, so how does this work?
For each architecture there is a input_$ARCH.ll containing a function called @run_test. In that function is a series of pairs of calls like:
call void llvm.experimental.stackmap(i64 0, i32 0, i32 50); call void sm_inspect()
The former emits the stackmap section at compile time, the latter checks *at runtime* that the storage referenced by the stackmap: a) is in the expected kind of storage (register, memory, constant etc.), and b) contains the right value. It does this by printing stuff to stdout which is then checked by your usual llvm-lit reference output stuff.
(For the above example, we expect some bytes stored directly inside the stackmap record's constant field to be, when casted to i32 , the integer value 50).
I've only made an x86_64 input so far. This demonstrates constant integers and integers in registers.
One nasty thing I've realised is that there is no guarantee that the live state isn't trashed between the call to llvm.experimental.stackmap() and sm_inspect(). It works in practice (by chance?) but only because:
- sm_inspect() takes no arguments, so the argument registers are untouched.
- I've added some notail, as tail call optimisations were moving stuff around between the two calls.
But in general, I think the compiler could do anything it wants to realise the call to sm_inspect(). How do we feel about this? Maybe we can't reliably test llvm.experimental.stackmap, but we may be able to test llvm.experimental.patchpoint as it emits stackmaps *and* does a call "atomically". There should be no window in which state could be trashed(?). I've not tried that, it's just a theory.
Other small questions:
- Is LLVM going to be deterministic with regards to where values are being stored?
- Do we need to test different optimisation levels? It occurs to me that I'm not sure what opt level I'm actually testing here!
- In CMakelists.txt is ${ARCH} the right variable to use? I'm only testing 64-bit x86 here, but ${ARCH} is x86 for me... Will it try to run my tests on 32-bit x86?
(If we want to test other arches, someone with the machines will need to add test inputs and reference outputs -- I only have x86_64).
I'm surprised to see text IR here. It's not stable so this could be problematic. Are there other existing tests written in text IR?