Skip to content

Commit 8a08730

Browse files
committed
JIT: Fixed NaN handling
1 parent f681f90 commit 8a08730

File tree

2 files changed

+81
-32
lines changed

2 files changed

+81
-32
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8616,51 +8616,47 @@ static int zend_jit_bool_jmpznz(dasm_State **Dst, const zend_op *opline, uint32_
86168616
if (set_bool) {
86178617
if (exit_addr) {
86188618
if (branch_opcode == ZEND_JMPNZ || branch_opcode == ZEND_JMPNZ_EX) {
8619-
| jp >1
86208619
| SET_ZVAL_TYPE_INFO res_addr, IS_TRUE
8620+
| jp &exit_addr
86218621
| jne &exit_addr
8622-
|1:
86238622
| SET_ZVAL_TYPE_INFO res_addr, IS_FALSE
86248623
} else {
8625-
| SET_ZVAL_TYPE_INFO res_addr, IS_FALSE
86268624
| jp >1
8625+
| SET_ZVAL_TYPE_INFO res_addr, IS_FALSE
86278626
| je &exit_addr
86288627
|1:
86298628
| SET_ZVAL_TYPE_INFO res_addr, IS_TRUE
86308629
}
8631-
} else if (false_label != (uint32_t)-1) { // JMPZ_EX
8630+
} else if (false_label != (uint32_t)-1) { // JMPZ_EX (p=>true, z=>false, false=>jmp)
8631+
| jp >1
86328632
| SET_ZVAL_TYPE_INFO res_addr, IS_FALSE
8633-
| jp >1
8634-
| je => false_label
8635-
| SET_ZVAL_TYPE_INFO res_addr, IS_TRUE
8633+
| je => false_label
86368634
|1:
8637-
} else if (true_label != (uint32_t)-1) { // JMPNZ_EX
8638-
| jp >1
86398635
| SET_ZVAL_TYPE_INFO res_addr, IS_TRUE
8640-
| jne => true_label
8641-
|1:
8636+
} else if (true_label != (uint32_t)-1) { // JMPNZ_EX (p=>true, z=>false, true=>jmp)
8637+
| SET_ZVAL_TYPE_INFO res_addr, IS_TRUE
8638+
| jp => true_label
8639+
| jne => true_label
86428640
| SET_ZVAL_TYPE_INFO res_addr, IS_FALSE
8643-
} else if (set_bool_not) { // BOOL_NOT
8641+
} else if (set_bool_not) { // BOOL_NOT (p=>false, z=>true)
8642+
| mov eax, IS_FALSE
86448643
| jp >1
8644+
| jne >1
86458645
| mov eax, IS_TRUE
8646-
| je >2
86478646
|1:
8648-
| mov eax, IS_FALSE
8649-
|2:
86508647
| SET_ZVAL_TYPE_INFO res_addr, eax
8651-
} else { // BOOL
8652-
| jp >1
8648+
} else { // BOOL (p=>true, z=>false)
86538649
| mov eax, IS_TRUE
8654-
| jne >2
8655-
|1:
8650+
| jp >1
8651+
| jne >1
86568652
| mov eax, IS_FALSE
8657-
|2:
8653+
|1:
86588654
| SET_ZVAL_TYPE_INFO res_addr, eax
86598655
}
86608656
} else {
86618657
if (exit_addr) {
86628658
if (branch_opcode == ZEND_JMPNZ || branch_opcode == ZEND_JMPNZ_EX) {
8663-
| jp >1
8659+
| jp &exit_addr
86648660
| jne &exit_addr
86658661
|1:
86668662
} else {
@@ -8670,20 +8666,17 @@ static int zend_jit_bool_jmpznz(dasm_State **Dst, const zend_op *opline, uint32_
86708666
}
86718667
} else {
86728668
ZEND_ASSERT(true_label != (uint32_t)-1 || false_label != (uint32_t)-1);
8673-
if (false_label != (uint32_t)-1) {
8674-
| jp =>false_label
8675-
} else {
8676-
| jp >1
8677-
}
8678-
if (true_label != (uint32_t)-1) {
8679-
| jne =>true_label
8680-
if (false_label != (uint32_t)-1) {
8681-
| jmp =>false_label
8669+
if (false_label != (uint32_t)-1 ) {
8670+
| jp >1
8671+
| je => false_label
8672+
|1:
8673+
if (true_label != (uint32_t)-1) {
8674+
| jmp =>true_label
86828675
}
86838676
} else {
8684-
| je =>false_label
8677+
| jp => true_label
8678+
| jne => true_label
86858679
}
8686-
|1:
86878680
}
86888681
}
86898682
} else if (op1_info & (MAY_BE_ANY - (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG))) {

ext/opcache/tests/jit/nan_002.phpt

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
--TEST--
2+
NaN handling: 002
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
opcache.protect_memory=1
9+
--FILE--
10+
<?php
11+
function test(float $a) {
12+
if ($a) var_dump("1");
13+
if (!$a) var_dump("2");
14+
var_dump((bool) $a);
15+
var_dump(!$a);
16+
echo "\n";
17+
}
18+
function test1(float $a, bool $b) {
19+
var_dump($a && $b); //JMPNZ_EX
20+
}
21+
function test2(float $a, bool $b) {
22+
var_dump($a || $b); // JMPZ_EX
23+
}
24+
test(NAN);
25+
test(1.0);
26+
test(0.0);
27+
28+
test1(NAN, true);
29+
test1(1.0, true);
30+
test1(0.0, true);
31+
echo "\n";
32+
33+
test2(NAN, false);
34+
test2(1.0, false);
35+
test2(0.0, false);
36+
?>
37+
--EXPECT--
38+
string(1) "1"
39+
bool(true)
40+
bool(false)
41+
42+
string(1) "1"
43+
bool(true)
44+
bool(false)
45+
46+
string(1) "2"
47+
bool(false)
48+
bool(true)
49+
50+
bool(true)
51+
bool(true)
52+
bool(false)
53+
54+
bool(true)
55+
bool(true)
56+
bool(false)

0 commit comments

Comments
 (0)