Closed anutosh491 closed 4 months ago
But if we add some print statements here
def mmrv(e: S, x: S) -> list[S]:
print(e)
print(x)
if e == x:
list1: list[S] = [x]
return list1
else:
print(e)
list2: list[S] = mmrv(x, x)
return list2
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine --backend=llvm integration_tests/test_gruntz.py
The stack address was not found in any shared library or the main program, the stack is probably corrupted. Aborting.
The stack address was not found in any shared library or the main program, the stack is probably corrupted. Aborting.
The stack address was not found in any shared library or the main program, the stack is probably corrupted. Aborting.
The stack address was not found in any shared library or the main program, the stack is probably corrupted. Aborting.
The stack address was not found in any shared library or the main program, the stack is probably corrupted. Aborting.
The stack address was not found in any shared library or the main program, the stack is probably corrupted. Aborting.
........
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine --backend=c integration_tests/test_gruntz.py
log(x)
x
0x7ffefd4a7b98
x
x
x
The llvm backend gives an error indefinitely and as shown in the C backend, the 2nd print(e)
or the print inside the if blocks isn't executed correctly !
I was able to boil down the reason for this. Conside the following function (symbolics_13.py)
from lpython import S
from sympy import pi
def func() -> S:
return pi
def test_func():
z: S = func()
print(y)
test_func()
Now if we check the ASR for it after the subroutine_from_function
call the ReturnVar
is update to Out
intent and the code is transformed to something like
def func(r: Out[S]) -> None:
r = pi
So now we have the ASR for this we have
[(=
(Var 3 r)
(IntrinsicScalarFunction
SymbolicPi
[]
0
(SymbolicExpression)
()
)
()
)]
If you see carefully the return node has been taken care of and we don't have a return node anymore (because obviously the function is not returning anything)
But if you see this function
from lpython import S
from sympy import pi
def func() -> S:
if True:
return pi
def test_func():
z: S = func()
print(y)
test_func()
We end up with the ASR
[(=
(Var 3 _lpython_return_variable)
(IntrinsicScalarFunction
SymbolicPi
[]
0
(SymbolicExpression)
()
)
()
)
(Return)]
Now we don't take care of the Return
node in this case ( I think we would encounter this if we are using any sort of loop or conditional block like if
,while
, for
) . Now as you can see we don't really need the Return
node there and hence we need some code segment that will keep removing the Return
Node depth wise I suppose .
So how this relates to my issue is if the return node is present (which shouldn't be) , we enter visit_Return
in the symbolic pass and things go wrong from there. @Thirumalai-Shaktivel could you please help me address this
For eg we might have
if x == pi:
if x != y:
return x
else:
return 2*x
else:
return 3*x
And if we are using the subroutine_from_function
, we would end up with
if x == pi:
if x != y:
r = x
else:
r = 2*x
else:
r = 3*x
But we might need a method to get rid of the return nodes overall because we would be having them but we wouldn't be needing them. I can think of something to address this.
Yes, the return is not needed there in ASR, however, it also does not hurt (and cannot hurt) to have it there.
It seems there is some issue how the Return statement is handled in the symbolic pass, and it looks like there is a bug with multiple present return statements.
We need to create a good robust design how freeing variables should be handled in the return visitor. Here are three ways:
A much more smaller/simpler example to consider here
from lpython import S
from sympy import Symbol, log
def mmrv(e: S, x: S) -> S:
print(e)
if e == x:
return x
print(e)
return e
def test_mrv():
x: S = Symbol("x")
ans3: S = mmrv(log(x), x)
print(ans3)
test_mrv()
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine examples/expr2.py --backend=c
log(x)
0x7ffcac7b0838
Segmentation fault
Consider the following minimalistic example
Mostly this works