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

View file

@ -39,4 +39,9 @@
, (float)"nan" < (1e40*0) , (float)"nan" < (1e40*0)
, 1e40 < 1e40 , 1e40 < 1e40
, -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
, 0 , 0
, 1 , 1
, 1
, 0
, 0
, llAbs(~-~-llGetLinkNumber()) < 3
, llFabs(-0.5 + llSetRegionPos(<1., 1., 1.>)) < 0
] ]