Skip to content

Fix too wide OR and AND range inference #11170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Zend/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ static void zend_ssa_range_or(zend_long a, zend_long b, zend_long c, zend_long d
int x = ((a < 0) ? 8 : 0) |
((b < 0) ? 4 : 0) |
((c < 0) ? 2 : 0) |
((d < 0) ? 2 : 0);
((d < 0) ? 1 : 0);
switch (x) {
case 0x0:
case 0x3:
Expand Down Expand Up @@ -484,7 +484,7 @@ static void zend_ssa_range_and(zend_long a, zend_long b, zend_long c, zend_long
int x = ((a < 0) ? 8 : 0) |
((b < 0) ? 4 : 0) |
((c < 0) ? 2 : 0) |
((d < 0) ? 2 : 0);
((d < 0) ? 1 : 0);
switch (x) {
case 0x0:
case 0x3:
Expand Down
145 changes: 145 additions & 0 deletions ext/opcache/tests/opt/gh11170.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
--TEST--
GH-11170 (Too wide OR and AND range inferred)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.opt_debug_level=0x400000
opcache.preload=
--EXTENSIONS--
opcache
--FILE--
<?php
function test_or() {
if (rand() % 10) {
$a = -27;
$b = -20;
} else {
$a = -7;
$b = -10;
}

return $a | $b;
}

function test_and() {
if (rand() % 10) {
$a = -12;
$b = -27;
} else {
$a = -9;
$b = -25;
}

return $a & $b;
}

test_or();
test_and();
?>
--EXPECTF--
$_main:
; (lines=5, args=0, vars=0, tmps=2, ssa_vars=0, no_loops)
; (after dfa pass)
; %s
; return [long] RANGE[1..1]
BB0:
; start exit lines=[0-4]
; level=0
0000 INIT_FCALL 0 %d string("test_or")
0001 DO_UCALL
0002 INIT_FCALL 0 %d string("test_and")
0003 DO_UCALL
0004 RETURN int(1)

test_or:
; (lines=11, args=0, vars=2, tmps=7, ssa_vars=11, no_loops)
; (after dfa pass)
; %s
; return [long] RANGE[-20..-1]
; #0.CV0($a) NOVAL [undef]
; #1.CV1($b) NOVAL [undef]
BB0:
; start lines=[0-3]
; to=(BB2, BB1)
; level=0
; children=(BB1, BB2, BB3)
0000 INIT_FCALL 0 %d string("rand")
0001 #2.V2 [long] = DO_ICALL
0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.V2 [long] int(10)
0003 JMPZ #3.T3 [long] RANGE[MIN..MAX] BB2

BB1:
; follow lines=[4-6]
; from=(BB0)
; to=(BB3)
; idom=BB0
; level=1
0004 #4.CV0($a) [long] RANGE[-27..-27] = QM_ASSIGN int(-27)
0005 #5.CV1($b) [long] RANGE[-20..-20] = QM_ASSIGN int(-20)
0006 JMP BB3

BB2:
; target lines=[7-8]
; from=(BB0)
; to=(BB3)
; idom=BB0
; level=1
0007 #6.CV0($a) [long] RANGE[-7..-7] = QM_ASSIGN int(-7)
0008 #7.CV1($b) [long] RANGE[-10..-10] = QM_ASSIGN int(-10)

BB3:
; follow target exit lines=[9-10]
; from=(BB1, BB2)
; idom=BB0
; level=1
#8.CV0($a) [long] RANGE[-27..-7] = Phi(#4.CV0($a) [long] RANGE[-27..-27], #6.CV0($a) [long] RANGE[-7..-7])
#9.CV1($b) [long] RANGE[-20..-10] = Phi(#5.CV1($b) [long] RANGE[-20..-20], #7.CV1($b) [long] RANGE[-10..-10])
0009 #10.T8 [long] RANGE[-20..-1] = BW_OR #8.CV0($a) [long] RANGE[-27..-7] #9.CV1($b) [long] RANGE[-20..-10]
0010 RETURN #10.T8 [long] RANGE[-20..-1]

test_and:
; (lines=11, args=0, vars=2, tmps=7, ssa_vars=11, no_loops)
; (after dfa pass)
; %s
; return [long] RANGE[-28..-25]
; #0.CV0($a) NOVAL [undef]
; #1.CV1($b) NOVAL [undef]
BB0:
; start lines=[0-3]
; to=(BB2, BB1)
; level=0
; children=(BB1, BB2, BB3)
0000 INIT_FCALL 0 %d string("rand")
0001 #2.V2 [long] = DO_ICALL
0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.V2 [long] int(10)
0003 JMPZ #3.T3 [long] RANGE[MIN..MAX] BB2

BB1:
; follow lines=[4-6]
; from=(BB0)
; to=(BB3)
; idom=BB0
; level=1
0004 #4.CV0($a) [long] RANGE[-12..-12] = QM_ASSIGN int(-12)
0005 #5.CV1($b) [long] RANGE[-27..-27] = QM_ASSIGN int(-27)
0006 JMP BB3

BB2:
; target lines=[7-8]
; from=(BB0)
; to=(BB3)
; idom=BB0
; level=1
0007 #6.CV0($a) [long] RANGE[-9..-9] = QM_ASSIGN int(-9)
0008 #7.CV1($b) [long] RANGE[-25..-25] = QM_ASSIGN int(-25)

BB3:
; follow target exit lines=[9-10]
; from=(BB1, BB2)
; idom=BB0
; level=1
#8.CV0($a) [long] RANGE[-12..-9] = Phi(#4.CV0($a) [long] RANGE[-12..-12], #6.CV0($a) [long] RANGE[-9..-9])
#9.CV1($b) [long] RANGE[-27..-25] = Phi(#5.CV1($b) [long] RANGE[-27..-27], #7.CV1($b) [long] RANGE[-25..-25])
0009 #10.T8 [long] RANGE[-28..-25] = BW_AND #8.CV0($a) [long] RANGE[-12..-9] #9.CV1($b) [long] RANGE[-27..-25]
0010 RETURN #10.T8 [long] RANGE[-28..-25]