Fix/extend the < operator; promote min/max from symbol to node

- Fix case where CONST < FNCALL or FNCALL < CONST, when the function was marked as SEF but the args were not SEF, could result in the FNCALL being optimized out, thus failing to apply the side effects of the arguments.
- Copy the function's `min` and `max` present in the symbol table, to the node; use the node's `min` and `max` properties in the `<` operator instead of looking up the symbol and using that.
- Extend it to cover all cases where CONST < SEFexpr and SEFexpr < CONST where SEFexpr.min and SEFexpr.max are defined.
This commit is contained in:
Sei Lisa 2024-05-06 23:55:55 +02:00
parent f5035ed62d
commit 65326115d8
3 changed files with 43 additions and 43 deletions

View file

@ -1318,51 +1318,37 @@ class foldconst(object):
parent[index] = nr(nt='CONST', t='integer', value=0,
SEF=True)
return
if child[0].t == child[1].t in ('integer', 'float'):
if (child[0].nt == 'CONST'
and child[1].nt == 'FNCALL'
and self.FnSEF(child[1])
if child[0].nt == 'CONST' and child[1].SEF:
# when CONST >= second.max: always false
# when CONST < second.min: always true
if (hasattr(child[1], 'max')
and not lslfuncs.less(child[0].value, child[1].max)
):
# CONST < FNCALL aka FNCALL > CONST
# when FNCALL.max <= CONST: always false
# when CONST < FNCALL.min: always true
if ('max' in self.symtab[0][child[1].name]
and not lslfuncs.less(child[0].value,
self.symtab[0][child[1].name]['max'])
):
parent[index] = nr(nt='CONST', t='integer',
value=0, SEF=True)
return
if ('min' in self.symtab[0][child[1].name]
and lslfuncs.less(child[0].value,
self.symtab[0][child[1].name]['min'])
):
parent[index] = nr(nt='CONST', t='integer',
value=1, SEF=True)
return
if (child[1].nt == 'CONST'
and child[0].nt == 'FNCALL'
and self.FnSEF(child[0])
parent[index] = nr(nt='CONST', t='integer',
value=0, SEF=True)
return
if (hasattr(child[1], 'min')
and lslfuncs.less(child[0].value, child[1].min)
):
# FNCALL < CONST
# when CONST > FNCALL.max: always true
# when CONST <= FNCALL.min: always false
if ('max' in self.symtab[0][child[0].name]
and lslfuncs.less(
self.symtab[0][child[0].name]['max']
, child[1].value)
):
parent[index] = nr(nt='CONST', t='integer',
value=1, SEF=True)
return
if ('min' in self.symtab[0][child[0].name]
and not lslfuncs.less(
self.symtab[0][child[0].name]['min'],
child[1].value)
):
parent[index] = nr(nt='CONST', t='integer',
value=0, SEF=True)
return
parent[index] = nr(nt='CONST', t='integer',
value=1, SEF=True)
return
if child[1].nt == 'CONST' and child[0].SEF:
# when first.max < CONST: always true
# when first.min >= CONST: always false
if (hasattr(child[0], 'max')
and lslfuncs.less(child[0].max, child[1].value)
):
parent[index] = nr(nt='CONST', t='integer',
value=1, SEF=True)
return
if (hasattr(child[0], 'min')
and not lslfuncs.less(child[0].min, child[1].value)
):
parent[index] = nr(nt='CONST', t='integer',
value=0, SEF=True)
return
# Convert 2147483647<i and i<-2147483648 to i&0
if (child[0].t == child[1].t == 'integer'
@ -1571,6 +1557,10 @@ class foldconst(object):
CONSTargs = CONSTargs and child[idx].nt == 'CONST'
sym = self.symtab[0][name]
if 'min' in sym:
node.min = sym['min']
if 'max' in sym:
node.max = sym['max']
OptimizeArgs(node, sym)
try:
if 'Fn' in sym and (self.FnSEF(node) or lslcommon.IsCalc):

View file

@ -39,4 +39,9 @@
, (float)"nan" < (1e40*0)
, 1e40 < 1e40
, -1e40 < 1e40
, llAbs(llGetLinkNumber()-2) >= 0
, llAbs(llGetLinkNumber()-2) < 0
, llAbs(llGetLinkNumber()-2) < -1
, llAbs(llGetLinkNumber()-2) < 3
, llFabs(llSetRegionPos(<1, 1, 1>) - 0.5) < 0
]

View file

@ -38,4 +38,9 @@
, 0
, 0
, 1
, 1
, 0
, 0
, llAbs(~-~-llGetLinkNumber()) < 3
, llFabs(-0.5 + llSetRegionPos(<1., 1., 1.>)) < 0
]