| OLD | NEW | 
|    1 // Copyright 2014 the V8 project authors. All rights reserved. |    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 |    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 <limits> |    5 #include <limits> | 
|    6  |    6  | 
|    7 #include "src/v8.h" |    7 #include "src/v8.h" | 
|    8 #include "test/cctest/cctest.h" |    8 #include "test/cctest/cctest.h" | 
|    9 #include "test/cctest/compiler/graph-builder-tester.h" |    9 #include "test/cctest/compiler/graph-builder-tester.h" | 
 |   10 #include "test/cctest/compiler/value-helper.h" | 
|   10  |   11  | 
|   11 #include "src/compiler/node-matchers.h" |   12 #include "src/compiler/node-matchers.h" | 
|   12 #include "src/compiler/representation-change.h" |   13 #include "src/compiler/representation-change.h" | 
|   13 #include "src/compiler/typer.h" |   14 #include "src/compiler/typer.h" | 
|   14  |   15  | 
|   15 using namespace v8::internal; |   16 using namespace v8::internal; | 
|   16 using namespace v8::internal::compiler; |   17 using namespace v8::internal::compiler; | 
|   17  |   18  | 
|   18 namespace v8 {  // for friendiness. |   19 namespace v8 {  // for friendiness. | 
|   19 namespace internal { |   20 namespace internal { | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|   44   JSGraph* jsgraph() { return &jsgraph_; } |   45   JSGraph* jsgraph() { return &jsgraph_; } | 
|   45   RepresentationChanger* changer() { return &changer_; } |   46   RepresentationChanger* changer() { return &changer_; } | 
|   46  |   47  | 
|   47   // TODO(titzer): use ValueChecker / ValueUtil |   48   // TODO(titzer): use ValueChecker / ValueUtil | 
|   48   void CheckInt32Constant(Node* n, int32_t expected) { |   49   void CheckInt32Constant(Node* n, int32_t expected) { | 
|   49     Int32Matcher m(n); |   50     Int32Matcher m(n); | 
|   50     CHECK(m.HasValue()); |   51     CHECK(m.HasValue()); | 
|   51     CHECK_EQ(expected, m.Value()); |   52     CHECK_EQ(expected, m.Value()); | 
|   52   } |   53   } | 
|   53  |   54  | 
 |   55   void CheckUint32Constant(Node* n, uint32_t expected) { | 
 |   56     Uint32Matcher m(n); | 
 |   57     CHECK(m.HasValue()); | 
 |   58     CHECK_EQ(static_cast<int>(expected), static_cast<int>(m.Value())); | 
 |   59   } | 
 |   60  | 
 |   61   void CheckFloat64Constant(Node* n, double expected) { | 
 |   62     Float64Matcher m(n); | 
 |   63     CHECK(m.HasValue()); | 
 |   64     CHECK_EQ(expected, m.Value()); | 
 |   65   } | 
 |   66  | 
 |   67   void CheckFloat32Constant(Node* n, float expected) { | 
 |   68     CHECK_EQ(IrOpcode::kFloat32Constant, n->opcode()); | 
 |   69     float fval = OpParameter<float>(n->op()); | 
 |   70     CHECK_EQ(expected, fval); | 
 |   71   } | 
 |   72  | 
|   54   void CheckHeapConstant(Node* n, HeapObject* expected) { |   73   void CheckHeapConstant(Node* n, HeapObject* expected) { | 
|   55     HeapObjectMatcher<HeapObject> m(n); |   74     HeapObjectMatcher<HeapObject> m(n); | 
|   56     CHECK(m.HasValue()); |   75     CHECK(m.HasValue()); | 
|   57     CHECK_EQ(expected, *m.Value().handle()); |   76     CHECK_EQ(expected, *m.Value().handle()); | 
|   58   } |   77   } | 
|   59  |   78  | 
|   60   void CheckNumberConstant(Node* n, double expected) { |   79   void CheckNumberConstant(Node* n, double expected) { | 
|   61     NumberMatcher m(n); |   80     NumberMatcher m(n); | 
|   62     CHECK_EQ(IrOpcode::kNumberConstant, n->opcode()); |   81     CHECK_EQ(IrOpcode::kNumberConstant, n->opcode()); | 
|   63     CHECK(m.HasValue()); |   82     CHECK(m.HasValue()); | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|   85 }; |  104 }; | 
|   86 } |  105 } | 
|   87 } |  106 } | 
|   88 }  // namespace v8::internal::compiler |  107 }  // namespace v8::internal::compiler | 
|   89  |  108  | 
|   90  |  109  | 
|   91 static const MachineType all_reps[] = {kRepBit,     kRepWord32,  kRepWord64, |  110 static const MachineType all_reps[] = {kRepBit,     kRepWord32,  kRepWord64, | 
|   92                                        kRepFloat32, kRepFloat64, kRepTagged}; |  111                                        kRepFloat32, kRepFloat64, kRepTagged}; | 
|   93  |  112  | 
|   94  |  113  | 
|   95 // TODO(titzer): lift this to ValueHelper |  | 
|   96 static const double double_inputs[] = { |  | 
|   97     0.0,   -0.0,    1.0,    -1.0,        0.1,         1.4,    -1.7, |  | 
|   98     2,     5,       6,      982983,      888,         -999.8, 3.1e7, |  | 
|   99     -2e66, 2.3e124, -12e73, V8_INFINITY, -V8_INFINITY}; |  | 
|  100  |  | 
|  101  |  | 
|  102 static const int32_t int32_inputs[] = { |  | 
|  103     0,      1,                                -1, |  | 
|  104     2,      5,                                6, |  | 
|  105     982983, 888,                              -999, |  | 
|  106     65535,  static_cast<int32_t>(0xFFFFFFFF), static_cast<int32_t>(0x80000000)}; |  | 
|  107  |  | 
|  108  |  | 
|  109 static const uint32_t uint32_inputs[] = { |  | 
|  110     0,      1,   static_cast<uint32_t>(-1),   2,     5,          6, |  | 
|  111     982983, 888, static_cast<uint32_t>(-999), 65535, 0xFFFFFFFF, 0x80000000}; |  | 
|  112  |  | 
|  113  |  | 
|  114 TEST(BoolToBit_constant) { |  114 TEST(BoolToBit_constant) { | 
|  115   RepresentationChangerTester r; |  115   RepresentationChangerTester r; | 
|  116  |  116  | 
|  117   Node* true_node = r.jsgraph()->TrueConstant(); |  117   Node* true_node = r.jsgraph()->TrueConstant(); | 
|  118   Node* true_bit = |  118   Node* true_bit = | 
|  119       r.changer()->GetRepresentationFor(true_node, kRepTagged, kRepBit); |  119       r.changer()->GetRepresentationFor(true_node, kRepTagged, kRepBit); | 
|  120   r.CheckInt32Constant(true_bit, 1); |  120   r.CheckInt32Constant(true_bit, 1); | 
|  121  |  121  | 
|  122   Node* false_node = r.jsgraph()->FalseConstant(); |  122   Node* false_node = r.jsgraph()->FalseConstant(); | 
|  123   Node* false_bit = |  123   Node* false_bit = | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  134     Node* val = r.changer()->GetRepresentationFor(node, kRepBit, kRepTagged); |  134     Node* val = r.changer()->GetRepresentationFor(node, kRepBit, kRepTagged); | 
|  135     r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value() |  135     r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value() | 
|  136                                     : r.isolate()->heap()->true_value()); |  136                                     : r.isolate()->heap()->true_value()); | 
|  137   } |  137   } | 
|  138 } |  138 } | 
|  139  |  139  | 
|  140  |  140  | 
|  141 TEST(ToTagged_constant) { |  141 TEST(ToTagged_constant) { | 
|  142   RepresentationChangerTester r; |  142   RepresentationChangerTester r; | 
|  143  |  143  | 
|  144   for (size_t i = 0; i < arraysize(double_inputs); i++) { |  144   { | 
|  145     Node* n = r.jsgraph()->Float64Constant(double_inputs[i]); |  145     FOR_FLOAT64_INPUTS(i) { | 
|  146     Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged); |  146       Node* n = r.jsgraph()->Float64Constant(*i); | 
|  147     r.CheckNumberConstant(c, double_inputs[i]); |  147       Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged); | 
|  148   } |  148       r.CheckNumberConstant(c, *i); | 
|  149  |  149     } | 
|  150   for (size_t i = 0; i < arraysize(double_inputs); i++) { |  150   } | 
|  151     volatile float fval = static_cast<float>(double_inputs[i]); |  151  | 
|  152     Node* n = r.jsgraph()->Float32Constant(fval); |  152   { | 
|  153     Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepTagged); |  153     FOR_FLOAT64_INPUTS(i) { | 
|  154     r.CheckNumberConstant(c, fval); |  154       Node* n = r.jsgraph()->Constant(*i); | 
|  155   } |  155       Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged); | 
|  156  |  156       r.CheckNumberConstant(c, *i); | 
|  157   for (size_t i = 0; i < arraysize(int32_inputs); i++) { |  157     } | 
|  158     Node* n = r.jsgraph()->Int32Constant(int32_inputs[i]); |  158   } | 
|  159     Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, |  159  | 
|  160                                                 kRepTagged); |  160   { | 
|  161     r.CheckNumberConstant(c, static_cast<double>(int32_inputs[i])); |  161     FOR_FLOAT32_INPUTS(i) { | 
|  162   } |  162       Node* n = r.jsgraph()->Float32Constant(*i); | 
|  163  |  163       Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepTagged); | 
|  164   for (size_t i = 0; i < arraysize(uint32_inputs); i++) { |  164       r.CheckNumberConstant(c, *i); | 
|  165     Node* n = r.jsgraph()->Int32Constant(uint32_inputs[i]); |  165     } | 
|  166     Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, |  166   } | 
|  167                                                 kRepTagged); |  167  | 
|  168     r.CheckNumberConstant(c, static_cast<double>(uint32_inputs[i])); |  168   { | 
|  169   } |  169     FOR_INT32_INPUTS(i) { | 
|  170 } |  170       Node* n = r.jsgraph()->Int32Constant(*i); | 
|  171  |  171       Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 
 |  172                                                   kRepTagged); | 
 |  173       r.CheckNumberConstant(c, *i); | 
 |  174     } | 
 |  175   } | 
 |  176  | 
 |  177   { | 
 |  178     FOR_UINT32_INPUTS(i) { | 
 |  179       Node* n = r.jsgraph()->Int32Constant(*i); | 
 |  180       Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 
 |  181                                                   kRepTagged); | 
 |  182       r.CheckNumberConstant(c, *i); | 
 |  183     } | 
 |  184   } | 
 |  185 } | 
 |  186  | 
 |  187  | 
 |  188 TEST(ToFloat64_constant) { | 
 |  189   RepresentationChangerTester r; | 
 |  190  | 
 |  191   { | 
 |  192     FOR_FLOAT64_INPUTS(i) { | 
 |  193       Node* n = r.jsgraph()->Float64Constant(*i); | 
 |  194       Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat64); | 
 |  195       CHECK_EQ(n, c); | 
 |  196     } | 
 |  197   } | 
 |  198  | 
 |  199   { | 
 |  200     FOR_FLOAT64_INPUTS(i) { | 
 |  201       Node* n = r.jsgraph()->Constant(*i); | 
 |  202       Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat64); | 
 |  203       r.CheckFloat64Constant(c, *i); | 
 |  204     } | 
 |  205   } | 
 |  206  | 
 |  207   { | 
 |  208     FOR_FLOAT32_INPUTS(i) { | 
 |  209       Node* n = r.jsgraph()->Float32Constant(*i); | 
 |  210       Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat64); | 
 |  211       r.CheckFloat64Constant(c, *i); | 
 |  212     } | 
 |  213   } | 
 |  214  | 
 |  215   { | 
 |  216     FOR_INT32_INPUTS(i) { | 
 |  217       Node* n = r.jsgraph()->Int32Constant(*i); | 
 |  218       Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 
 |  219                                                   kRepFloat64); | 
 |  220       r.CheckFloat64Constant(c, *i); | 
 |  221     } | 
 |  222   } | 
 |  223  | 
 |  224   { | 
 |  225     FOR_UINT32_INPUTS(i) { | 
 |  226       Node* n = r.jsgraph()->Int32Constant(*i); | 
 |  227       Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 
 |  228                                                   kRepFloat64); | 
 |  229       r.CheckFloat64Constant(c, *i); | 
 |  230     } | 
 |  231   } | 
 |  232 } | 
 |  233  | 
 |  234  | 
 |  235 static bool IsFloat32Int32(int32_t val) { | 
 |  236   return val >= -(1 << 23) && val <= (1 << 23); | 
 |  237 } | 
 |  238  | 
 |  239  | 
 |  240 static bool IsFloat32Uint32(uint32_t val) { return val <= (1 << 23); } | 
 |  241  | 
 |  242  | 
 |  243 TEST(ToFloat32_constant) { | 
 |  244   RepresentationChangerTester r; | 
 |  245  | 
 |  246   { | 
 |  247     FOR_FLOAT32_INPUTS(i) { | 
 |  248       Node* n = r.jsgraph()->Float32Constant(*i); | 
 |  249       Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat32); | 
 |  250       CHECK_EQ(n, c); | 
 |  251     } | 
 |  252   } | 
 |  253  | 
 |  254   { | 
 |  255     FOR_FLOAT32_INPUTS(i) { | 
 |  256       Node* n = r.jsgraph()->Constant(*i); | 
 |  257       Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat32); | 
 |  258       r.CheckFloat32Constant(c, *i); | 
 |  259     } | 
 |  260   } | 
 |  261  | 
 |  262   { | 
 |  263     FOR_FLOAT32_INPUTS(i) { | 
 |  264       Node* n = r.jsgraph()->Float64Constant(*i); | 
 |  265       Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat32); | 
 |  266       r.CheckFloat32Constant(c, *i); | 
 |  267     } | 
 |  268   } | 
 |  269  | 
 |  270   { | 
 |  271     FOR_INT32_INPUTS(i) { | 
 |  272       if (!IsFloat32Int32(*i)) continue; | 
 |  273       Node* n = r.jsgraph()->Int32Constant(*i); | 
 |  274       Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 
 |  275                                                   kRepFloat32); | 
 |  276       r.CheckFloat32Constant(c, *i); | 
 |  277     } | 
 |  278   } | 
 |  279  | 
 |  280   { | 
 |  281     FOR_UINT32_INPUTS(i) { | 
 |  282       if (!IsFloat32Uint32(*i)) continue; | 
 |  283       Node* n = r.jsgraph()->Int32Constant(*i); | 
 |  284       Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 
 |  285                                                   kRepFloat32); | 
 |  286       r.CheckFloat32Constant(c, *i); | 
 |  287     } | 
 |  288   } | 
 |  289 } | 
 |  290  | 
 |  291  | 
 |  292 TEST(ToInt32_constant) { | 
 |  293   RepresentationChangerTester r; | 
 |  294  | 
 |  295   { | 
 |  296     FOR_INT32_INPUTS(i) { | 
 |  297       Node* n = r.jsgraph()->Int32Constant(*i); | 
 |  298       Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 
 |  299                                                   kRepWord32); | 
 |  300       r.CheckInt32Constant(c, *i); | 
 |  301     } | 
 |  302   } | 
 |  303  | 
 |  304   { | 
 |  305     FOR_INT32_INPUTS(i) { | 
 |  306       if (!IsFloat32Int32(*i)) continue; | 
 |  307       Node* n = r.jsgraph()->Float32Constant(*i); | 
 |  308       Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeInt32, | 
 |  309                                                   kRepWord32); | 
 |  310       r.CheckInt32Constant(c, *i); | 
 |  311     } | 
 |  312   } | 
 |  313  | 
 |  314   { | 
 |  315     FOR_INT32_INPUTS(i) { | 
 |  316       Node* n = r.jsgraph()->Float64Constant(*i); | 
 |  317       Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeInt32, | 
 |  318                                                   kRepWord32); | 
 |  319       r.CheckInt32Constant(c, *i); | 
 |  320     } | 
 |  321   } | 
 |  322  | 
 |  323   { | 
 |  324     FOR_INT32_INPUTS(i) { | 
 |  325       Node* n = r.jsgraph()->Constant(*i); | 
 |  326       Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeInt32, | 
 |  327                                                   kRepWord32); | 
 |  328       r.CheckInt32Constant(c, *i); | 
 |  329     } | 
 |  330   } | 
 |  331 } | 
 |  332  | 
 |  333  | 
 |  334 TEST(ToUint32_constant) { | 
 |  335   RepresentationChangerTester r; | 
 |  336  | 
 |  337   { | 
 |  338     FOR_UINT32_INPUTS(i) { | 
 |  339       Node* n = r.jsgraph()->Int32Constant(*i); | 
 |  340       Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 
 |  341                                                   kRepWord32); | 
 |  342       r.CheckUint32Constant(c, *i); | 
 |  343     } | 
 |  344   } | 
 |  345  | 
 |  346   { | 
 |  347     FOR_UINT32_INPUTS(i) { | 
 |  348       if (!IsFloat32Uint32(*i)) continue; | 
 |  349       Node* n = r.jsgraph()->Float32Constant(*i); | 
 |  350       Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeUint32, | 
 |  351                                                   kRepWord32); | 
 |  352       r.CheckUint32Constant(c, *i); | 
 |  353     } | 
 |  354   } | 
 |  355  | 
 |  356   { | 
 |  357     FOR_UINT32_INPUTS(i) { | 
 |  358       Node* n = r.jsgraph()->Float64Constant(*i); | 
 |  359       Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeUint32, | 
 |  360                                                   kRepWord32); | 
 |  361       r.CheckUint32Constant(c, *i); | 
 |  362     } | 
 |  363   } | 
 |  364  | 
 |  365   { | 
 |  366     FOR_UINT32_INPUTS(i) { | 
 |  367       Node* n = r.jsgraph()->Constant(static_cast<double>(*i)); | 
 |  368       Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeUint32, | 
 |  369                                                   kRepWord32); | 
 |  370       r.CheckUint32Constant(c, *i); | 
 |  371     } | 
 |  372   } | 
 |  373 } | 
 |  374  | 
|  172  |  375  | 
|  173 static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from, |  376 static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from, | 
|  174                         MachineTypeUnion to) { |  377                         MachineTypeUnion to) { | 
|  175   RepresentationChangerTester r; |  378   RepresentationChangerTester r; | 
|  176  |  379  | 
|  177   Node* n = r.Parameter(); |  380   Node* n = r.Parameter(); | 
|  178   Node* c = r.changer()->GetRepresentationFor(n, from, to); |  381   Node* c = r.changer()->GetRepresentationFor(n, from, to); | 
|  179  |  382  | 
|  180   CHECK_NE(c, n); |  383   CHECK_NE(c, n); | 
|  181   CHECK_EQ(expected, c->opcode()); |  384   CHECK_EQ(expected, c->opcode()); | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  241                   kRepWord32); |  444                   kRepWord32); | 
|  242  |  445  | 
|  243   // Float32 <-> Tagged require two changes. |  446   // Float32 <-> Tagged require two changes. | 
|  244   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, |  447   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, | 
|  245                   IrOpcode::kChangeFloat64ToTagged, kRepFloat32, kRepTagged); |  448                   IrOpcode::kChangeFloat64ToTagged, kRepFloat32, kRepTagged); | 
|  246   CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64, |  449   CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64, | 
|  247                   IrOpcode::kTruncateFloat64ToFloat32, kRepTagged, kRepFloat32); |  450                   IrOpcode::kTruncateFloat64ToFloat32, kRepTagged, kRepFloat32); | 
|  248 } |  451 } | 
|  249  |  452  | 
|  250  |  453  | 
|  251 // TODO(titzer): test constant folding of changes between int/float |  | 
|  252  |  | 
|  253  |  | 
|  254 TEST(SignednessInWord32) { |  454 TEST(SignednessInWord32) { | 
|  255   RepresentationChangerTester r; |  455   RepresentationChangerTester r; | 
|  256  |  456  | 
|  257   // TODO(titzer): assume that uses of a word32 without a sign mean kTypeInt32. |  457   // TODO(titzer): assume that uses of a word32 without a sign mean kTypeInt32. | 
|  258   CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged, |  458   CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged, | 
|  259               kRepWord32 | kTypeInt32); |  459               kRepWord32 | kTypeInt32); | 
|  260   CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged, |  460   CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged, | 
|  261               kRepWord32 | kTypeUint32); |  461               kRepWord32 | kTypeUint32); | 
|  262   CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32, kRepFloat64); |  462   CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32, kRepFloat64); | 
|  263   CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64, kRepWord32); |  463   CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64, kRepWord32); | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  340   r.CheckTypeError(kRepWord32 | kTypeUint32, kRepWord64); |  540   r.CheckTypeError(kRepWord32 | kTypeUint32, kRepWord64); | 
|  341  |  541  | 
|  342   for (size_t i = 0; i < arraysize(all_reps); i++) { |  542   for (size_t i = 0; i < arraysize(all_reps); i++) { | 
|  343     for (size_t j = 0; j < arraysize(all_reps); j++) { |  543     for (size_t j = 0; j < arraysize(all_reps); j++) { | 
|  344       if (i == j) continue; |  544       if (i == j) continue; | 
|  345       // Only a single from representation is allowed. |  545       // Only a single from representation is allowed. | 
|  346       r.CheckTypeError(all_reps[i] | all_reps[j], kRepTagged); |  546       r.CheckTypeError(all_reps[i] | all_reps[j], kRepTagged); | 
|  347     } |  547     } | 
|  348   } |  548   } | 
|  349 } |  549 } | 
| OLD | NEW |