| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright 2013 the V8 project authors. All rights reserved. | 
 |    2 // Redistribution and use in source and binary forms, with or without | 
 |    3 // modification, are permitted provided that the following conditions are | 
 |    4 // met: | 
 |    5 // | 
 |    6 //     * Redistributions of source code must retain the above copyright | 
 |    7 //       notice, this list of conditions and the following disclaimer. | 
 |    8 //     * Redistributions in binary form must reproduce the above | 
 |    9 //       copyright notice, this list of conditions and the following | 
 |   10 //       disclaimer in the documentation and/or other materials provided | 
 |   11 //       with the distribution. | 
 |   12 //     * Neither the name of Google Inc. nor the names of its | 
 |   13 //       contributors may be used to endorse or promote products derived | 
 |   14 //       from this software without specific prior written permission. | 
 |   15 // | 
 |   16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
 |   17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
 |   18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
 |   19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
 |   20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
 |   21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
 |   22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
 |   23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
 |   24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
 |   25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
 |   26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
 |   27  | 
 |   28 #include <stdlib.h> | 
 |   29  | 
 |   30 #include "v8.h" | 
 |   31  | 
 |   32 #include "hydrogen-instructions.h" | 
 |   33 #include "cctest.h" | 
 |   34  | 
 |   35 using namespace v8::internal; | 
 |   36  | 
 |   37 static int32_t GetLo(const BitRange& range) { | 
 |   38   int32_t lo = kMaxInt, hi = kMinInt; | 
 |   39   range.ExtendRange(&lo, &hi); | 
 |   40   return lo; | 
 |   41 } | 
 |   42  | 
 |   43  | 
 |   44 static int32_t GetHi(const BitRange& range) { | 
 |   45   int32_t lo = kMaxInt, hi = kMinInt; | 
 |   46   range.ExtendRange(&lo, &hi); | 
 |   47   return hi; | 
 |   48 } | 
 |   49  | 
 |   50  | 
 |   51 static void CheckOp(int32_t a_lo, int32_t a_hi, | 
 |   52                     int32_t b_lo, int32_t b_hi, | 
 |   53                     BitRange op(BitRange, BitRange), | 
 |   54                     int32_t expected_lo, int32_t expected_hi) { | 
 |   55   BitRange a_range; | 
 |   56   BitRange b_range; | 
 |   57   BitRange::SetFromRange(&a_range, a_lo, a_hi); | 
 |   58   BitRange::SetFromRange(&b_range, b_lo, b_hi); | 
 |   59   BitRange result = op(a_range, b_range); | 
 |   60   CHECK_EQ(expected_lo, GetLo(result)); | 
 |   61   CHECK_EQ(expected_hi, GetHi(result)); | 
 |   62 } | 
 |   63  | 
 |   64  | 
 |   65 TEST(BitRangeConstants) { | 
 |   66   // Converting a constant to BitRange and back is lossless. | 
 |   67   for (int32_t i = -100; i <= 100; i++) { | 
 |   68     BitRange r; | 
 |   69     BitRange::SetFromRange(&r, i, i); | 
 |   70     int32_t lo = kMaxInt, hi = kMinInt; | 
 |   71     r.ExtendRange(&lo, &hi); | 
 |   72     CHECK_EQ(i, lo); | 
 |   73     CHECK_EQ(i, hi); | 
 |   74   } | 
 |   75 } | 
 |   76  | 
 |   77  | 
 |   78 TEST(BitRangeConstantOps) { | 
 |   79   for (int32_t a = -16; a <= 15; a++) { | 
 |   80     for (int32_t b = -16; b <= 15; b++) { | 
 |   81       CheckOp(a, a, b, b, &BitRange::And, a & b, a & b); | 
 |   82       CheckOp(a, a, b, b, &BitRange::Or, a | b, a | b); | 
 |   83       CheckOp(a, a, b, b, &BitRange::Xor, a ^ b, a ^ b); | 
 |   84     } | 
 |   85   } | 
 |   86 } | 
 |   87  | 
 |   88  | 
 |   89 static void CheckConvert(int32_t lo, int32_t hi, | 
 |   90                          int32_t expected_lo, int32_t expected_hi) { | 
 |   91   BitRange range; | 
 |   92   BitRange::SetFromRange(&range, lo, hi); | 
 |   93   CHECK_EQ(expected_lo, GetLo(range)); | 
 |   94   CHECK_EQ(expected_hi, GetHi(range)); | 
 |   95 } | 
 |   96  | 
 |   97  | 
 |   98 TEST(BitRangeConversion) { | 
 |   99   // [0, 4] -->  000xxx | 
 |  100   CheckConvert(0, 4, 0, 7); | 
 |  101   CheckConvert(0, 5, 0, 7); | 
 |  102   CheckConvert(0, 6, 0, 7); | 
 |  103   CheckConvert(0, 7, 0, 7); | 
 |  104  | 
 |  105   CheckConvert(1, 4, 0, 7); | 
 |  106   CheckConvert(1, 5, 0, 7); | 
 |  107   CheckConvert(1, 6, 0, 7); | 
 |  108   CheckConvert(1, 7, 0, 7); | 
 |  109 } | 
 |  110  | 
 |  111  | 
 |  112 TEST(BitRangeConservativeApproximation) { | 
 |  113   // Exhaustive test of 5-bit integers. | 
 |  114   // The BitRange operation must always include all real possible values. | 
 |  115   const int32_t kMin = -16; | 
 |  116   const int32_t kMax = 15; | 
 |  117  | 
 |  118   int count = 0; | 
 |  119   int and_precise_count = 0; | 
 |  120   int or_precise_count = 0; | 
 |  121   int xor_precise_count = 0; | 
 |  122  | 
 |  123   for (int32_t a_lo = kMin; a_lo <= kMax; a_lo++) { | 
 |  124     for (int32_t a_hi = a_lo; a_hi <= kMax; a_hi++) { | 
 |  125       for (int32_t b_lo = kMin; b_lo <= kMax; b_lo++) { | 
 |  126         for (int32_t b_hi = a_lo; b_hi <= kMax; b_hi++) { | 
 |  127           // Compute precise ranges. | 
 |  128           int32_t and_lo = kMaxInt, and_hi = kMinInt; | 
 |  129           int32_t or_lo = kMaxInt, or_hi = kMinInt; | 
 |  130           int32_t xor_lo = kMaxInt, xor_hi = kMinInt; | 
 |  131  | 
 |  132           for (int32_t a = a_lo; a <= a_hi; a++) { | 
 |  133             for (int32_t b = b_lo; b <= b_hi; b++) { | 
 |  134               int32_t a_and_b = a & b; | 
 |  135               and_lo = Min(and_lo, a_and_b); | 
 |  136               and_hi = Max(and_hi, a_and_b); | 
 |  137               int32_t a_or_b = a | b; | 
 |  138               or_lo = Min(or_lo, a_or_b); | 
 |  139               or_hi = Max(or_hi, a_or_b); | 
 |  140               int32_t a_xor_b = a ^ b; | 
 |  141               xor_lo = Min(xor_lo, a_xor_b); | 
 |  142               xor_hi = Max(xor_hi, a_xor_b); | 
 |  143             } | 
 |  144           } | 
 |  145  | 
 |  146           BitRange a_range; | 
 |  147           BitRange::SetFromRange(&a_range, a_lo, a_hi); | 
 |  148           BitRange b_range; | 
 |  149           BitRange::SetFromRange(&b_range, b_lo, b_hi); | 
 |  150  | 
 |  151           ++count; | 
 |  152           // Precise range must always be included in approximate result. | 
 |  153           BitRange and_range = BitRange::And(a_range, b_range); | 
 |  154           CHECK(GetLo(and_range) <= and_lo); | 
 |  155           CHECK(GetHi(and_range) >= and_hi); | 
 |  156           if (GetLo(and_range) == and_lo && GetHi(and_range) == and_hi) { | 
 |  157             ++and_precise_count; | 
 |  158           } | 
 |  159  | 
 |  160           BitRange or_range = BitRange::Or(a_range, b_range); | 
 |  161           CHECK(GetLo(or_range) <= or_lo); | 
 |  162           CHECK(GetHi(or_range) >= or_hi); | 
 |  163           if (GetLo(or_range) == or_lo && GetHi(or_range) == or_hi) { | 
 |  164             ++or_precise_count; | 
 |  165           } | 
 |  166  | 
 |  167           BitRange xor_range = BitRange::Xor(a_range, b_range); | 
 |  168           CHECK(GetLo(xor_range) <= xor_lo); | 
 |  169           CHECK(GetHi(xor_range) >= xor_hi); | 
 |  170           if (GetLo(xor_range) == xor_lo && GetHi(xor_range) == xor_hi) { | 
 |  171             ++xor_precise_count; | 
 |  172           } | 
 |  173         } | 
 |  174       } | 
 |  175     } | 
 |  176   } | 
 |  177  | 
 |  178   CHECK_EQ(366080, count); | 
 |  179   CHECK_EQ(35668, and_precise_count); | 
 |  180   CHECK_EQ(35668, or_precise_count); | 
 |  181   CHECK_EQ(37480, xor_precise_count); | 
 |  182 } | 
 |  183  | 
 |  184  | 
 |  185 TEST(BitRangeMultiRange) { | 
 |  186   // Multiple ranges can be unioned with multiple calls to ExtendRange. | 
 |  187   // | 
 |  188   // HBitWise::InferRange is a 1x1 decomposition.  Each input range is | 
 |  189   // 'decomposed' into 1 BitRange.  It is possible to do a more precise | 
 |  190   // decompostion into several BitRanges.  2 BitRanges might be the sweet-spot | 
 |  191   // since it prevents change-of-sign polluting the result. | 
 |  192   // | 
 |  193   // E.g.  [-2,3] = {xxxxxxxx} as one BitRange, but is {1111111x, 000000xx} as | 
 |  194   // two. | 
 |  195   // | 
 |  196   //   [-2,3] ^ [-1,5] = {xxxxxxxx} ^ {xxxxxxxx} = xxxxxxxx | 
 |  197   // | 
 |  198   // With a 2x2 decomposition, there are 4 intermediate results. | 
 |  199   // | 
 |  200   //   [-2,3] ^ [-1,5] = {1111111x, 000000xx} ^ {11111111, 00000xxx} | 
 |  201   //     result11 = 1111111x ^ 11111111 = 0000000x | 
 |  202   //     result12 = 1111111x ^ 00000xxx = 11111xxx | 
 |  203   //     result21 = 000000xx ^ 11111111 = 111111xx | 
 |  204   //     result22 = 000000xx ^ 00000xxx = 00000xxx | 
 |  205   // | 
 |  206   // These can be accumulated into a range as follows: | 
 |  207   // | 
 |  208   //     result11.ExtendRange(&lower, &upper);  // 0, 1 | 
 |  209   //     result12.ExtendRange(&lower, &upper);  // -8, 1 | 
 |  210   //     result21.ExtendRange(&lower, &upper);  // -8, 1 | 
 |  211   //     result22.ExtendRange(&lower, &upper);  // -8, 7 | 
 |  212   //   = [-8,7] | 
 |  213  | 
 |  214   { | 
 |  215     BitRange r1(~0x000C, 0x0022);   // 0010xx10 | 
 |  216     BitRange r2(~0x0003, 0x0004);   // 0000x1xx | 
 |  217     int32_t lo = kMaxInt, hi = kMinInt; | 
 |  218     r1.ExtendRange(&lo, &hi); | 
 |  219     CHECK_EQ(0x22, lo); | 
 |  220     CHECK_EQ(0x2E, hi); | 
 |  221  | 
 |  222     r2.ExtendRange(&lo, &hi); | 
 |  223     CHECK_EQ(0x04, lo); | 
 |  224     CHECK_EQ(0x2E, hi); | 
 |  225   } | 
 |  226  | 
 |  227   { | 
 |  228     BitRange r1(~0, -1);   // 11111111 | 
 |  229     BitRange r2(~1, 0);    // 0000000x | 
 |  230     int32_t lo = kMaxInt, hi = kMinInt; | 
 |  231     r1.ExtendRange(&lo, &hi); | 
 |  232     CHECK_EQ(-1, lo); | 
 |  233     CHECK_EQ(-1, hi); | 
 |  234  | 
 |  235     r2.ExtendRange(&lo, &hi); | 
 |  236     CHECK_EQ(-1, lo); | 
 |  237     CHECK_EQ(1, hi); | 
 |  238   } | 
 |  239 } | 
 |  240  | 
 |  241  | 
 |  242 TEST(BitRangeOps) { | 
 |  243   // xxxx & 000x => 000x | 
 |  244   CheckOp(kMinInt, kMaxInt,  0, 1,  &BitRange::And,  0, 1); | 
 |  245  | 
 |  246   CheckOp(3, 7,  0, 0,  &BitRange::Or,  0, 7); | 
 |  247   CheckOp(4, 5,  0, 0,  &BitRange::Or,  4, 5); | 
 |  248   CheckOp(3, 7,  4, 4,  &BitRange::Or,  4, 7); | 
 |  249   CheckOp(0, 99,  4, 4, &BitRange::Or,  4, 127); | 
 |  250  | 
 |  251   // 01xx ^ 0100 -> 00xx | 
 |  252   CheckOp(4, 7,  4, 4,  &BitRange::Xor,  0, 3); | 
 |  253   // 00xx ^ 0100 -> 01xx | 
 |  254   CheckOp(0, 3,  4, 4,  &BitRange::Xor,  4, 7); | 
 |  255 } | 
| OLD | NEW |