Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: src/compiler/effect-control-linearizer.cc

Issue 2243803002: [turbofan] Fix CheckedInt32Mod lowering for -0 case with negative left hand side. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-5286.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/effect-control-linearizer.h" 5 #include "src/compiler/effect-control-linearizer.h"
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/compiler/access-builder.h" 8 #include "src/compiler/access-builder.h"
9 #include "src/compiler/js-graph.h" 9 #include "src/compiler/js-graph.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 frame_state, effect, control); 1308 frame_state, effect, control);
1309 1309
1310 return ValueEffectControl(value, effect, control); 1310 return ValueEffectControl(value, effect, control);
1311 } 1311 }
1312 1312
1313 EffectControlLinearizer::ValueEffectControl 1313 EffectControlLinearizer::ValueEffectControl
1314 EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state, 1314 EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state,
1315 Node* effect, Node* control) { 1315 Node* effect, Node* control) {
1316 Node* zero = jsgraph()->Int32Constant(0); 1316 Node* zero = jsgraph()->Int32Constant(0);
1317 Node* one = jsgraph()->Int32Constant(1); 1317 Node* one = jsgraph()->Int32Constant(1);
1318 Node* minusone = jsgraph()->Int32Constant(-1);
1319 1318
1320 // General case for signed integer modulus, with optimization for (unknown) 1319 // General case for signed integer modulus, with optimization for (unknown)
1321 // power of 2 right hand side. 1320 // power of 2 right hand side.
1322 // 1321 //
1323 // if 1 < rhs then 1322 // if rhs <= 0 then
1324 // msk = rhs - 1 1323 // rhs = -rhs
1324 // deopt if rhs == 0
1325 // if lhs < 0 then
1326 // let res = lhs % rhs in
1327 // deopt if res == 0
1328 // res
1329 // else
1330 // let msk = rhs - 1 in
1325 // if rhs & msk == 0 then 1331 // if rhs & msk == 0 then
1326 // if lhs < 0 then 1332 // lhs & msk
1327 // -(-lhs & msk)
1328 // else
1329 // lhs & msk
1330 // else 1333 // else
1331 // lhs % rhs 1334 // lhs % rhs
1332 // else
1333 // if rhs < -1 then
1334 // lhs % rhs
1335 // else
1336 // deopt if rhs == 0
1337 // deopt if lhs < 0
1338 // zero
1339 // 1335 //
1340 Node* lhs = node->InputAt(0); 1336 Node* lhs = node->InputAt(0);
1341 Node* rhs = node->InputAt(1); 1337 Node* rhs = node->InputAt(1);
1342 1338
1343 // Check if {rhs} is strictly greater than one. 1339 // Check if {rhs} is not strictly positive.
1344 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), one, rhs); 1340 Node* check0 = graph()->NewNode(machine()->Int32LessThanOrEqual(), rhs, zero);
1345 Node* branch0 = 1341 Node* branch0 =
1346 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 1342 graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control);
1347 1343
1348 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 1344 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1349 Node* etrue0 = effect; 1345 Node* etrue0 = effect;
1350 Node* vtrue0; 1346 Node* vtrue0;
1351 { 1347 {
1352 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minusone); 1348 // Negate {rhs}, might still produce a negative result in case of
1349 // -2^31, but that is handled safely below.
1350 vtrue0 = graph()->NewNode(machine()->Int32Sub(), zero, rhs);
1353 1351
1354 // Check if {rhs} minus one is a valid mask. 1352 // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
1355 Node* check1 = graph()->NewNode( 1353 Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue0, zero);
1356 machine()->Word32Equal(), 1354 if_true0 = etrue0 = graph()->NewNode(
1357 graph()->NewNode(machine()->Word32And(), rhs, msk), zero); 1355 common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
1358 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0); 1356 frame_state, etrue0, if_true0);
1359
1360 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1361 Node* vtrue1;
1362 {
1363 // Check if {lhs} is negative.
1364 Node* check2 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
1365 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1366 check2, if_true1);
1367
1368 // Compute the remainder as {-(-lhs & msk)}.
1369 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
1370 Node* vtrue2 = graph()->NewNode(
1371 machine()->Int32Sub(), zero,
1372 graph()->NewNode(machine()->Word32And(),
1373 graph()->NewNode(machine()->Int32Sub(), zero, lhs),
1374 msk));
1375
1376 // Compute the remainder as {lhs & msk}.
1377 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
1378 Node* vfalse2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
1379
1380 if_true1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
1381 vtrue1 =
1382 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1383 vtrue2, vfalse2, if_true1);
1384 }
1385
1386 // Compute the remainder using the generic {lhs % rhs}.
1387 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1388 Node* vfalse1 =
1389 graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false1);
1390
1391 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1392 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1393 vtrue1, vfalse1, if_true0);
1394 } 1357 }
1395 1358
1396 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 1359 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1397 Node* efalse0 = effect; 1360 Node* efalse0 = effect;
1398 Node* vfalse0; 1361 Node* vfalse0 = rhs;
1362
1363 // At this point {rhs} is either greater than zero or -2^31, both are
1364 // fine for the code that follows.
1365 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1366 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1367 rhs = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1368 vtrue0, vfalse0, control);
1369
1370 // Check if {lhs} is negative.
1371 Node* check1 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
1372 Node* branch1 =
1373 graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control);
1374
1375 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1376 Node* etrue1 = effect;
1377 Node* vtrue1;
1399 { 1378 {
1400 // Check if {rhs} is strictly less than -1. 1379 // Compute the remainder using {lhs % msk}.
1401 Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minusone); 1380 vtrue1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
1402 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue), 1381
1403 check1, if_false0); 1382 // Check if we would have to return -0.
1383 Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue1, zero);
1384 if_true1 = etrue1 =
1385 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
1386 check, frame_state, etrue1, if_true1);
1387 }
1388
1389 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1390 Node* efalse1 = effect;
1391 Node* vfalse1;
1392 {
1393 Node* msk = graph()->NewNode(machine()->Int32Sub(), rhs, one);
1394
1395 // Check if {rhs} minus one is a valid mask.
1396 Node* check2 = graph()->NewNode(
1397 machine()->Word32Equal(),
1398 graph()->NewNode(machine()->Word32And(), rhs, msk), zero);
1399 Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
1400
1401 // Compute the remainder using {lhs & msk}.
1402 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
1403 Node* vtrue2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
1404 1404
1405 // Compute the remainder using the generic {lhs % rhs}. 1405 // Compute the remainder using the generic {lhs % rhs}.
1406 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 1406 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
1407 Node* etrue1 = efalse0; 1407 Node* vfalse2 =
1408 Node* vtrue1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1); 1408 graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false2);
1409 1409
1410 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); 1410 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
1411 Node* efalse1 = efalse0; 1411 vfalse1 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1412 Node* vfalse1; 1412 vtrue2, vfalse2, if_false1);
1413 {
1414 // Ensure that {rhs} is not zero.
1415 Node* check2 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
1416 if_false1 = efalse1 = graph()->NewNode(
1417 common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check2,
1418 frame_state, efalse1, if_false1);
1419
1420 // Now we know that {rhs} is -1, so make sure {lhs} is >= 0, as we would
1421 // otherwise have to return -0.
1422 Node* check3 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
1423 if_false1 = efalse1 =
1424 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
1425 check3, frame_state, efalse1, if_false1);
1426
1427 // The remainder is zero.
1428 vfalse1 = zero;
1429 }
1430
1431 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1432 efalse0 =
1433 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
1434 vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1435 vtrue1, vfalse1, if_false0);
1436 } 1413 }
1437 1414
1438 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); 1415 control = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1439 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); 1416 effect = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, control);
1440 Node* value = 1417 Node* value =
1441 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0, 1418 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue1,
1442 vfalse0, control); 1419 vfalse1, control);
1443 1420
1444 return ValueEffectControl(value, effect, control); 1421 return ValueEffectControl(value, effect, control);
1445 } 1422 }
1446 1423
1447 EffectControlLinearizer::ValueEffectControl 1424 EffectControlLinearizer::ValueEffectControl
1448 EffectControlLinearizer::LowerCheckedUint32Div(Node* node, Node* frame_state, 1425 EffectControlLinearizer::LowerCheckedUint32Div(Node* node, Node* frame_state,
1449 Node* effect, Node* control) { 1426 Node* effect, Node* control) {
1450 Node* zero = jsgraph()->Int32Constant(0); 1427 Node* zero = jsgraph()->Int32Constant(0);
1451 1428
1452 Node* lhs = node->InputAt(0); 1429 Node* lhs = node->InputAt(0);
(...skipping 1856 matching lines...) Expand 10 before | Expand all | Expand 10 after
3309 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 3286 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
3310 Operator::kEliminatable); 3287 Operator::kEliminatable);
3311 to_number_operator_.set(common()->Call(desc)); 3288 to_number_operator_.set(common()->Call(desc));
3312 } 3289 }
3313 return to_number_operator_.get(); 3290 return to_number_operator_.get();
3314 } 3291 }
3315 3292
3316 } // namespace compiler 3293 } // namespace compiler
3317 } // namespace internal 3294 } // namespace internal
3318 } // namespace v8 3295 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-5286.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698