Bug #80404 [Opn->Ver]: opcache breaks expression evaluation order when cast as int

From: Date: Tue, 24 Nov 2020 09:20:48 +0000
Subject: Bug #80404 [Opn->Ver]: opcache breaks expression evaluation order when cast as int
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-230562@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80404&edit=1 ID: 80404 Updated by: nikic@php.net Reported by: contact at shivammathur dot com Summary: opcache breaks expression evaluation order when cast as int -Status: Open +Status: Verified Type: Bug Package: opcache Operating System: Tested on Ubuntu 18.04 PHP Version: 8.0Git-2020-11-23 (Git) Block user comment: N Private report: N New Comment: 0000 ASSIGN #0.CV0($firstRowColumns) [undef, ref, any] -> #1.CV0($firstRowColumns) [ref, any] RANGE[63..63] int(63) 0001 INIT_FCALL 1 96 string("var_dump") 0002 #2.T1 [false, long, double, object] RANGE[0..0] = DIV #1.CV0($firstRowColumns) [ref, any] RANGE[63..63] int(120) 0003 #3.T2 [false, long, double, object] RANGE[0..0] = MUL #2.T1 [false, long, double, object] RANGE[0..0] int(100) 0004 #4.T1 [long] RANGE[0..0] = CAST (long) #3.T2 [false, long, double, object] RANGE[0..0] 0005 SEND_VAL #4.T1 [long] RANGE[0..0] 1 0006 DO_ICALL 0007 RETURN int(1) Interesting issue. We determine that ($firstRowColumns / 120) has value range 0..0 and thus that ($firstRowColumns / 120) * 100 stays zero. We probably shouldn't be rounding down the division. While that's the behavior of integer divisions, it does not accurately model PHP's fallback to float division. Previous Comments: ------------------------------------------------------------------------ [2020-11-23 14:12:24] cmb@php.net Ah, thanks! ------------------------------------------------------------------------ [2020-11-23 11:59:03] contact at shivammathur dot com @cmb Can be reproduced with opcache.jit=off, so I'm not sure if this is JIT related. Jit Status - https://github.com/shivammathur/test-setup-php/runs/1441867898?check_suite_focus=true#step:5:67 Test - https://github.com/shivammathur/test-setup-php/runs/1441867898?check_suite_focus=true#step:6:33 ------------------------------------------------------------------------ [2020-11-23 11:53:08] cmb@php.net This looks like a JIT issue. ------------------------------------------------------------------------ [2020-11-23 10:06:00] contact at shivammathur dot com Description: ------------ PHP 8.0.0-dev (cli) (built: Nov 23 2020 00:27:07) ( NTS ) Copyright (c) The PHP Group Zend Engine v4.0.0-dev, Copyright (c) Zend Technologies with Zend OPcache v8.0.0-dev, Copyright (c), by Zend Technologies Build Configuration: https://github.com/shivammathur/php-builder/blob/master/.github/scripts/8.0 Script: https://3v4l.org/kkRIE curl -o test.php -H Accept:text/plain -sL https://3v4l.org/kkRIE for ((i=1;i<=5;i++)); do echo $i php test.php sleep 1 done Above snippet will run the script "https://3v4l.org/kkRIE" multiple times and when opcache kicks in "(int) (63/ 120 * 100)" starts evaluating to 0. This works fine with opcache disabled on PHP 8.0 and with or without opcache on PHP 7.4 Test workflow - https://github.com/shivammathur/test-setup-php/runs/1441325553?check_suite_focus=true#step:6:33 Test script: --------------- <?php $firstRowColumns = 63; var_dump([ $firstRowColumns, ($firstRowColumns / 120), ($firstRowColumns / 120 * 100), (int) ($firstRowColumns / 120 * 100), ]); Expected result: ---------------- (int) (63/ 120 * 100) should evaluate to 52 with opcache enabled on PHP 8.0 Actual result: -------------- (int) (63/ 120 * 100) evaluates to 0 with opcache enabled on PHP 8.0 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=80404&edit=1

« previous php.bugs (#230562) next »