|
From: Carl E. L. <ce...@us...> - 2017-05-01 19:58:40
|
On Thu, 2017-04-27 at 17:02 +0200, Julian Seward wrote:
> The important IR bits are these:
>
> 100004bc: 28 4c 20 7d ldbrx r9,0,r9
> 100004c0: 28 54 40 7d ldbrx r10,0,r10
> // t143 is r9 after the load
> // t166 is r10 after the load
>
> 100004c4: 51 48 6a 7c subf. r3,r10,r9
> t69 = Sub64(t143,t166) // r3
> t167 = 64to8(CmpORD64S(t69,0x0:I64))
>
> 100004c8: 1c 00 82 40 bne 100004e4 <main+0x84>
> if (CmpNE32(Xor32(And32(8Uto32(t167),0x2:I32),0x2:I32),0x0:I32))
> { PUT(1296) = 0x100004E4:I64; exit-Boring }
>
> My best guess is, this is a problem with the instrumentation of the
> CmpORD64S. What that does is to compare t69 against zero, and produce
> a 3 bit value like this:
>
> 8 if t69 < 0, 4 if t69 > 0, 2 if t69 == 0
>
> A bit strange but that's how the Power integer condition codes work.
> And you can see that the branch condition in the IR tests for 2, meaning
> equal.
>
> This is handled by doCmpORD in mc_translate.c. It special cases the case
> where the second arg is zero, but only for the < (8) case: that bit is a
> copy of the most significant bit of t69, so it doesn't matter if all the
> other bits are undefined. But it doesn't special case the == (2) case, and
> so that bit is regarded as undefined if any bit in t69 is undefined. But
> that's too pessimistic. In fact the "is t69 == 0" question is a defined
> "no" if we can find any bit in t69 which is nonzero and defined. The
> general logic is explained a bit more in the comment further up, "Accurate
> interpretation of CmpEQ/CmpNE."
>
> Applying that to this problem would fix it, I suspect.
doCmpORD should be calculating the shadow bit values for the LT, EQ and
GE bits. The LT bit is 1 if the MSB of xxhash is a 1. I figured the EQ
bit should be 1 if all of the xxhash bits are undefined since we don't
have any valid bits in xx to determine if the valid bits in xx are equal
to zero. Similarly, the GT bit would be undefined if there were no
defined bits in xxhash. This implementation generated more warnings
then the original code. So either my understanding of what doCmpORD is
calculating is wrong or my algorithm for setting the EQ and GT bits is
wrong.
Just for grins, I had doCmpORD return all zeros. The comparison with
uninitialized bits goes away but I get the error "Syscall param
exit_group(status) contains uninitialised byte". Not sure why the
syscall now has uninitialized data.
Anyway, am I wrong on what doCmpORD is doing? Thoughts on how to
determine the Eq and GT bits for this case? Thanks for the help.
Carl
|