<arigato>
it may be some aliasing problem, of the kind: p1 and p2 are different at the start of the loop, but become equal at the end, and the optimized 2nd version of the loop uses that fact
<arigato>
we later attach a bridge directly to the 2nd version, but without checking that p1 and p2 are indeed equal
<arigato>
does it sound like it could occur?
<arigato>
I think the 2nd version of the loop uses equality like this: it optimizes i3=getfield(p1) by replacing it with the value of computed long ago for getfield(p2)
<arigato>
ah, or rather, the arguments of the 2nd version of the loop contain i3, which is equal to getfield(p1) or getfield(p2), doesn't matter which one
<cfbolz>
arigato: I thought that virtual state checks for aliasing
<cfbolz>
But it's not impossible indeed
<arigato>
...still confused, looking more...
<cfbolz>
did you notice just how weird the loop in the python example is? It passes the inner while header *three* times, not two
<arigato>
"passes the inner while header"?
<cfbolz>
arigato: I'll paste you something when I'm back at the laptop
<cfbolz>
Just look at how many pop_jump_ifs bytecodes there are
<arigato>
I think that's explainable
<arigato>
the first is #45 POP_JUMP_IF_FALSE
<arigato>
the second is #24 POP_JUMP_IF_FALSE, that's the outer loop
<arigato>
the third one is also #45 POP_JUMP_IF_FALSE but always passes
<arigato>
because we know more or less statically at this point that height > 0
<cfbolz>
So it prevents the merge at this one because one is always true, the other always false?
<arigato>
I think the third one is not recorded as interesting at all, it's a guard on what is known to be true
<arigato>
and I think we force merge points only on JUMP_ABSOLUTE, i.e. at the end of loops, not at the beginning
<cfbolz>
Right
<cfbolz>
Ah, I see
<arigato>
that's happy nonsense but only a little bit
krono has joined #pypy
<cfbolz>
arigato: yes, because the first guard in the loop body will always fail
<arigato>
yes
<arigato>
it would make sense if we were calling f(1), at least
<cfbolz>
arigato: yes, but we aren't
<cfbolz>
So it's just silly
<arigato>
agreed, but "too bad", such cases occur---as long as they don't also cause bugs :-)
<cfbolz>
Yes :-)
<arigato>
so basically, the loop goes from the inner while, "h <= 0", down the bottom, up the outer loop again, "h = height which is > 0", inside the inner loop, and back at the start of the inner while
<arigato>
unrolling figures out that if we run this loop two times in a row, then it must mean that "h = (height - 1) <= 0"
<arigato>
so the optimized 2nd iteration of the loop should have as condition "height == 1" somehow
<arigato>
or "h == height - 1"
<cfbolz>
Yes
<cfbolz>
But I think it figures this out very implicitly
<arigato>
...and now I understood why the end of the 2nd iteration passes a constant 0: that's because at that point we know that h = height - 1 == 0
<cfbolz>
arigato: but note that coming from the preamble we can never actually reach the jump
<arigato>
unless we call f(1)
<cfbolz>
So things become wrong only through making a bridge jump to the loop
<arigato>
it's more complicated than "this code is fully unreachable"