-
Notifications
You must be signed in to change notification settings - Fork 1
Fix bug that ignored defs in if when missing from else #417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
pyright failure seems to be unrelated, I think. |
@Roger-luo do we support |
From what I saw looking into this: yes, that's how an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually why do we remove node.orelse
here?
@Roger-luo you mean the But also, this still doesn't work for all cases! See my question in the description. |
There we go: the issue that kept the I added if frame.parent is not None:
frame.defs.update(frame.parent.defs) and now everything seems to work. The example from before @kernel
def main_elif(n: int):
x = 0
if x == n:
x = 3
elif x == n + 1:
x = 4
return x
main_elif.print() now prints func.func @main_elif(n : !py.int) -> !Any {
^0(%main_elif_self, %n):
│ %x = py.constant.constant 0 : !py.int
│ %0 = py.cmp.eq(lhs=%x, rhs=%n : !py.int) : !py.bool
│ %x_1 = scf.if %0 {
│ │ ^1(%1):
│ │ │ %x_2 = py.constant.constant 3 : !py.int
│ │ │ scf.yield %x_2
│ } else {
│ │ ^2(%5):
│ │ │ %2 = py.constant.constant 1 : !py.int
│ │ │ %3 = py.binop.add(%n : !py.int, %2) : ~T
│ │ │ %4 = py.cmp.eq(lhs=%x, rhs=%3) : !py.bool
│ │ │ %x_3 = scf.if %4 {
│ │ │ │ ^3(%6):
│ │ │ │ │ %x_4 = py.constant.constant 4 : !py.int
│ │ │ │ │ scf.yield %x_4
│ │ │ } else {
│ │ │ │ ^4(%7):
│ │ │ │ │ scf.yield %x
│ │ │ } -> purity=False
│ │ │ scf.yield %x_3
│ } -> purity=False
│ func.return %x_1
} // func.func main_elif That looks correct to me! @Roger-luo ready for another round of review! |
I think this breaks some of the test case? |
Ah, damn, I need to take another look then. |
Looks like copying over the definitions from the parent frame was too much. Now, I just check for them and add them to the yields if needed. |
Codecov ReportAttention: Patch coverage is
📢 Thoughts on this report? Let us know! |
☂️ Python Coverage
Overall Coverage
New FilesNo new covered files... Modified Files
|
@Roger-luo I found another test case that didn't work when not copying over the defs with @kernel
def main_nested_if(n: int):
x = 0
if n > 0:
if n > 1:
if n == 3:
x = 4
return x With multiple levels of nesting, the definitions are no longer carried over from the respective parent frame and I only checked up to one level above (just one This would still work if we just copied over the definitions with So, now I wrote a little helper function that walks through all parent frames to see if there's a definition there. That's probably not the cleanest way to do this, but at least all tests seem to work now. |
@Roger-luo this fixes the bug in #416 when there's a definition in the
if
path, but not in theelse
path.However, the issue with the
elif
persists since the definition from the nested if isn't propagated upwards properly.In code:
This fails on main, but works on this branch
This fails both on main and this branch:
(or, equivalently)
We somehow need to lower the bodies first in order to obtain the nested definitions in them, but I'm not sure how exactly.