herd / herdtools7

The Herd toolsuite to deal with .cat memory models (version 7.xx)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Data dependencies from AMO instructions in RISCV

hernanponcedeleon opened this issue · comments

Apparently herd7 does not generate data-dependencies originated from the destination register of an AMO instruction in RISCV.
In this example

{
0:x6=x; 0:x8=y;
1:x6=y; 1:x8=x;
}
 P0                      | P1                      ;
 ori x5,x0,2             | lw x5,0(x6)             ;
 amoswap.w.rl x0,x5,(x6) | ori x7,x0,1             ;
 ori x7,x0,1             | amoswap.w.rl x0,x7,(x8) ;
 sw x7,0(x8)             |                         ;
exists
(x=2 /\ 1:x5=1)

I would have expected a data-dependency in the first thread (amoswap -> ori -> sw via x0 and x7) which would forbid to reorder the swap and the store, making the behaviour unobservable.

However herd7 reports that the behaviour is possible an indeed the data edge is not in the generated graph

❯ herd7 -model ~/git/herdtools7/herd/libdir/riscv.cat test.litmus -o . -show all -doshow data
Test S+porlp+poprl+NEW Allowed
States 4
1:x5=0; x=1;
1:x5=0; x=2;
1:x5=1; x=1;
1:x5=1; x=2;
Ok
Witnesses
Positive: 1 Negative: 3
Condition exists (x=2 /\ 1:x5=1)
Observation S+porlp+poprl+NEW Sometimes 1 3
Time S+porlp+poprl+NEW 0.01
Hash=6911d30c1458d70f9a9a239417914cc7

test

Is this really intended? I could not find anything in RISCV's documentation here and here about AMO instructions not generating data dependencies.

Hi @hernanponcedeleon, isn't x0 a register whose value always is zero? If so, the amoswap instruction discards its result resulting in a simple store and there is not reason that a data dependency exists here.

Are you saying that because the amoswap is guaranteed to always succeed, the value of x0 is constant and then instruction ori x7,x0,1 can simple be interpreted as ori x7,0,1?

Are you saying that because the amoswap is guaranteed to always succeed, the value of x0 is constant and then instruction ori x7,x0,1 can simple be interpreted as ori x7,0,1?

Yes, ori x7,x0,1 is more like a "load constant in register" instruction. Moreover amoswap does not write the x0 register, as a consequence there is no rf-reg relation from this instruction to the following ori x7,x0,1 instruction and thus no data dependency.

What do you mean by "amoswap does not write the x0 register"?
According to this "amoswap.w rd,rs2,(rs1) ... place the value into register rd".
This is why I was surprised by the missing rf-reg edge in the graph that also contains local events.

Yes but when the target register is x0 no write is perfomed as the value of the "register" is hard-wired to zero.

"

Consider the following variant of the test where x is initialled to 1.

RISCV Test
{
x=1;
0:x6=x; 0:x8=y;
1:x6=y; 1:x8=x;
}
 P0                      | P1                      ;
 ori x5,x0,2             | lw x5,0(x6)             ;
 amoswap.w.rl x0,x5,(x6) | ori x7,x0,1             ;
 ori x7,x0,1             | amoswap.w.rl x0,x7,(x8) ;
 sw x7,0(x8)             |                         ;
exists
(x=2 /\ 1:x5=1)

The graph shows that amoswap reads from the initial value of x (i.e. value 1) and then this instruction should write x0=1 (or am I missing something?). However, there is still no rf-reg from amorswap to ori.

test

Ok, this answers my question

RISC-V base ISA consists of 31 general-purpose registers x1-x31 which hold integer values. The register x0 is hardwired to the constant 0

and indeed if I use x1 instead of x0 the behaviour is forbidden