Skip to content

Commit e6df13e

Browse files
author
Vladimir Ivanov
committed
8256054: C2: Floating-point min/max operations on vectors intermittently produce wrong results for NaN values
Reviewed-by: redestad, psandoz, dlong
1 parent 52805f5 commit e6df13e

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ void C2_MacroAssembler::vabsnegf(int opcode, XMMRegister dst, XMMRegister src, i
878878

879879
void C2_MacroAssembler::pminmax(int opcode, BasicType elem_bt, XMMRegister dst, XMMRegister src, XMMRegister tmp) {
880880
assert(opcode == Op_MinV || opcode == Op_MaxV, "sanity");
881+
assert(tmp == xnoreg || elem_bt == T_LONG, "unused");
881882

882883
if (opcode == Op_MinV) {
883884
if (elem_bt == T_BYTE) {
@@ -889,6 +890,7 @@ void C2_MacroAssembler::pminmax(int opcode, BasicType elem_bt, XMMRegister dst,
889890
} else {
890891
assert(elem_bt == T_LONG, "required");
891892
assert(tmp == xmm0, "required");
893+
assert_different_registers(dst, src, tmp);
892894
movdqu(xmm0, dst);
893895
pcmpgtq(xmm0, src);
894896
blendvpd(dst, src); // xmm0 as mask
@@ -903,6 +905,7 @@ void C2_MacroAssembler::pminmax(int opcode, BasicType elem_bt, XMMRegister dst,
903905
} else {
904906
assert(elem_bt == T_LONG, "required");
905907
assert(tmp == xmm0, "required");
908+
assert_different_registers(dst, src, tmp);
906909
movdqu(xmm0, src);
907910
pcmpgtq(xmm0, dst);
908911
blendvpd(dst, src); // xmm0 as mask
@@ -927,6 +930,7 @@ void C2_MacroAssembler::vpminmax(int opcode, BasicType elem_bt,
927930
if (UseAVX > 2 && (vlen_enc == Assembler::AVX_512bit || VM_Version::supports_avx512vl())) {
928931
vpminsq(dst, src1, src2, vlen_enc);
929932
} else {
933+
assert_different_registers(dst, src1, src2);
930934
vpcmpgtq(dst, src1, src2, vlen_enc);
931935
vblendvpd(dst, src1, src2, dst, vlen_enc);
932936
}
@@ -943,6 +947,7 @@ void C2_MacroAssembler::vpminmax(int opcode, BasicType elem_bt,
943947
if (UseAVX > 2 && (vlen_enc == Assembler::AVX_512bit || VM_Version::supports_avx512vl())) {
944948
vpmaxsq(dst, src1, src2, vlen_enc);
945949
} else {
950+
assert_different_registers(dst, src1, src2);
946951
vpcmpgtq(dst, src1, src2, vlen_enc);
947952
vblendvpd(dst, src2, src1, dst, vlen_enc);
948953
}
@@ -960,6 +965,7 @@ void C2_MacroAssembler::vminmax_fp(int opcode, BasicType elem_bt,
960965
assert(opcode == Op_MinV || opcode == Op_MinReductionV ||
961966
opcode == Op_MaxV || opcode == Op_MaxReductionV, "sanity");
962967
assert(elem_bt == T_FLOAT || elem_bt == T_DOUBLE, "sanity");
968+
assert_different_registers(a, b, tmp, atmp, btmp);
963969

964970
bool is_min = (opcode == Op_MinV || opcode == Op_MinReductionV);
965971
bool is_double_word = is_double_word_type(elem_bt);
@@ -1000,6 +1006,7 @@ void C2_MacroAssembler::evminmax_fp(int opcode, BasicType elem_bt,
10001006
assert(opcode == Op_MinV || opcode == Op_MinReductionV ||
10011007
opcode == Op_MaxV || opcode == Op_MaxReductionV, "sanity");
10021008
assert(elem_bt == T_FLOAT || elem_bt == T_DOUBLE, "sanity");
1009+
assert_different_registers(dst, a, b, atmp, btmp);
10031010

10041011
bool is_min = (opcode == Op_MinV || opcode == Op_MinReductionV);
10051012
bool is_double_word = is_double_word_type(elem_bt);

src/hotspot/cpu/x86/x86.ad

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5787,7 +5787,7 @@ instruct evminmaxFP_reg_eavx(vec dst, vec a, vec b, vec atmp, vec btmp) %{
57875787
is_floating_point_type(vector_element_basic_type(n))); // T_FLOAT, T_DOUBLE
57885788
match(Set dst (MinV a b));
57895789
match(Set dst (MaxV a b));
5790-
effect(USE a, USE b, TEMP atmp, TEMP btmp);
5790+
effect(TEMP dst, USE a, USE b, TEMP atmp, TEMP btmp);
57915791
format %{ "vector_minmaxFP $dst,$a,$b\t!using $atmp, $btmp as TEMP" %}
57925792
ins_encode %{
57935793
assert(UseAVX > 2, "required");

0 commit comments

Comments
 (0)