Skip to content

Commit be2ec3c

Browse files
committed
Fix too wide OR and AND range inference
There is a typo which causes the AND and OR range inference to infer a wider range than necessary. Fix this typo. There are many ranges for which the inference is too wide, I just picked one for AND and one for OR that I found through symbolic execution. In this example test, the previous range inferred for test_or was [-27..-1] instead of [-20..-1]. And the previous range inferred for test_and was [-32..-25] instead of [-28..-25].
1 parent 5cbc917 commit be2ec3c

File tree

2 files changed

+147
-2
lines changed

2 files changed

+147
-2
lines changed

Zend/Optimizer/zend_inference.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ static void zend_ssa_range_or(zend_long a, zend_long b, zend_long c, zend_long d
436436
int x = ((a < 0) ? 8 : 0) |
437437
((b < 0) ? 4 : 0) |
438438
((c < 0) ? 2 : 0) |
439-
((d < 0) ? 2 : 0);
439+
((d < 0) ? 1 : 0);
440440
switch (x) {
441441
case 0x0:
442442
case 0x3:
@@ -484,7 +484,7 @@ static void zend_ssa_range_and(zend_long a, zend_long b, zend_long c, zend_long
484484
int x = ((a < 0) ? 8 : 0) |
485485
((b < 0) ? 4 : 0) |
486486
((c < 0) ? 2 : 0) |
487-
((d < 0) ? 2 : 0);
487+
((d < 0) ? 1 : 0);
488488
switch (x) {
489489
case 0x0:
490490
case 0x3:

ext/opcache/tests/opt/gh11170.phpt

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
--TEST--
2+
GH-11170 (Too wide OR and AND range inferred)
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=-1
7+
opcache.opt_debug_level=0x400000
8+
opcache.preload=
9+
--EXTENSIONS--
10+
opcache
11+
--FILE--
12+
<?php
13+
function test_or() {
14+
if (rand() % 10) {
15+
$a = -27;
16+
$b = -20;
17+
} else {
18+
$a = -7;
19+
$b = -10;
20+
}
21+
22+
return $a | $b;
23+
}
24+
25+
function test_and() {
26+
if (rand() % 10) {
27+
$a = -12;
28+
$b = -27;
29+
} else {
30+
$a = -9;
31+
$b = -25;
32+
}
33+
34+
return $a & $b;
35+
}
36+
37+
test_or();
38+
test_and();
39+
?>
40+
--EXPECTF--
41+
$_main:
42+
; (lines=5, args=0, vars=0, tmps=2, ssa_vars=0, no_loops)
43+
; (after dfa pass)
44+
; %s
45+
; return [long] RANGE[1..1]
46+
BB0:
47+
; start exit lines=[0-4]
48+
; level=0
49+
0000 INIT_FCALL 0 %d string("test_or")
50+
0001 DO_UCALL
51+
0002 INIT_FCALL 0 %d string("test_and")
52+
0003 DO_UCALL
53+
0004 RETURN int(1)
54+
55+
test_or:
56+
; (lines=11, args=0, vars=2, tmps=7, ssa_vars=11, no_loops)
57+
; (after dfa pass)
58+
; %s
59+
; return [long] RANGE[-20..-1]
60+
; #0.CV0($a) NOVAL [undef]
61+
; #1.CV1($b) NOVAL [undef]
62+
BB0:
63+
; start lines=[0-3]
64+
; to=(BB2, BB1)
65+
; level=0
66+
; children=(BB1, BB2, BB3)
67+
0000 INIT_FCALL 0 %d string("rand")
68+
0001 #2.V2 [long] = DO_ICALL
69+
0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.V2 [long] int(10)
70+
0003 JMPZ #3.T3 [long] RANGE[MIN..MAX] BB2
71+
72+
BB1:
73+
; follow lines=[4-6]
74+
; from=(BB0)
75+
; to=(BB3)
76+
; idom=BB0
77+
; level=1
78+
0004 #4.CV0($a) [long] RANGE[-27..-27] = QM_ASSIGN int(-27)
79+
0005 #5.CV1($b) [long] RANGE[-20..-20] = QM_ASSIGN int(-20)
80+
0006 JMP BB3
81+
82+
BB2:
83+
; target lines=[7-8]
84+
; from=(BB0)
85+
; to=(BB3)
86+
; idom=BB0
87+
; level=1
88+
0007 #6.CV0($a) [long] RANGE[-7..-7] = QM_ASSIGN int(-7)
89+
0008 #7.CV1($b) [long] RANGE[-10..-10] = QM_ASSIGN int(-10)
90+
91+
BB3:
92+
; follow target exit lines=[9-10]
93+
; from=(BB1, BB2)
94+
; idom=BB0
95+
; level=1
96+
#8.CV0($a) [long] RANGE[-27..-7] = Phi(#4.CV0($a) [long] RANGE[-27..-27], #6.CV0($a) [long] RANGE[-7..-7])
97+
#9.CV1($b) [long] RANGE[-20..-10] = Phi(#5.CV1($b) [long] RANGE[-20..-20], #7.CV1($b) [long] RANGE[-10..-10])
98+
0009 #10.T8 [long] RANGE[-20..-1] = BW_OR #8.CV0($a) [long] RANGE[-27..-7] #9.CV1($b) [long] RANGE[-20..-10]
99+
0010 RETURN #10.T8 [long] RANGE[-20..-1]
100+
101+
test_and:
102+
; (lines=11, args=0, vars=2, tmps=7, ssa_vars=11, no_loops)
103+
; (after dfa pass)
104+
; %s
105+
; return [long] RANGE[-28..-25]
106+
; #0.CV0($a) NOVAL [undef]
107+
; #1.CV1($b) NOVAL [undef]
108+
BB0:
109+
; start lines=[0-3]
110+
; to=(BB2, BB1)
111+
; level=0
112+
; children=(BB1, BB2, BB3)
113+
0000 INIT_FCALL 0 %d string("rand")
114+
0001 #2.V2 [long] = DO_ICALL
115+
0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.V2 [long] int(10)
116+
0003 JMPZ #3.T3 [long] RANGE[MIN..MAX] BB2
117+
118+
BB1:
119+
; follow lines=[4-6]
120+
; from=(BB0)
121+
; to=(BB3)
122+
; idom=BB0
123+
; level=1
124+
0004 #4.CV0($a) [long] RANGE[-12..-12] = QM_ASSIGN int(-12)
125+
0005 #5.CV1($b) [long] RANGE[-27..-27] = QM_ASSIGN int(-27)
126+
0006 JMP BB3
127+
128+
BB2:
129+
; target lines=[7-8]
130+
; from=(BB0)
131+
; to=(BB3)
132+
; idom=BB0
133+
; level=1
134+
0007 #6.CV0($a) [long] RANGE[-9..-9] = QM_ASSIGN int(-9)
135+
0008 #7.CV1($b) [long] RANGE[-25..-25] = QM_ASSIGN int(-25)
136+
137+
BB3:
138+
; follow target exit lines=[9-10]
139+
; from=(BB1, BB2)
140+
; idom=BB0
141+
; level=1
142+
#8.CV0($a) [long] RANGE[-12..-9] = Phi(#4.CV0($a) [long] RANGE[-12..-12], #6.CV0($a) [long] RANGE[-9..-9])
143+
#9.CV1($b) [long] RANGE[-27..-25] = Phi(#5.CV1($b) [long] RANGE[-27..-27], #7.CV1($b) [long] RANGE[-25..-25])
144+
0009 #10.T8 [long] RANGE[-28..-25] = BW_AND #8.CV0($a) [long] RANGE[-12..-9] #9.CV1($b) [long] RANGE[-27..-25]
145+
0010 RETURN #10.T8 [long] RANGE[-28..-25]

0 commit comments

Comments
 (0)