fitzgen opened PR #5676 from or-and-y-with-not-y
to main
:
Thanks again to Souper for pointing this one out! cc @regehr
<!--
Please ensure that the following steps are all taken care of before submitting
the PR.
[ ] This has been discussed in issue #..., or if not, please tell us why
here.[ ] A short description of what this does, why it is needed; if the
description becomes long, the matter should probably be discussed in an issue
first.[ ] This PR contains test cases, if meaningful.
- [ ] A reviewer from the core maintainer team has been assigned for this PR.
If you don't know who could review this, please indicate so. The list of
suggested reviewers on the right can help you.Please ensure all communication adheres to the code of conduct.
-->
fitzgen requested cfallin for a review on PR #5676.
cfallin submitted PR review.
fitzgen updated PR #5676 from or-and-y-with-not-y
to main
.
fitzgen has enabled auto merge for PR #5676.
jameysharp submitted PR review.
jameysharp submitted PR review.
jameysharp created PR review comment:
I think there's an equivalent version of this rule where the
bnot
is inside theband
, and the operand tobor
is the uninverted value.
jameysharp created PR review comment:
Could you duplicate the egraph filetests so there's a second version of each one with the operands to
bor
flipped? I suspect some of these will pass but maybe not all of them.
jameysharp created PR review comment:
Do the
check
lines do anything in runtests?
fitzgen has disabled auto merge for PR #5676.
fitzgen updated PR #5676 from or-and-y-with-not-y
to main
.
fitzgen submitted PR review.
fitzgen created PR review comment:
We talked, decided this was one rabbit hole too deep.
fitzgen has enabled auto merge for PR #5676.
fitzgen merged PR #5676.
avanhatt submitted PR review.
avanhatt created PR review comment:
Our verifier prototype finds the following counterexample for this rule (lightly edited for readability):
simplify (lhs): #x0000000000000000 #b0 bor (rhs): #x0000000000000001 #b1 x: #x0000000000000001 #b1 y: #x0000000000000002 #b10 z: #x0000000000000000 #b0 zk: #x0000000000000000 #b0
fitzgen submitted PR review.
fitzgen created PR review comment:
I believe that this is because the
if
precondition is buggy. It is just checking whether the constructor succeeds or not, it is not checking if it returnedtrue
. Basically ignoring that predicate. (Funnily enough, becauseu64_eq
ispure
, the constructor will always succeed! This seems like something the ISLE compiler can check for and reject.) This is a pretty big foot gun withif
, IMHO.Anyways, the predicate needs to be rewritten as
(if-let $true ...)
.
jameysharp submitted PR review.
jameysharp created PR review comment:
That's so cool! I don't understand it but it's awesome. :laughing:
Here's what's confusing me: The rule should only fire if
zk
is equal to!y
. But in this counterexample,y
is 2, sou64_not y
is0xfffffffffffffffd
, butzk
is 0. Is the verifier missing theif
condition? Or isu64_not
modeled incorrectly, maybe? (It's supposed to be bitwise-not, but this counterexample would make sense if that were modeled as boolean-not, turning non-zero values into 0.)Also, what type is this counterexample for? I'd be especially interested if you can find counterexamples for I64 specifically, because I think the rule as-written is wrong for any other width. That said, I'd expect other widths to just fail to match the rule most of the time, rather than ever rewriting incorrectly, so if you find a narrower counterexample it's probably a real issue.
jameysharp submitted PR review.
jameysharp created PR review comment:
Ohhh, Nick's got it right. Although it's because
u64_eq
is notpartial
, not because it'spure
. (Those flags are independent now.)We also need to mask both constants down to the appropriate width if we want to make the rule fire on <64-bit types.
avanhatt created PR review comment:
To restate what @fitzgen realized:
(if (u64_eq zk (u64_not y)))
desugars to(if-let _ (u64_eq zk (u64_not y)))
, which ISLE is perfectly happy to match on. That is, the semantics forif
is whether some match is possible, _not_ whether the match is possible and its boolean value is truthy. The verifier matches these weird semantics, since it treatsif-let
statements as constraints setting the LHS and RHS of the statement to be equal---in this case, happily setting the wildcard to false and considering the rule to have matched.Right now, this counterexample is for BVs of width 64, and the verifier is complaining that the rule is infeasible (that is, doesn't match) for other widths (which, based on your comment, seems correct?).
avanhatt submitted PR review.
avanhatt edited PR review comment.
Last updated: Dec 23 2024 at 12:05 UTC