Skip to content

Commit 109a976

Browse files
committed
6c, 8c: make floating point code NaN-safe
R=ken2 CC=golang-dev https://golang.org/cl/5569071
1 parent 29dbd98 commit 109a976

File tree

2 files changed

+79
-4
lines changed

2 files changed

+79
-4
lines changed

src/cmd/6c/cgen.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,11 +1237,12 @@ void
12371237
boolgen(Node *n, int true, Node *nn)
12381238
{
12391239
int o;
1240-
Prog *p1, *p2;
1240+
Prog *p1, *p2, *p3;
12411241
Node *l, *r, nod, nod1;
12421242
int32 curs;
12431243

12441244
if(debug['g']) {
1245+
print("boolgen %d\n", true);
12451246
prtree(nn, "boolgen lhs");
12461247
prtree(n, "boolgen");
12471248
}
@@ -1353,6 +1354,15 @@ boolgen(Node *n, int true, Node *nn)
13531354
case OLO:
13541355
case OLS:
13551356
o = n->op;
1357+
if(true && typefd[l->type->etype] && (o == OEQ || o == ONE)) {
1358+
// Cannot rewrite !(l == r) into l != r with float64; it breaks NaNs.
1359+
// Jump around instead.
1360+
boolgen(n, 0, Z);
1361+
p1 = p;
1362+
gbranch(OGOTO);
1363+
patch(p1, pc);
1364+
goto com;
1365+
}
13561366
if(true)
13571367
o = comrel[relindex(o)];
13581368
if(l->complex >= FNX && r->complex >= FNX) {
@@ -1367,6 +1377,10 @@ boolgen(Node *n, int true, Node *nn)
13671377
break;
13681378
}
13691379
if(immconst(l)) {
1380+
// NOTE: Reversing the comparison here is wrong
1381+
// for floating point ordering comparisons involving NaN,
1382+
// but we don't have any of those yet so we don't
1383+
// bother worrying about it.
13701384
o = invrel[relindex(o)];
13711385
/* bad, 13 is address of external that becomes constant */
13721386
if(r->addable < INDEXED || r->addable == 13) {
@@ -1388,10 +1402,11 @@ boolgen(Node *n, int true, Node *nn)
13881402
cgen(r, &nod1);
13891403
gopcode(o, l->type, &nod, &nod1);
13901404
regfree(&nod1);
1391-
} else
1405+
} else {
13921406
gopcode(o, l->type, &nod, r);
1407+
}
13931408
regfree(&nod);
1394-
goto com;
1409+
goto fixfloat;
13951410
}
13961411
regalloc(&nod, r, nn);
13971412
cgen(r, &nod);
@@ -1406,6 +1421,33 @@ boolgen(Node *n, int true, Node *nn)
14061421
} else
14071422
gopcode(o, l->type, l, &nod);
14081423
regfree(&nod);
1424+
fixfloat:
1425+
if(typefd[l->type->etype]) {
1426+
switch(o) {
1427+
case OEQ:
1428+
// Already emitted AJEQ; want AJEQ and AJPC.
1429+
p1 = p;
1430+
gbranch(OGOTO);
1431+
p2 = p;
1432+
patch(p1, pc);
1433+
gins(AJPC, Z, Z);
1434+
patch(p2, pc);
1435+
break;
1436+
1437+
case ONE:
1438+
// Already emitted AJNE; want AJNE or AJPS.
1439+
p1 = p;
1440+
gins(AJPS, Z, Z);
1441+
p2 = p;
1442+
gbranch(OGOTO);
1443+
p3 = p;
1444+
patch(p1, pc);
1445+
patch(p2, pc);
1446+
gbranch(OGOTO);
1447+
patch(p3, pc);
1448+
break;
1449+
}
1450+
}
14091451

14101452
com:
14111453
if(nn != Z) {

src/cmd/8c/cgen.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,7 @@ void
12211221
boolgen(Node *n, int true, Node *nn)
12221222
{
12231223
int o;
1224-
Prog *p1, *p2;
1224+
Prog *p1, *p2, *p3;
12251225
Node *l, *r, nod, nod1;
12261226
int32 curs;
12271227

@@ -1346,6 +1346,15 @@ boolgen(Node *n, int true, Node *nn)
13461346
cgen64(n, Z);
13471347
goto com;
13481348
}
1349+
if(true && typefd[l->type->etype] && (o == OEQ || o == ONE)) {
1350+
// Cannot rewrite !(l == r) into l != r with float64; it breaks NaNs.
1351+
// Jump around instead.
1352+
boolgen(n, 0, Z);
1353+
p1 = p;
1354+
gbranch(OGOTO);
1355+
patch(p1, pc);
1356+
goto com;
1357+
}
13491358
if(true)
13501359
o = comrel[relindex(o)];
13511360
if(l->complex >= FNX && r->complex >= FNX) {
@@ -1378,6 +1387,30 @@ boolgen(Node *n, int true, Node *nn)
13781387
} else
13791388
fgopcode(o, l, &fregnode0, 0, 1);
13801389
}
1390+
switch(o) {
1391+
case OEQ:
1392+
// Already emitted AJEQ; want AJEQ and AJPC.
1393+
p1 = p;
1394+
gbranch(OGOTO);
1395+
p2 = p;
1396+
patch(p1, pc);
1397+
gins(AJPC, Z, Z);
1398+
patch(p2, pc);
1399+
break;
1400+
1401+
case ONE:
1402+
// Already emitted AJNE; want AJNE or AJPS.
1403+
p1 = p;
1404+
gins(AJPS, Z, Z);
1405+
p2 = p;
1406+
gbranch(OGOTO);
1407+
p3 = p;
1408+
patch(p1, pc);
1409+
patch(p2, pc);
1410+
gbranch(OGOTO);
1411+
patch(p3, pc);
1412+
break;
1413+
}
13811414
goto com;
13821415
}
13831416
if(l->op == OCONST) {

0 commit comments

Comments
 (0)