Reviewers: Michael Starzinger,

Description:
[turbofan] Fix stack->stack double moves for pushing on ia32 and x64.

[email protected]
BUG=

Please review this at https://codereview.chromium.org/1299023002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+65, -6 lines):
  M src/compiler/ia32/instruction-selector-ia32.cc
  M src/compiler/instruction.h
  M src/compiler/x64/instruction-selector-x64.cc
  M test/cctest/compiler/test-run-native-calls.cc


Index: src/compiler/ia32/instruction-selector-ia32.cc
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc index 084024f1b3f89648d6cfcc8bf05aa045ff6c50f0..e363093c2a4fe7fb31b393881403c27f0c4b326f 100644
--- a/src/compiler/ia32/instruction-selector-ia32.cc
+++ b/src/compiler/ia32/instruction-selector-ia32.cc
@@ -857,10 +857,14 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
     for (Node* input : base::Reversed(buffer.pushed_nodes)) {
       // Skip any alignment holes in pushed nodes.
       if (input == nullptr) continue;
+      // TODO(titzer): GapResolver cannot handle stack->stack double moves.
       InstructionOperand value =
           g.CanBeImmediate(input)
               ? g.UseImmediate(input)
-              : IsSupported(ATOM) ? g.UseRegister(input) : g.Use(input);
+              : IsSupported(ATOM) ||
+                        sequence()->IsFloat(GetVirtualRegister(input))
+                    ? g.UseRegister(input)
+                    : g.Use(input);
       Emit(kIA32Push, g.NoOutput(), value);
     }
   }
Index: src/compiler/instruction.h
diff --git a/src/compiler/instruction.h b/src/compiler/instruction.h
index 304d7499d386a35361bc4a0b1da45f1a574c4603..4f6a515f1151fe20f4933b70dd4442c9cd634281 100644
--- a/src/compiler/instruction.h
+++ b/src/compiler/instruction.h
@@ -1023,7 +1023,6 @@ struct PrintableInstructionSequence;

// Represents architecture-specific generated code before, during, and after
 // register allocation.
-// TODO(titzer): s/IsDouble/IsFloat64/
 class InstructionSequence final : public ZoneObject {
  public:
   static InstructionBlocks* InstructionBlocksFor(Zone* zone,
Index: src/compiler/x64/instruction-selector-x64.cc
diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc index 4838f3b69b3e99d4a479ddf79df75a1c4d70503a..b9646e401d2353dcc179902658290e2ca05f0653 100644
--- a/src/compiler/x64/instruction-selector-x64.cc
+++ b/src/compiler/x64/instruction-selector-x64.cc
@@ -1054,7 +1054,7 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
     // Poke any stack arguments.
     for (size_t n = 0; n < buffer.pushed_nodes.size(); ++n) {
       if (Node* input = buffer.pushed_nodes[n]) {
-        int const slot = static_cast<int>(n);
+        int slot = static_cast<int>(n);
         InstructionOperand value = g.CanBeImmediate(input)
                                        ? g.UseImmediate(input)
                                        : g.UseRegister(input);
@@ -1064,11 +1064,14 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
   } else {
     // Push any stack arguments.
     for (Node* input : base::Reversed(buffer.pushed_nodes)) {
-      // TODO(titzer): handle pushing double parameters.
+      // TODO(titzer): GapResolver cannot handle stack->stack double moves.
       InstructionOperand value =
           g.CanBeImmediate(input)
               ? g.UseImmediate(input)
-              : IsSupported(ATOM) ? g.UseRegister(input) : g.Use(input);
+              : IsSupported(ATOM) ||
+                        sequence()->IsFloat(GetVirtualRegister(input))
+                    ? g.UseRegister(input)
+                    : g.Use(input);
       Emit(kX64Push, g.NoOutput(), value);
     }
   }
Index: test/cctest/compiler/test-run-native-calls.cc
diff --git a/test/cctest/compiler/test-run-native-calls.cc b/test/cctest/compiler/test-run-native-calls.cc index 4a963d5f9743d018c10a899d107f66194fbf1b19..fa639e298dd7e98c090f764520380fabb7f0eb57 100644
--- a/test/cctest/compiler/test-run-native-calls.cc
+++ b/test/cctest/compiler/test-run-native-calls.cc
@@ -447,7 +447,7 @@ class Computer {
         Unique<HeapObject> unique =
             Unique<HeapObject>::CreateUninitialized(inner);
         Node* target = raw.HeapConstant(unique);
-        Node** args = zone.NewArray<Node*>(kMaxParamCount);
+        Node** args = zone.NewArray<Node*>(num_params);
         for (int i = 0; i < num_params; i++) {
           args[i] = io.MakeConstant(raw, io.input[i]);
         }
@@ -930,3 +930,56 @@ TEST(Float64Select_stack_params_return_reg) {
     RunSelect<float64, 5>(desc);
   }
 }
+
+
+template <typename CType, int which>
+static void Build_Select_With_Call(CallDescriptor* desc,
+                                   RawMachineAssembler& raw) {
+  Handle<Code> inner = Handle<Code>::null();
+  int num_params = ParamCount(desc);
+  CHECK_LE(num_params, kMaxParamCount);
+  {
+    Isolate* isolate = CcTest::InitIsolateOnce();
+    // Build the actual select.
+    Zone zone;
+    Graph graph(&zone);
+    RawMachineAssembler raw(isolate, &graph, desc);
+    raw.Return(raw.Parameter(which));
+    inner = CompileGraph("Select-indirection", desc, &graph, raw.Export());
+    CHECK(!inner.is_null());
+    CHECK(inner->IsCode());
+  }
+
+  {
+    // Build a call to the function that does the select.
+ Unique<HeapObject> unique = Unique<HeapObject>::CreateUninitialized(inner);
+    Node* target = raw.HeapConstant(unique);
+    Node** args = raw.zone()->NewArray<Node*>(num_params);
+    for (int i = 0; i < num_params; i++) {
+      args[i] = raw.Parameter(i);
+    }
+
+    Node* call = raw.CallN(desc, target, args);
+    raw.Return(call);
+  }
+}
+
+
+TEST(Float64StackParamsToStackParams) {
+  if (DISABLE_NATIVE_STACK_PARAMS) return;
+
+  int rarray[] = {0};
+  Allocator params(nullptr, 0, nullptr, 0);
+  Allocator rets(nullptr, 0, rarray, 1);
+
+  Zone zone;
+  ArgsBuffer<float64>::Sig sig(2);
+  RegisterConfig config(params, rets);
+  CallDescriptor* desc = config.Create(&zone, &sig);
+
+  Run_Computation<float64>(desc, Build_Select_With_Call<float64, 0>,
+                           Compute_Select<float64, 0>, 1098);
+
+  Run_Computation<float64>(desc, Build_Select_With_Call<float64, 1>,
+                           Compute_Select<float64, 1>, 1099);
+}


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to