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
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 ofx0
is constant and then instructionori x7,x0,1
can simple be interpreted asori 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
.
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