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

Unified Diff: src/compiler/mips64/instruction-selector-mips64.cc

Issue 2391393003: MIPS64: Fix Word32Compare turbofan operator implementation when comparing signed with unsigned oper… (Closed)
Patch Set: Add runtime checks to make sure optimized compare always works Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: src/compiler/mips64/instruction-selector-mips64.cc
diff --git a/src/compiler/mips64/instruction-selector-mips64.cc b/src/compiler/mips64/instruction-selector-mips64.cc
index 6e937e20d7ae9fdc4c48245b4bf3f8e760504a8a..1b3b6a6d62ccfc598253072bb32c7c83934f145a 100644
--- a/src/compiler/mips64/instruction-selector-mips64.cc
+++ b/src/compiler/mips64/instruction-selector-mips64.cc
@@ -1840,10 +1840,89 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
}
}
+bool IsNodeUnsigned(Node* n) {
+ NodeMatcher m(n);
+
+ if (m.IsLoad()) {
+ LoadRepresentation load_rep = LoadRepresentationOf(n->op());
+ return load_rep.IsUnsigned();
+ } else if (m.IsUnalignedLoad()) {
+ UnalignedLoadRepresentation load_rep =
+ UnalignedLoadRepresentationOf(n->op());
+ return load_rep.IsUnsigned();
+ } else {
+ return m.IsUint32Div() || m.IsUint32LessThan() ||
+ m.IsUint32LessThanOrEqual() || m.IsUint32Mod() ||
+ m.IsUint32MulHigh() || m.IsChangeFloat64ToUint32() ||
+ m.IsTruncateFloat64ToUint32() || m.IsTruncateFloat32ToUint32();
+ }
+}
+
+// Shared routine for multiple word compare operations.
+void VisitFullWord32Compare(InstructionSelector* selector, Node* node,
+ InstructionCode opcode, FlagsContinuation* cont) {
+ Mips64OperandGenerator g(selector);
+ InstructionOperand leftOp = g.TempRegister();
+ InstructionOperand rightOp = g.TempRegister();
+
+ selector->Emit(kMips64Dshl, leftOp, g.UseRegister(node->InputAt(0)),
+ g.TempImmediate(32));
+ selector->Emit(kMips64Dshl, rightOp, g.UseRegister(node->InputAt(1)),
+ g.TempImmediate(32));
+
+ VisitCompare(selector, opcode, leftOp, rightOp, cont);
+}
+
+void VisitOptimizedWord32Compare(InstructionSelector* selector, Node* node,
+ InstructionCode opcode,
+ FlagsContinuation* cont) {
+ if (FLAG_debug_code) {
+ Mips64OperandGenerator g(selector);
+ InstructionOperand leftOp = g.TempRegister();
+ InstructionOperand rightOp = g.TempRegister();
+ InstructionOperand optimizedResult = g.TempRegister();
+ InstructionOperand fullResult = g.TempRegister();
+ FlagsCondition condition = cont->condition();
+ InstructionCode testOpcode = opcode |
+ FlagsConditionField::encode(condition) |
+ FlagsModeField::encode(kFlags_set);
+
+ selector->Emit(testOpcode, optimizedResult, g.UseRegister(node->InputAt(0)),
+ g.UseRegister(node->InputAt(1)));
+
+ selector->Emit(kMips64Dshl, leftOp, g.UseRegister(node->InputAt(0)),
+ g.TempImmediate(32));
+ selector->Emit(kMips64Dshl, rightOp, g.UseRegister(node->InputAt(1)),
+ g.TempImmediate(32));
+ selector->Emit(testOpcode, fullResult, leftOp, rightOp);
+
+ selector->Emit(
+ kMips64AssertEqual, g.NoOutput(), optimizedResult, fullResult,
+ g.TempImmediate(BailoutReason::kUnsupportedNonPrimitiveCompare));
+ }
+
+ VisitWordCompare(selector, node, opcode, cont, false);
+}
void VisitWord32Compare(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
- VisitWordCompare(selector, node, kMips64Cmp, cont, false);
+ // MIPS64 doesn't support Word32 compare instructions. Instead it relies
+ // that the values in registers are correctly sign-extended and uses
+ // Word64 comparison instead. This behavior is correct in most cases,
+ // but doesn't work when comparing signed with unsigned operands.
+ // We could simulate full Word32 compare in all cases but this would
+ // create an unnecessary overhead since unsigned integers are rarely
+ // used in JavaScript.
+ // The solution proposed here tries to match a comparison of signed
+ // with unsigned operand, and perform full Word32Compare only
+ // in those cases. Unfortunately, the solution is not complete because
+ // it might skip cases where Word32 full compare is needed, so
+ // basically it is a hack.
+ if (IsNodeUnsigned(node->InputAt(0)) != IsNodeUnsigned(node->InputAt(1))) {
+ VisitFullWord32Compare(selector, node, kMips64Cmp, cont);
+ } else {
+ VisitOptimizedWord32Compare(selector, node, kMips64Cmp, cont);
+ }
}
« no previous file with comments | « src/compiler/mips64/instruction-codes-mips64.h ('k') | test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698