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

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: Simplify ToSimulateWord32Compare 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..d4491d7b08c3af79f0d67f97184633cef928b995 100644
--- a/src/compiler/mips64/instruction-selector-mips64.cc
+++ b/src/compiler/mips64/instruction-selector-mips64.cc
@@ -1840,10 +1840,60 @@ 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 {
ahaas 2016/10/13 08:10:54 I think you also have to deal with parameter and p
ivica.bogosavljevic 2016/10/14 08:16:40 Hi Ahaas! I looked at the code: the Phi and Selec
titzer 2016/10/15 10:45:33 Is it possible to add some extra --debug-code chec
+ 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 VisitSimulateWord32Compare(InstructionSelector* selector, Node* node,
+ InstructionCode opcode, FlagsContinuation* cont,
+ bool commutative) {
+ Mips64OperandGenerator g(selector);
+ Node* left = node->InputAt(0);
+ Node* right = node->InputAt(1);
+ InstructionOperand leftOp = g.TempRegister();
+ InstructionOperand rightOp = g.TempRegister();
+
+ selector->Emit(kMips64Dshl, leftOp, g.UseRegister(left), g.TempImmediate(32));
+ selector->Emit(kMips64Dshl, rightOp, g.UseRegister(right),
+ g.TempImmediate(32));
+
+ VisitCompare(selector, opcode, leftOp, rightOp, cont);
+}
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 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 Word32Compare simulation only
+ // in those cases. Unfortunately, the solution is not complete because
+ // it might skip cases where Word32 compare simulation is needed, so
+ // basically it is a hack.
+ if (IsNodeUnsigned(node->InputAt(0)) != IsNodeUnsigned(node->InputAt(1))) {
+ VisitSimulateWord32Compare(selector, node, kMips64Cmp, cont, false);
+ } else {
+ VisitWordCompare(selector, node, kMips64Cmp, cont, false);
+ }
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698