Skip to content

Commit 18bb540

Browse files
authored
Merge pull request #7693 from dotty-staging/nan-comparisons
Fix #7677: Fix comparisons involving NaN
2 parents 8698691 + 2e429e0 commit 18bb540

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-15
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,23 +1224,20 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
12241224
}
12251225

12261226
/* Emit code to compare the two top-most stack values using the 'op' operator. */
1227-
private def genCJUMP(success: asm.Label, failure: asm.Label, op: TestOp, tk: BType, targetIfNoJump: asm.Label): Unit = {
1228-
if (targetIfNoJump == success) genCJUMP(failure, success, op.negate(), tk, targetIfNoJump)
1227+
private def genCJUMP(success: asm.Label, failure: asm.Label, op: TestOp, tk: BType, targetIfNoJump: asm.Label, negated: Boolean = false): Unit = {
1228+
if (targetIfNoJump == success) genCJUMP(failure, success, op.negate(), tk, targetIfNoJump, negated = !negated)
12291229
else {
12301230
if (tk.isIntSizedType) { // BOOL, BYTE, CHAR, SHORT, or INT
12311231
bc.emitIF_ICMP(op, success)
12321232
} else if (tk.isRef) { // REFERENCE(_) | ARRAY(_)
12331233
bc.emitIF_ACMP(op, success)
12341234
} else {
12351235
import Primitives._
1236+
def useCmpG = if (negated) op == GT || op == GE else op == LT || op == LE
12361237
(tk: @unchecked) match {
12371238
case LONG => emit(asm.Opcodes.LCMP)
1238-
case FLOAT =>
1239-
if (op == LT || op == LE) emit(asm.Opcodes.FCMPL)
1240-
else emit(asm.Opcodes.FCMPG)
1241-
case DOUBLE =>
1242-
if (op == LT || op == LE) emit(asm.Opcodes.DCMPL)
1243-
else emit(asm.Opcodes.DCMPG)
1239+
case FLOAT => emit(if (useCmpG) asm.Opcodes.FCMPG else asm.Opcodes.FCMPL)
1240+
case DOUBLE => emit(if (useCmpG) asm.Opcodes.DCMPG else asm.Opcodes.DCMPL)
12441241
}
12451242
bc.emitIF(op, success)
12461243
}
@@ -1249,9 +1246,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
12491246
}
12501247

12511248
/* Emits code to compare (and consume) stack-top and zero using the 'op' operator */
1252-
private def genCZJUMP(success: asm.Label, failure: asm.Label, op: TestOp, tk: BType, targetIfNoJump: asm.Label): Unit = {
1249+
private def genCZJUMP(success: asm.Label, failure: asm.Label, op: TestOp, tk: BType, targetIfNoJump: asm.Label, negated: Boolean = false): Unit = {
12531250
import Primitives._
1254-
if (targetIfNoJump == success) genCZJUMP(failure, success, op.negate(), tk, targetIfNoJump)
1251+
if (targetIfNoJump == success) genCZJUMP(failure, success, op.negate(), tk, targetIfNoJump, negated = !negated)
12551252
else {
12561253
if (tk.isIntSizedType) { // BOOL, BYTE, CHAR, SHORT, or INT
12571254
bc.emitIF(op, success)
@@ -1261,18 +1258,17 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
12611258
case NE => bc emitIFNONNULL success
12621259
}
12631260
} else {
1261+
def useCmpG = if (negated) op == GT || op == GE else op == LT || op == LE
12641262
(tk: @unchecked) match {
12651263
case LONG =>
12661264
emit(asm.Opcodes.LCONST_0)
12671265
emit(asm.Opcodes.LCMP)
12681266
case FLOAT =>
12691267
emit(asm.Opcodes.FCONST_0)
1270-
if (op == LT || op == LE) emit(asm.Opcodes.FCMPL)
1271-
else emit(asm.Opcodes.FCMPG)
1268+
emit(if (useCmpG) asm.Opcodes.FCMPG else asm.Opcodes.FCMPL)
12721269
case DOUBLE =>
12731270
emit(asm.Opcodes.DCONST_0)
1274-
if (op == LT || op == LE) emit(asm.Opcodes.DCMPL)
1275-
else emit(asm.Opcodes.DCMPG)
1271+
emit(if (useCmpG) asm.Opcodes.DCMPG else asm.Opcodes.DCMPL)
12761272
}
12771273
bc.emitIF(op, success)
12781274
}
@@ -1287,8 +1283,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
12871283
case ScalaPrimitivesOps.NE => Primitives.NE
12881284
case ScalaPrimitivesOps.LT => Primitives.LT
12891285
case ScalaPrimitivesOps.LE => Primitives.LE
1290-
case ScalaPrimitivesOps.GE => Primitives.GE
12911286
case ScalaPrimitivesOps.GT => Primitives.GT
1287+
case ScalaPrimitivesOps.GE => Primitives.GE
12921288
}
12931289

12941290
/*
File renamed without changes.

tests/run/i7677.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
val a: Double = Double.NaN
4+
val eval = (a <= 0) || (10L <= 0)
5+
assert(!eval)
6+
val eval2 = (Double.NaN <= 0) || (10L <= 0)
7+
assert(!eval2)
8+
9+
val b: Float = Float.NaN
10+
val eval3 = (b <= 0) || (10L <= 0)
11+
assert(!eval3)
12+
val eval4 = (Float.NaN <= 0) || (10L <= 0)
13+
assert(!eval4)
14+
}
15+
}

0 commit comments

Comments
 (0)