LCOV - code coverage report
Current view: top level - test/cctest/compiler - test-representation-change.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 365 365 100.0 %
Date: 2019-04-17 Functions: 33 33 100.0 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <limits>
       6             : 
       7             : #include "src/compiler/node-matchers.h"
       8             : #include "src/compiler/representation-change.h"
       9             : #include "src/compiler/type-cache.h"
      10             : #include "src/objects-inl.h"
      11             : #include "test/cctest/cctest.h"
      12             : #include "test/cctest/compiler/codegen-tester.h"
      13             : #include "test/cctest/compiler/graph-builder-tester.h"
      14             : #include "test/cctest/compiler/value-helper.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : namespace compiler {
      19             : 
      20         530 : class RepresentationChangerTester : public HandleAndZoneScope,
      21             :                                     public GraphAndBuilders {
      22             :  public:
      23         530 :   explicit RepresentationChangerTester(int num_parameters = 0)
      24             :       : GraphAndBuilders(main_zone()),
      25             :         javascript_(main_zone()),
      26             :         jsgraph_(main_isolate(), main_graph_, &main_common_, &javascript_,
      27             :                  &main_simplified_, &main_machine_),
      28        1590 :         changer_(&jsgraph_, main_isolate()) {
      29         530 :     Node* s = graph()->NewNode(common()->Start(num_parameters));
      30             :     graph()->SetStart(s);
      31         530 :   }
      32             : 
      33             :   JSOperatorBuilder javascript_;
      34             :   JSGraph jsgraph_;
      35             :   RepresentationChanger changer_;
      36             : 
      37             :   Isolate* isolate() { return main_isolate(); }
      38             :   Graph* graph() { return main_graph_; }
      39        4630 :   CommonOperatorBuilder* common() { return &main_common_; }
      40             :   JSGraph* jsgraph() { return &jsgraph_; }
      41         140 :   RepresentationChanger* changer() { return &changer_; }
      42             : 
      43             :   // TODO(titzer): use ValueChecker / ValueUtil
      44         300 :   void CheckInt32Constant(Node* n, int32_t expected) {
      45             :     Int32Matcher m(n);
      46         300 :     CHECK(m.HasValue());
      47         300 :     CHECK_EQ(expected, m.Value());
      48         300 :   }
      49             : 
      50         290 :   void CheckInt64Constant(Node* n, int64_t expected) {
      51             :     Int64Matcher m(n);
      52         290 :     CHECK(m.HasValue());
      53         290 :     CHECK_EQ(expected, m.Value());
      54         290 :   }
      55             : 
      56         290 :   void CheckUint32Constant(Node* n, uint32_t expected) {
      57             :     Uint32Matcher m(n);
      58         290 :     CHECK(m.HasValue());
      59         290 :     CHECK_EQ(static_cast<int>(expected), static_cast<int>(m.Value()));
      60         290 :   }
      61             : 
      62         830 :   void CheckFloat64Constant(Node* n, double expected) {
      63             :     Float64Matcher m(n);
      64         830 :     CHECK(m.HasValue());
      65         830 :     CHECK_DOUBLE_EQ(expected, m.Value());
      66         830 :   }
      67             : 
      68         875 :   void CheckFloat32Constant(Node* n, float expected) {
      69         875 :     CHECK_EQ(IrOpcode::kFloat32Constant, n->opcode());
      70         875 :     float fval = OpParameter<float>(n->op());
      71         875 :     CHECK_FLOAT_EQ(expected, fval);
      72         875 :   }
      73             : 
      74             :   void CheckHeapConstant(Node* n, HeapObject expected) {
      75             :     HeapObjectMatcher m(n);
      76             :     CHECK(m.HasValue());
      77             :     CHECK_EQ(expected, *m.Value());
      78             :   }
      79             : 
      80         825 :   void CheckNumberConstant(Node* n, double expected) {
      81             :     NumberMatcher m(n);
      82         825 :     CHECK_EQ(IrOpcode::kNumberConstant, n->opcode());
      83         825 :     CHECK(m.HasValue());
      84         825 :     CHECK_DOUBLE_EQ(expected, m.Value());
      85         825 :   }
      86             : 
      87         610 :   Node* Parameter(int index = 0) {
      88         610 :     Node* n = graph()->NewNode(common()->Parameter(index), graph()->start());
      89             :     NodeProperties::SetType(n, Type::Any());
      90         610 :     return n;
      91             :   }
      92             : 
      93        4020 :   Node* Return(Node* input) {
      94        8040 :     Node* n = graph()->NewNode(common()->Return(), jsgraph()->Int32Constant(0),
      95             :                                input, graph()->start(), graph()->start());
      96        4020 :     return n;
      97             :   }
      98             : 
      99          35 :   void CheckTypeError(MachineRepresentation from, Type from_type,
     100             :                       MachineRepresentation to) {
     101          35 :     changer()->testing_type_errors_ = true;
     102          35 :     changer()->type_error_ = false;
     103          35 :     Node* n = Parameter(0);
     104          35 :     Node* use = Return(n);
     105          70 :     Node* c = changer()->GetRepresentationFor(n, from, from_type, use,
     106          35 :                                               UseInfo(to, Truncation::None()));
     107          35 :     CHECK(changer()->type_error_);
     108          35 :     CHECK_EQ(n, c);
     109          35 :   }
     110             : 
     111         105 :   void CheckNop(MachineRepresentation from, Type from_type,
     112             :                 MachineRepresentation to) {
     113         105 :     Node* n = Parameter(0);
     114         105 :     Node* use = Return(n);
     115         210 :     Node* c = changer()->GetRepresentationFor(n, from, from_type, use,
     116         105 :                                               UseInfo(to, Truncation::None()));
     117         105 :     CHECK_EQ(n, c);
     118         105 :   }
     119             : };
     120             : 
     121             : const MachineType kMachineTypes[] = {
     122             :     MachineType::Float32(),   MachineType::Float64(),
     123             :     MachineType::Int8(),      MachineType::Uint8(),
     124             :     MachineType::Int16(),     MachineType::Uint16(),
     125             :     MachineType::Int32(),     MachineType::Uint32(),
     126             :     MachineType::Int64(),     MachineType::Uint64(),
     127             :     MachineType::AnyTagged(), MachineType::AnyCompressed()};
     128             : 
     129       26644 : TEST(BoolToBit_constant) {
     130           5 :   RepresentationChangerTester r;
     131             : 
     132           5 :   Node* true_node = r.jsgraph()->TrueConstant();
     133           5 :   Node* true_use = r.Return(true_node);
     134          10 :   Node* true_bit = r.changer()->GetRepresentationFor(
     135             :       true_node, MachineRepresentation::kTagged, Type::None(), true_use,
     136           5 :       UseInfo(MachineRepresentation::kBit, Truncation::None()));
     137           5 :   r.CheckInt32Constant(true_bit, 1);
     138             : 
     139           5 :   Node* false_node = r.jsgraph()->FalseConstant();
     140           5 :   Node* false_use = r.Return(false_node);
     141          10 :   Node* false_bit = r.changer()->GetRepresentationFor(
     142             :       false_node, MachineRepresentation::kTagged, Type::None(), false_use,
     143           5 :       UseInfo(MachineRepresentation::kBit, Truncation::None()));
     144           5 :   r.CheckInt32Constant(false_bit, 0);
     145           5 : }
     146             : 
     147       26644 : TEST(ToTagged_constant) {
     148           5 :   RepresentationChangerTester r;
     149             : 
     150         495 :   for (double i : ValueHelper::float64_vector()) {
     151         245 :     Node* n = r.jsgraph()->Constant(i);
     152         245 :     Node* use = r.Return(n);
     153         490 :     Node* c = r.changer()->GetRepresentationFor(
     154             :         n, MachineRepresentation::kFloat64, Type::None(), use,
     155         245 :         UseInfo(MachineRepresentation::kTagged, Truncation::None()));
     156         245 :     r.CheckNumberConstant(c, i);
     157             :   }
     158             : 
     159         585 :   for (int i : ValueHelper::int32_vector()) {
     160         290 :     Node* n = r.jsgraph()->Constant(i);
     161         290 :     Node* use = r.Return(n);
     162         580 :     Node* c = r.changer()->GetRepresentationFor(
     163             :         n, MachineRepresentation::kWord32, Type::Signed32(), use,
     164         290 :         UseInfo(MachineRepresentation::kTagged, Truncation::None()));
     165         290 :     r.CheckNumberConstant(c, i);
     166             :   }
     167             : 
     168         585 :   for (uint32_t i : ValueHelper::uint32_vector()) {
     169         290 :     Node* n = r.jsgraph()->Constant(i);
     170         290 :     Node* use = r.Return(n);
     171         580 :     Node* c = r.changer()->GetRepresentationFor(
     172             :         n, MachineRepresentation::kWord32, Type::Unsigned32(), use,
     173         290 :         UseInfo(MachineRepresentation::kTagged, Truncation::None()));
     174         290 :     r.CheckNumberConstant(c, i);
     175             :   }
     176           5 : }
     177             : 
     178       26644 : TEST(ToFloat64_constant) {
     179           5 :   RepresentationChangerTester r;
     180             : 
     181         495 :   for (double i : ValueHelper::float64_vector()) {
     182         245 :     Node* n = r.jsgraph()->Constant(i);
     183         245 :     Node* use = r.Return(n);
     184         490 :     Node* c = r.changer()->GetRepresentationFor(
     185             :         n, MachineRepresentation::kTagged, Type::None(), use,
     186         245 :         UseInfo(MachineRepresentation::kFloat64, Truncation::None()));
     187         245 :     r.CheckFloat64Constant(c, i);
     188             :   }
     189             : 
     190         585 :   for (int i : ValueHelper::int32_vector()) {
     191         290 :     Node* n = r.jsgraph()->Constant(i);
     192         290 :     Node* use = r.Return(n);
     193         580 :     Node* c = r.changer()->GetRepresentationFor(
     194             :         n, MachineRepresentation::kWord32, Type::Signed32(), use,
     195         290 :         UseInfo(MachineRepresentation::kFloat64, Truncation::None()));
     196         290 :     r.CheckFloat64Constant(c, i);
     197             :   }
     198             : 
     199         585 :   for (uint32_t i : ValueHelper::uint32_vector()) {
     200         290 :     Node* n = r.jsgraph()->Constant(i);
     201         290 :     Node* use = r.Return(n);
     202         580 :     Node* c = r.changer()->GetRepresentationFor(
     203             :         n, MachineRepresentation::kWord32, Type::Unsigned32(), use,
     204         290 :         UseInfo(MachineRepresentation::kFloat64, Truncation::None()));
     205         290 :     r.CheckFloat64Constant(c, i);
     206             :   }
     207             : 
     208             :   {
     209           5 :     Node* n = r.jsgraph()->Constant(0);
     210           5 :     Node* use = r.Return(n);
     211          15 :     Node* c = r.changer()->GetRepresentationFor(
     212             :         n, MachineRepresentation::kWord64, Type::Range(0, 0, r.zone()), use,
     213           5 :         UseInfo(MachineRepresentation::kFloat64, Truncation::None()));
     214           5 :     r.CheckFloat64Constant(c, 0);
     215             :   }
     216           5 : }
     217             : 
     218             : 
     219             : static bool IsFloat32Int32(int32_t val) {
     220         290 :   return val >= -(1 << 23) && val <= (1 << 23);
     221             : }
     222             : 
     223             : 
     224             : static bool IsFloat32Uint32(uint32_t val) { return val <= (1 << 23); }
     225             : 
     226             : 
     227       26644 : TEST(ToFloat32_constant) {
     228           5 :   RepresentationChangerTester r;
     229             : 
     230        1155 :   for (double i : ValueHelper::float32_vector()) {
     231         575 :     Node* n = r.jsgraph()->Constant(i);
     232         575 :     Node* use = r.Return(n);
     233        1150 :     Node* c = r.changer()->GetRepresentationFor(
     234             :         n, MachineRepresentation::kTagged, Type::None(), use,
     235         575 :         UseInfo(MachineRepresentation::kFloat32, Truncation::None()));
     236         575 :     r.CheckFloat32Constant(c, i);
     237             :   }
     238             : 
     239         585 :   for (int i : ValueHelper::int32_vector()) {
     240         290 :     if (!IsFloat32Int32(i)) continue;
     241         155 :     Node* n = r.jsgraph()->Constant(i);
     242         155 :     Node* use = r.Return(n);
     243         310 :     Node* c = r.changer()->GetRepresentationFor(
     244             :         n, MachineRepresentation::kWord32, Type::Signed32(), use,
     245         155 :         UseInfo(MachineRepresentation::kFloat32, Truncation::None()));
     246         155 :     r.CheckFloat32Constant(c, static_cast<float>(i));
     247             :   }
     248             : 
     249         585 :   for (uint32_t i : ValueHelper::uint32_vector()) {
     250         290 :     if (!IsFloat32Uint32(i)) continue;
     251         145 :     Node* n = r.jsgraph()->Constant(i);
     252         145 :     Node* use = r.Return(n);
     253         290 :     Node* c = r.changer()->GetRepresentationFor(
     254             :         n, MachineRepresentation::kWord32, Type::Unsigned32(), use,
     255         145 :         UseInfo(MachineRepresentation::kFloat32, Truncation::None()));
     256         145 :     r.CheckFloat32Constant(c, static_cast<float>(i));
     257             :   }
     258           5 : }
     259             : 
     260       26644 : TEST(ToInt32_constant) {
     261           5 :   RepresentationChangerTester r;
     262             :   {
     263         585 :     FOR_INT32_INPUTS(i) {
     264         290 :       Node* n = r.jsgraph()->Constant(i);
     265         290 :       Node* use = r.Return(n);
     266         580 :       Node* c = r.changer()->GetRepresentationFor(
     267             :           n, MachineRepresentation::kTagged, Type::Signed32(), use,
     268         290 :           UseInfo(MachineRepresentation::kWord32, Truncation::None()));
     269         290 :       r.CheckInt32Constant(c, i);
     270             :     }
     271             :   }
     272           5 : }
     273             : 
     274       26644 : TEST(ToUint32_constant) {
     275           5 :   RepresentationChangerTester r;
     276         585 :   FOR_UINT32_INPUTS(i) {
     277         290 :     Node* n = r.jsgraph()->Constant(static_cast<double>(i));
     278         290 :     Node* use = r.Return(n);
     279         580 :     Node* c = r.changer()->GetRepresentationFor(
     280             :         n, MachineRepresentation::kTagged, Type::Unsigned32(), use,
     281         290 :         UseInfo(MachineRepresentation::kWord32, Truncation::None()));
     282         290 :     r.CheckUint32Constant(c, i);
     283             :   }
     284           5 : }
     285             : 
     286       26644 : TEST(ToInt64_constant) {
     287           5 :   RepresentationChangerTester r;
     288         585 :   FOR_INT32_INPUTS(i) {
     289         290 :     Node* n = r.jsgraph()->Constant(i);
     290         290 :     Node* use = r.Return(n);
     291         580 :     Node* c = r.changer()->GetRepresentationFor(
     292         290 :         n, MachineRepresentation::kTagged, TypeCache::Get()->kSafeInteger, use,
     293         290 :         UseInfo(MachineRepresentation::kWord64, Truncation::None()));
     294         290 :     r.CheckInt64Constant(c, i);
     295             :   }
     296           5 : }
     297             : 
     298         300 : static void CheckChange(IrOpcode::Value expected, MachineRepresentation from,
     299             :                         Type from_type, UseInfo use_info) {
     300         300 :   RepresentationChangerTester r;
     301             : 
     302         300 :   Node* n = r.Parameter();
     303         300 :   Node* use = r.Return(n);
     304             :   Node* c =
     305         300 :       r.changer()->GetRepresentationFor(n, from, from_type, use, use_info);
     306             : 
     307         300 :   CHECK_NE(c, n);
     308         300 :   CHECK_EQ(expected, c->opcode());
     309         300 :   CHECK_EQ(n, c->InputAt(0));
     310             : 
     311         300 :   if (expected == IrOpcode::kCheckedFloat64ToInt32 ||
     312             :       expected == IrOpcode::kCheckedFloat64ToInt64) {
     313             :     CheckForMinusZeroMode mode =
     314          40 :         from_type.Maybe(Type::MinusZero())
     315             :             ? use_info.minus_zero_check()
     316          40 :             : CheckForMinusZeroMode::kDontCheckForMinusZero;
     317          40 :     CHECK_EQ(mode, CheckMinusZeroParametersOf(c->op()).mode());
     318             :   }
     319         300 : }
     320             : 
     321         255 : static void CheckChange(IrOpcode::Value expected, MachineRepresentation from,
     322             :                         Type from_type, MachineRepresentation to) {
     323         510 :   CheckChange(expected, from, from_type, UseInfo(to, Truncation::Any()));
     324         255 : }
     325             : 
     326         115 : static void CheckTwoChanges(IrOpcode::Value expected2,
     327             :                             IrOpcode::Value expected1,
     328             :                             MachineRepresentation from, Type from_type,
     329             :                             MachineRepresentation to, UseInfo use_info) {
     330         115 :   RepresentationChangerTester r;
     331             : 
     332         115 :   Node* n = r.Parameter();
     333         115 :   Node* use = r.Return(n);
     334             :   Node* c1 =
     335         115 :       r.changer()->GetRepresentationFor(n, from, from_type, use, use_info);
     336             : 
     337         115 :   CHECK_NE(c1, n);
     338         115 :   CHECK_EQ(expected1, c1->opcode());
     339             :   Node* c2 = c1->InputAt(0);
     340         115 :   CHECK_NE(c2, n);
     341         115 :   CHECK_EQ(expected2, c2->opcode());
     342         115 :   CHECK_EQ(n, c2->InputAt(0));
     343         115 : }
     344             : 
     345         110 : static void CheckTwoChanges(IrOpcode::Value expected2,
     346             :                             IrOpcode::Value expected1,
     347             :                             MachineRepresentation from, Type from_type,
     348             :                             MachineRepresentation to) {
     349         220 :   CheckTwoChanges(expected2, expected1, from, from_type, to,
     350         110 :                   UseInfo(to, Truncation::None()));
     351         110 : }
     352             : 
     353          55 : static void CheckChange(IrOpcode::Value expected, MachineRepresentation from,
     354             :                         Type from_type, MachineRepresentation to,
     355             :                         UseInfo use_info) {
     356          55 :   RepresentationChangerTester r;
     357             : 
     358          55 :   Node* n = r.Parameter();
     359          55 :   Node* use = r.Return(n);
     360             :   Node* c =
     361          55 :       r.changer()->GetRepresentationFor(n, from, from_type, use, use_info);
     362             : 
     363          55 :   CHECK_NE(c, n);
     364          55 :   CHECK_EQ(expected, c->opcode());
     365          55 :   CHECK_EQ(n, c->InputAt(0));
     366          55 : }
     367             : 
     368       26644 : TEST(Word64) {
     369             :   CheckChange(IrOpcode::kChangeInt32ToInt64, MachineRepresentation::kWord8,
     370           5 :               TypeCache::Get()->kInt8, MachineRepresentation::kWord64);
     371             :   CheckChange(IrOpcode::kChangeUint32ToUint64, MachineRepresentation::kWord8,
     372           5 :               TypeCache::Get()->kUint8, MachineRepresentation::kWord64);
     373             :   CheckChange(IrOpcode::kChangeInt32ToInt64, MachineRepresentation::kWord16,
     374           5 :               TypeCache::Get()->kInt16, MachineRepresentation::kWord64);
     375             :   CheckChange(IrOpcode::kChangeUint32ToUint64, MachineRepresentation::kWord16,
     376           5 :               TypeCache::Get()->kUint16, MachineRepresentation::kWord64);
     377             :   CheckChange(IrOpcode::kChangeInt32ToInt64, MachineRepresentation::kWord32,
     378           5 :               Type::Signed32(), MachineRepresentation::kWord64);
     379             :   CheckChange(IrOpcode::kChangeUint32ToUint64, MachineRepresentation::kWord32,
     380           5 :               Type::Unsigned32(), MachineRepresentation::kWord64);
     381             : 
     382             :   CheckChange(IrOpcode::kTruncateInt64ToInt32, MachineRepresentation::kWord64,
     383           5 :               Type::Signed32(), MachineRepresentation::kWord32);
     384             :   CheckChange(IrOpcode::kTruncateInt64ToInt32, MachineRepresentation::kWord64,
     385           5 :               Type::Unsigned32(), MachineRepresentation::kWord32);
     386             :   CheckChange(IrOpcode::kTruncateInt64ToInt32, MachineRepresentation::kWord64,
     387           5 :               TypeCache::Get()->kSafeInteger, MachineRepresentation::kWord32,
     388           5 :               UseInfo::TruncatingWord32());
     389          10 :   CheckChange(
     390             :       IrOpcode::kCheckedInt64ToInt32, MachineRepresentation::kWord64,
     391           5 :       TypeCache::Get()->kSafeInteger, MachineRepresentation::kWord32,
     392           5 :       UseInfo::CheckedSigned32AsWord32(kIdentifyZeros, VectorSlotPair()));
     393          10 :   CheckChange(
     394             :       IrOpcode::kCheckedUint64ToInt32, MachineRepresentation::kWord64,
     395           5 :       TypeCache::Get()->kPositiveSafeInteger, MachineRepresentation::kWord32,
     396           5 :       UseInfo::CheckedSigned32AsWord32(kIdentifyZeros, VectorSlotPair()));
     397             : 
     398             :   CheckChange(IrOpcode::kChangeFloat64ToInt64, MachineRepresentation::kFloat64,
     399           5 :               Type::Signed32(), MachineRepresentation::kWord64);
     400             :   CheckChange(IrOpcode::kChangeFloat64ToInt64, MachineRepresentation::kFloat64,
     401           5 :               Type::Unsigned32(), MachineRepresentation::kWord64);
     402             :   CheckChange(IrOpcode::kChangeFloat64ToInt64, MachineRepresentation::kFloat64,
     403           5 :               TypeCache::Get()->kSafeInteger, MachineRepresentation::kWord64);
     404             :   CheckChange(IrOpcode::kChangeFloat64ToInt64, MachineRepresentation::kFloat64,
     405           5 :               TypeCache::Get()->kInt64, MachineRepresentation::kWord64);
     406             :   CheckChange(IrOpcode::kChangeFloat64ToUint64, MachineRepresentation::kFloat64,
     407           5 :               TypeCache::Get()->kUint64, MachineRepresentation::kWord64);
     408          10 :   CheckChange(
     409             :       IrOpcode::kCheckedFloat64ToInt64, MachineRepresentation::kFloat64,
     410             :       Type::Number(), MachineRepresentation::kWord64,
     411           5 :       UseInfo::CheckedSigned64AsWord64(kIdentifyZeros, VectorSlotPair()));
     412             : 
     413             :   CheckChange(IrOpcode::kChangeInt64ToFloat64, MachineRepresentation::kWord64,
     414           5 :               Type::Signed32(), MachineRepresentation::kFloat64);
     415             :   CheckChange(IrOpcode::kChangeInt64ToFloat64, MachineRepresentation::kWord64,
     416           5 :               Type::Unsigned32(), MachineRepresentation::kFloat64);
     417             :   CheckChange(IrOpcode::kChangeInt64ToFloat64, MachineRepresentation::kWord64,
     418           5 :               TypeCache::Get()->kSafeInteger, MachineRepresentation::kFloat64);
     419             : 
     420             :   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
     421             :                   IrOpcode::kChangeFloat64ToInt64,
     422             :                   MachineRepresentation::kFloat32, Type::Signed32(),
     423           5 :                   MachineRepresentation::kWord64);
     424             :   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
     425             :                   IrOpcode::kChangeFloat64ToInt64,
     426             :                   MachineRepresentation::kFloat32, Type::Unsigned32(),
     427           5 :                   MachineRepresentation::kWord64);
     428             :   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
     429             :                   IrOpcode::kChangeFloat64ToInt64,
     430           5 :                   MachineRepresentation::kFloat32, TypeCache::Get()->kInt64,
     431           5 :                   MachineRepresentation::kWord64);
     432             :   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
     433             :                   IrOpcode::kChangeFloat64ToUint64,
     434           5 :                   MachineRepresentation::kFloat32, TypeCache::Get()->kUint64,
     435           5 :                   MachineRepresentation::kWord64);
     436          10 :   CheckTwoChanges(
     437             :       IrOpcode::kChangeFloat32ToFloat64, IrOpcode::kCheckedFloat64ToInt64,
     438             :       MachineRepresentation::kFloat32, Type::Number(),
     439             :       MachineRepresentation::kWord64,
     440           5 :       UseInfo::CheckedSigned64AsWord64(kIdentifyZeros, VectorSlotPair()));
     441             : 
     442             :   CheckTwoChanges(IrOpcode::kChangeInt64ToFloat64,
     443             :                   IrOpcode::kTruncateFloat64ToFloat32,
     444             :                   MachineRepresentation::kWord64, Type::Signed32(),
     445           5 :                   MachineRepresentation::kFloat32);
     446             : 
     447             :   CheckChange(IrOpcode::kChangeTaggedToInt64, MachineRepresentation::kTagged,
     448           5 :               Type::Signed32(), MachineRepresentation::kWord64);
     449             :   CheckChange(IrOpcode::kChangeTaggedToInt64, MachineRepresentation::kTagged,
     450           5 :               Type::Unsigned32(), MachineRepresentation::kWord64);
     451             :   CheckChange(IrOpcode::kChangeTaggedToInt64, MachineRepresentation::kTagged,
     452           5 :               TypeCache::Get()->kSafeInteger, MachineRepresentation::kWord64);
     453             :   CheckChange(IrOpcode::kChangeTaggedToInt64, MachineRepresentation::kTagged,
     454           5 :               TypeCache::Get()->kInt64, MachineRepresentation::kWord64);
     455             :   CheckChange(IrOpcode::kChangeTaggedSignedToInt64,
     456             :               MachineRepresentation::kTaggedSigned, Type::SignedSmall(),
     457           5 :               MachineRepresentation::kWord64);
     458          10 :   CheckChange(
     459             :       IrOpcode::kCheckedTaggedToInt64, MachineRepresentation::kTagged,
     460             :       Type::Number(), MachineRepresentation::kWord64,
     461           5 :       UseInfo::CheckedSigned64AsWord64(kIdentifyZeros, VectorSlotPair()));
     462          10 :   CheckChange(
     463             :       IrOpcode::kCheckedTaggedToInt64, MachineRepresentation::kTaggedPointer,
     464             :       Type::Number(), MachineRepresentation::kWord64,
     465           5 :       UseInfo::CheckedSigned64AsWord64(kIdentifyZeros, VectorSlotPair()));
     466             : 
     467             :   CheckTwoChanges(IrOpcode::kTruncateInt64ToInt32,
     468             :                   IrOpcode::kChangeInt31ToTaggedSigned,
     469             :                   MachineRepresentation::kWord64, Type::Signed31(),
     470           5 :                   MachineRepresentation::kTagged);
     471             :   CheckTwoChanges(IrOpcode::kTruncateInt64ToInt32,
     472             :                   IrOpcode::kChangeInt32ToTagged,
     473             :                   MachineRepresentation::kWord64, Type::Signed32(),
     474           5 :                   MachineRepresentation::kTagged);
     475             :   CheckTwoChanges(IrOpcode::kTruncateInt64ToInt32,
     476             :                   IrOpcode::kChangeUint32ToTagged,
     477             :                   MachineRepresentation::kWord64, Type::Unsigned32(),
     478           5 :                   MachineRepresentation::kTagged);
     479             :   CheckChange(IrOpcode::kChangeInt64ToTagged, MachineRepresentation::kWord64,
     480           5 :               TypeCache::Get()->kSafeInteger, MachineRepresentation::kTagged);
     481             :   CheckChange(IrOpcode::kChangeUint64ToTagged, MachineRepresentation::kWord64,
     482           5 :               TypeCache::Get()->kPositiveSafeInteger,
     483           5 :               MachineRepresentation::kTagged);
     484             : 
     485             :   CheckTwoChanges(IrOpcode::kTruncateInt64ToInt32,
     486             :                   IrOpcode::kChangeInt31ToTaggedSigned,
     487             :                   MachineRepresentation::kWord64, Type::Signed31(),
     488           5 :                   MachineRepresentation::kTaggedSigned);
     489             :   if (SmiValuesAre32Bits()) {
     490             :     CheckTwoChanges(IrOpcode::kTruncateInt64ToInt32,
     491             :                     IrOpcode::kChangeInt32ToTagged,
     492             :                     MachineRepresentation::kWord64, Type::Signed32(),
     493           5 :                     MachineRepresentation::kTaggedSigned);
     494             :   }
     495          10 :   CheckChange(IrOpcode::kCheckedInt64ToTaggedSigned,
     496           5 :               MachineRepresentation::kWord64, TypeCache::Get()->kSafeInteger,
     497             :               MachineRepresentation::kTaggedSigned,
     498           5 :               UseInfo::CheckedSignedSmallAsTaggedSigned(VectorSlotPair()));
     499          10 :   CheckChange(IrOpcode::kCheckedUint64ToTaggedSigned,
     500             :               MachineRepresentation::kWord64,
     501           5 :               TypeCache::Get()->kPositiveSafeInteger,
     502             :               MachineRepresentation::kTaggedSigned,
     503           5 :               UseInfo::CheckedSignedSmallAsTaggedSigned(VectorSlotPair()));
     504             : 
     505             :   CheckTwoChanges(
     506             :       IrOpcode::kChangeInt64ToFloat64, IrOpcode::kChangeFloat64ToTaggedPointer,
     507           5 :       MachineRepresentation::kWord64, TypeCache::Get()->kSafeInteger,
     508           5 :       MachineRepresentation::kTaggedPointer);
     509           5 : }
     510             : 
     511       26644 : TEST(SingleChanges) {
     512             :   CheckChange(IrOpcode::kChangeTaggedToBit, MachineRepresentation::kTagged,
     513           5 :               Type::Boolean(), MachineRepresentation::kBit);
     514             :   CheckChange(IrOpcode::kChangeBitToTagged, MachineRepresentation::kBit,
     515           5 :               Type::Boolean(), MachineRepresentation::kTagged);
     516             : 
     517             :   CheckChange(IrOpcode::kChangeInt31ToTaggedSigned,
     518             :               MachineRepresentation::kWord32, Type::Signed31(),
     519           5 :               MachineRepresentation::kTagged);
     520             :   CheckChange(IrOpcode::kChangeInt32ToTagged, MachineRepresentation::kWord32,
     521           5 :               Type::Signed32(), MachineRepresentation::kTagged);
     522             :   CheckChange(IrOpcode::kChangeUint32ToTagged, MachineRepresentation::kWord32,
     523           5 :               Type::Unsigned32(), MachineRepresentation::kTagged);
     524             :   CheckChange(IrOpcode::kChangeFloat64ToTagged, MachineRepresentation::kFloat64,
     525           5 :               Type::Number(), MachineRepresentation::kTagged);
     526             :   CheckTwoChanges(IrOpcode::kChangeFloat64ToInt32,
     527             :                   IrOpcode::kChangeInt31ToTaggedSigned,
     528             :                   MachineRepresentation::kFloat64, Type::Signed31(),
     529           5 :                   MachineRepresentation::kTagged);
     530             :   CheckTwoChanges(IrOpcode::kChangeFloat64ToInt32,
     531             :                   IrOpcode::kChangeInt32ToTagged,
     532             :                   MachineRepresentation::kFloat64, Type::Signed32(),
     533           5 :                   MachineRepresentation::kTagged);
     534             :   CheckTwoChanges(IrOpcode::kChangeFloat64ToUint32,
     535             :                   IrOpcode::kChangeUint32ToTagged,
     536             :                   MachineRepresentation::kFloat64, Type::Unsigned32(),
     537           5 :                   MachineRepresentation::kTagged);
     538             : 
     539             :   CheckChange(IrOpcode::kChangeTaggedToInt32, MachineRepresentation::kTagged,
     540           5 :               Type::Signed32(), MachineRepresentation::kWord32);
     541             :   CheckChange(IrOpcode::kChangeTaggedToUint32, MachineRepresentation::kTagged,
     542           5 :               Type::Unsigned32(), MachineRepresentation::kWord32);
     543             :   CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged,
     544           5 :               Type::Number(), MachineRepresentation::kFloat64);
     545             :   CheckChange(IrOpcode::kTruncateTaggedToFloat64,
     546             :               MachineRepresentation::kTagged, Type::NumberOrUndefined(),
     547           5 :               MachineRepresentation::kFloat64);
     548             :   CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged,
     549           5 :               Type::Signed31(), MachineRepresentation::kFloat64);
     550             : 
     551             :   // Int32,Uint32 <-> Float64 are actually machine conversions.
     552             :   CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32,
     553           5 :               Type::Signed32(), MachineRepresentation::kFloat64);
     554          10 :   CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32,
     555             :               Type::Signed32OrMinusZero(), MachineRepresentation::kFloat64,
     556             :               UseInfo(MachineRepresentation::kFloat64,
     557           5 :                       Truncation::Any(kIdentifyZeros)));
     558             :   CheckChange(IrOpcode::kChangeUint32ToFloat64, MachineRepresentation::kWord32,
     559           5 :               Type::Unsigned32(), MachineRepresentation::kFloat64);
     560             :   CheckChange(IrOpcode::kChangeFloat64ToInt32, MachineRepresentation::kFloat64,
     561           5 :               Type::Signed32(), MachineRepresentation::kWord32);
     562             :   CheckChange(IrOpcode::kChangeFloat64ToUint32, MachineRepresentation::kFloat64,
     563           5 :               Type::Unsigned32(), MachineRepresentation::kWord32);
     564             : 
     565             :   CheckChange(IrOpcode::kTruncateFloat64ToFloat32,
     566             :               MachineRepresentation::kFloat64, Type::Number(),
     567           5 :               MachineRepresentation::kFloat32);
     568             : 
     569             :   // Int32,Uint32 <-> Float32 require two changes.
     570             :   CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
     571             :                   IrOpcode::kTruncateFloat64ToFloat32,
     572             :                   MachineRepresentation::kWord32, Type::Signed32(),
     573           5 :                   MachineRepresentation::kFloat32);
     574             :   CheckTwoChanges(IrOpcode::kChangeUint32ToFloat64,
     575             :                   IrOpcode::kTruncateFloat64ToFloat32,
     576             :                   MachineRepresentation::kWord32, Type::Unsigned32(),
     577           5 :                   MachineRepresentation::kFloat32);
     578             :   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
     579             :                   IrOpcode::kChangeFloat64ToInt32,
     580             :                   MachineRepresentation::kFloat32, Type::Signed32(),
     581           5 :                   MachineRepresentation::kWord32);
     582             :   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
     583             :                   IrOpcode::kChangeFloat64ToUint32,
     584             :                   MachineRepresentation::kFloat32, Type::Unsigned32(),
     585           5 :                   MachineRepresentation::kWord32);
     586             : 
     587             :   // Float32 <-> Tagged require two changes.
     588             :   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
     589             :                   IrOpcode::kChangeFloat64ToTagged,
     590             :                   MachineRepresentation::kFloat32, Type::Number(),
     591           5 :                   MachineRepresentation::kTagged);
     592             :   CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64,
     593             :                   IrOpcode::kTruncateFloat64ToFloat32,
     594             :                   MachineRepresentation::kTagged, Type::Number(),
     595           5 :                   MachineRepresentation::kFloat32);
     596           5 : }
     597             : 
     598             : 
     599       26644 : TEST(SignednessInWord32) {
     600           5 :   RepresentationChangerTester r;
     601             : 
     602             :   CheckChange(IrOpcode::kChangeTaggedToInt32, MachineRepresentation::kTagged,
     603           5 :               Type::Signed32(), MachineRepresentation::kWord32);
     604             :   CheckChange(IrOpcode::kChangeTaggedToUint32, MachineRepresentation::kTagged,
     605           5 :               Type::Unsigned32(), MachineRepresentation::kWord32);
     606             :   CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32,
     607           5 :               Type::Signed32(), MachineRepresentation::kFloat64);
     608             :   CheckChange(IrOpcode::kChangeFloat64ToInt32, MachineRepresentation::kFloat64,
     609           5 :               Type::Signed32(), MachineRepresentation::kWord32);
     610          10 :   CheckChange(IrOpcode::kTruncateFloat64ToWord32,
     611             :               MachineRepresentation::kFloat64, Type::Number(),
     612             :               MachineRepresentation::kWord32,
     613           5 :               UseInfo(MachineRepresentation::kWord32, Truncation::Word32()));
     614          10 :   CheckChange(IrOpcode::kCheckedTruncateTaggedToWord32,
     615             :               MachineRepresentation::kTagged, Type::NonInternal(),
     616             :               MachineRepresentation::kWord32,
     617           5 :               UseInfo::CheckedNumberOrOddballAsWord32(VectorSlotPair()));
     618             : 
     619             :   CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
     620             :                   IrOpcode::kTruncateFloat64ToFloat32,
     621             :                   MachineRepresentation::kWord32, Type::Signed32(),
     622           5 :                   MachineRepresentation::kFloat32);
     623             :   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
     624             :                   IrOpcode::kTruncateFloat64ToWord32,
     625             :                   MachineRepresentation::kFloat32, Type::Number(),
     626           5 :                   MachineRepresentation::kWord32);
     627             : 
     628          10 :   CheckChange(
     629             :       IrOpcode::kCheckedUint32ToInt32, MachineRepresentation::kWord32,
     630             :       Type::Unsigned32(),
     631           5 :       UseInfo::CheckedSigned32AsWord32(kIdentifyZeros, VectorSlotPair()));
     632           5 : }
     633             : 
     634       26644 : TEST(CompressedAndTagged) {
     635             :   // Simple Tagged to Compressed
     636             :   CheckChange(IrOpcode::kChangeTaggedToCompressed,
     637             :               MachineRepresentation::kTagged, Type::Any(),
     638           5 :               MachineRepresentation::kCompressed);
     639             :   CheckChange(IrOpcode::kChangeTaggedPointerToCompressedPointer,
     640             :               MachineRepresentation::kTaggedPointer, Type::Any(),
     641           5 :               MachineRepresentation::kCompressedPointer);
     642             :   CheckChange(IrOpcode::kChangeTaggedSignedToCompressedSigned,
     643             :               MachineRepresentation::kTaggedSigned, Type::Any(),
     644           5 :               MachineRepresentation::kCompressedSigned);
     645             : 
     646             :   // Simple Compressed to Tagged
     647             :   CheckChange(IrOpcode::kChangeCompressedToTagged,
     648             :               MachineRepresentation::kCompressed, Type::Any(),
     649           5 :               MachineRepresentation::kTagged);
     650             :   CheckChange(IrOpcode::kChangeCompressedPointerToTaggedPointer,
     651             :               MachineRepresentation::kCompressedPointer, Type::Any(),
     652           5 :               MachineRepresentation::kTaggedPointer);
     653             :   CheckChange(IrOpcode::kChangeCompressedSignedToTaggedSigned,
     654             :               MachineRepresentation::kCompressedSigned, Type::Any(),
     655           5 :               MachineRepresentation::kTaggedSigned);
     656             : 
     657             :   // Compressed To TaggedSigned
     658             :   CheckChange(IrOpcode::kChangeCompressedToTaggedSigned,
     659             :               MachineRepresentation::kCompressed, Type::SignedSmall(),
     660           5 :               MachineRepresentation::kTaggedSigned);
     661             : 
     662             :   // Tagged To CompressedSigned
     663             :   CheckChange(IrOpcode::kChangeTaggedToCompressedSigned,
     664             :               MachineRepresentation::kTagged, Type::SignedSmall(),
     665           5 :               MachineRepresentation::kCompressedSigned);
     666           5 : }
     667             : 
     668          10 : static void TestMinusZeroCheck(IrOpcode::Value expected, Type from_type) {
     669          10 :   RepresentationChangerTester r;
     670             : 
     671          20 :   CheckChange(
     672             :       expected, MachineRepresentation::kFloat64, from_type,
     673          10 :       UseInfo::CheckedSignedSmallAsWord32(kDistinguishZeros, VectorSlotPair()));
     674             : 
     675          20 :   CheckChange(
     676             :       expected, MachineRepresentation::kFloat64, from_type,
     677          10 :       UseInfo::CheckedSignedSmallAsWord32(kIdentifyZeros, VectorSlotPair()));
     678             : 
     679          20 :   CheckChange(
     680             :       expected, MachineRepresentation::kFloat64, from_type,
     681          10 :       UseInfo::CheckedSigned32AsWord32(kDistinguishZeros, VectorSlotPair()));
     682             : 
     683          20 :   CheckChange(
     684             :       expected, MachineRepresentation::kFloat64, from_type,
     685          10 :       UseInfo::CheckedSigned32AsWord32(kDistinguishZeros, VectorSlotPair()));
     686          10 : }
     687             : 
     688       26644 : TEST(MinusZeroCheck) {
     689           5 :   TestMinusZeroCheck(IrOpcode::kCheckedFloat64ToInt32, Type::NumberOrOddball());
     690             :   // PlainNumber cannot be minus zero so the minus zero check should be
     691             :   // eliminated.
     692           5 :   TestMinusZeroCheck(IrOpcode::kCheckedFloat64ToInt32, Type::PlainNumber());
     693           5 : }
     694             : 
     695       26644 : TEST(Nops) {
     696           5 :   RepresentationChangerTester r;
     697             : 
     698             :   // X -> X is always a nop for any single representation X.
     699         125 :   for (size_t i = 0; i < arraysize(kMachineTypes); i++) {
     700          60 :     r.CheckNop(kMachineTypes[i].representation(), Type::Number(),
     701          60 :                kMachineTypes[i].representation());
     702             :   }
     703             : 
     704             :   // 32-bit floats.
     705             :   r.CheckNop(MachineRepresentation::kFloat32, Type::Number(),
     706           5 :              MachineRepresentation::kFloat32);
     707             : 
     708             :   // 32-bit words can be used as smaller word sizes and vice versa, because
     709             :   // loads from memory implicitly sign or zero extend the value to the
     710             :   // full machine word size, and stores implicitly truncate.
     711             :   r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(),
     712           5 :              MachineRepresentation::kWord8);
     713             :   r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(),
     714           5 :              MachineRepresentation::kWord16);
     715             :   r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(),
     716           5 :              MachineRepresentation::kWord32);
     717             :   r.CheckNop(MachineRepresentation::kWord8, Type::Signed32(),
     718           5 :              MachineRepresentation::kWord32);
     719             :   r.CheckNop(MachineRepresentation::kWord16, Type::Signed32(),
     720           5 :              MachineRepresentation::kWord32);
     721             : 
     722             :   // kRepBit (result of comparison) is implicitly a wordish thing.
     723             :   r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
     724           5 :              MachineRepresentation::kWord8);
     725             :   r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
     726           5 :              MachineRepresentation::kWord16);
     727             :   r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
     728           5 :              MachineRepresentation::kWord32);
     729           5 : }
     730             : 
     731             : 
     732       26644 : TEST(TypeErrors) {
     733           5 :   RepresentationChangerTester r;
     734             : 
     735             :   // Floats cannot be implicitly converted to/from comparison conditions.
     736             :   r.CheckTypeError(MachineRepresentation::kBit, Type::Number(),
     737           5 :                    MachineRepresentation::kFloat32);
     738             :   r.CheckTypeError(MachineRepresentation::kBit, Type::Boolean(),
     739           5 :                    MachineRepresentation::kFloat32);
     740             : 
     741             :   // Word64 is internal and shouldn't be implicitly converted.
     742             :   r.CheckTypeError(MachineRepresentation::kWord64, Type::Internal(),
     743           5 :                    MachineRepresentation::kTagged);
     744             :   r.CheckTypeError(MachineRepresentation::kTagged, Type::Number(),
     745           5 :                    MachineRepresentation::kWord64);
     746             :   r.CheckTypeError(MachineRepresentation::kTagged, Type::Boolean(),
     747           5 :                    MachineRepresentation::kWord64);
     748             :   r.CheckTypeError(MachineRepresentation::kWord64, Type::Internal(),
     749           5 :                    MachineRepresentation::kWord32);
     750             :   r.CheckTypeError(MachineRepresentation::kWord32, Type::Number(),
     751           5 :                    MachineRepresentation::kWord64);
     752           5 : }
     753             : 
     754             : }  // namespace compiler
     755             : }  // namespace internal
     756       79917 : }  // namespace v8

Generated by: LCOV version 1.10