Skip to content

Optimizer does not account for INF and NAN #16

@Muqsit

Description

@Muqsit

Description

Operator Strength Reduction optimizer directly substitutes a sub-expression x - x with 0, not accounting for INF or NAN values being supplied to x (inf - inf and nan - nan must produce nan). Other affected cases include 0 * inf returning 0 instead of NAN, and sqrt(-1) / sqrt(-1) getting substituted for 1 despite sqrt(-1) === NAN (NAN / NAN === NAN).

As variable resolution occurs during evaluation, x - x cannot be resolved during parsing although 1 - 1 and inf - inf can. One way to address this would be to resolve operations between numeric literal operands during parsing and implement a mechanism to toggle optimizations that disregard INF and NAN (like GCC's FloatingPointMath flags).

Workarounds

  1. Filter out operator strength reduction optimization from ExpressionOptimizerRegistry
    $parser = Parser::createDefault();
    
    $optimizations = new ExpressionOptimizerRegistry();
    foreach($parser->getExpressionOptimizerRegistry()->getRegistered() as $identifier => $value){
    	if(!($value instanceof OperatorStrengthReductionExpressionOptimizer)){
    		$optimizations->register($identifier, $value);
    	}
    }
    
    $parser = new Parser(
    	$parser->getBinaryOperatorRegistry(),
    	$parser->getUnaryOperatorRegistry(),
    	$parser->getConstantRegistry(),
    	$parser->getFunctionRegistry(),
    	$optimizations,
    	$parser->getScanner()
    );
  2. Disable optimizations altogether — $parser = Parser::createUnoptimized();

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions