Skip to content

Commit 9f76467

Browse files
committed
+ Add unit test.
+ Remove duplicate False assignment in negated equality comparison.
1 parent 2983995 commit 9f76467

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

lib/Backend/LowerMDShared.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2683,9 +2683,10 @@ void LowererMD::GenerateFastCmXx(IR::Instr *instr)
26832683
}
26842684

26852685
bool isNegOpt = instr->m_opcode == Js::OpCode::CmNeq_A || instr->m_opcode == Js::OpCode::CmSrNeq_A;
2686+
bool initDstToFalse = true;
26862687
if (isIntDst)
26872688
{
2688-
// Fast path for float src when destination is type specialized to int
2689+
// Fast path for int src with destination type specialized to int
26892690
// reg = MOV 0 will get peeped to XOR reg, reg which sets the flags.
26902691
// Put the MOV before the CMP, but use a tmp if dst == src1/src2
26912692
if (dst->IsEqual(src1) || dst->IsEqual(src2))
@@ -2705,7 +2706,7 @@ void LowererMD::GenerateFastCmXx(IR::Instr *instr)
27052706
}
27062707
else if (isFloatSrc)
27072708
{
2708-
// Fast path for float src when destination is not type specialized to int
2709+
// Fast path for float src when destination is a var
27092710
// Assign default value for destination in case either src is NaN
27102711
Assert(dst->IsVar());
27112712
if (isNegOpt)
@@ -2715,6 +2716,7 @@ void LowererMD::GenerateFastCmXx(IR::Instr *instr)
27152716
else
27162717
{
27172718
opnd = this->m_lowerer->LoadLibraryValueOpnd(instr, LibraryValue::ValueFalse);
2719+
initDstToFalse = false;
27182720
}
27192721
Lowerer::InsertMove(tmp, opnd, done);
27202722
}
@@ -2748,7 +2750,9 @@ void LowererMD::GenerateFastCmXx(IR::Instr *instr)
27482750
done->InsertBefore(newInstr);
27492751
}
27502752

2751-
if (!isIntDst)
2753+
// For all cases where the operator is a comparison, we do not want to emit False value
2754+
// since it has already been generated in the if block before.
2755+
if (!isIntDst && initDstToFalse)
27522756
{
27532757
opnd = this->m_lowerer->LoadLibraryValueOpnd(instr, LibraryValue::ValueFalse);
27542758
Lowerer::InsertMove(tmp, opnd, done);

test/Basics/FloatComparison.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
2+
3+
// This tests the fast path for cmxx where either src is type specialized to float
4+
var tests = [
5+
{
6+
name: "NaN equality test",
7+
body: function() {
8+
assert.isTrue(NaN !== NaN);
9+
assert.isTrue(NaN !== 0.5);
10+
assert.isTrue(0.5 !== NaN);
11+
12+
assert.isTrue(NaN != NaN);
13+
assert.isTrue(NaN != 0.5);
14+
assert.isTrue(0.5 != NaN);
15+
16+
assert.isFalse(NaN === NaN);
17+
assert.isFalse(NaN === 0.5);
18+
assert.isFalse(0.5 === NaN);
19+
20+
assert.isFalse(NaN == NaN);
21+
assert.isFalse(NaN == 0.5);
22+
assert.isFalse(0.5 == NaN);
23+
24+
assert.isFalse(NaN > 0.5);
25+
assert.isFalse(NaN >= 0.5);
26+
assert.isFalse(NaN < 0.5);
27+
assert.isFalse(NaN <= 0.5);
28+
}
29+
},
30+
{
31+
name: "Type coercion test",
32+
body: function() {
33+
assert.isTrue('0.5' == 0.5);
34+
assert.isFalse('0.5' === 0.5);
35+
assert.isFalse('NaN' == NaN);
36+
assert.isTrue('NaN' != NaN);
37+
}
38+
},
39+
{
40+
name: "int vs. float",
41+
body: function() {
42+
assert.isFalse(5 == 0.5);
43+
assert.isTrue(5 != 0.5);
44+
assert.isFalse(5 === 0.5);
45+
assert.isTrue(5 !== 0.5);
46+
}
47+
},
48+
{
49+
name: "object vs. float",
50+
body: function() {
51+
assert.isFalse({} == 0.5);
52+
assert.isFalse({} === 0.5);
53+
assert.isTrue({} != 0.5);
54+
assert.isTrue({} !== 0.5);
55+
56+
assert.isFalse({} > 0.5);
57+
assert.isFalse({} >= 0.5);
58+
assert.isFalse({} < 0.5);
59+
assert.isFalse({} <= 0.5);
60+
}
61+
}
62+
];
63+
64+
testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });

test/Basics/rlexe.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,4 +337,10 @@
337337
<tags>exclude_test,exclude_jshost</tags>
338338
</default>
339339
</test>
340+
<test>
341+
<default>
342+
<files>FloatComparison.js</files>
343+
<compile-flags>-args summary -endargs</compile-flags>
344+
</default>
345+
</test>
340346
</regress-exe>

0 commit comments

Comments
 (0)