1 /*
   2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.nodes.test;
  24 
  25 import static org.graalvm.compiler.core.test.GraalCompilerTest.getInitialOptions;
  26 import static org.junit.Assert.assertEquals;
  27 import static org.junit.Assert.assertFalse;
  28 
  29 import java.math.BigInteger;
  30 
  31 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
  32 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp;
  33 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
  34 import org.graalvm.compiler.core.common.type.IntegerStamp;
  35 import org.graalvm.compiler.core.common.type.Stamp;
  36 import org.graalvm.compiler.core.common.type.StampFactory;
  37 import org.graalvm.compiler.debug.DebugContext;
  38 import org.graalvm.compiler.graph.test.GraphTest;
  39 import org.graalvm.compiler.nodes.ConstantNode;
  40 import org.graalvm.compiler.nodes.StructuredGraph;
  41 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  42 import org.graalvm.compiler.options.OptionValues;
  43 import org.junit.Assert;
  44 import org.junit.Before;
  45 import org.junit.Test;
  46 
  47 import jdk.vm.ci.meta.JavaConstant;
  48 import jdk.vm.ci.meta.JavaKind;
  49 
  50 /**
  51  * This class tests that integer stamps are created correctly for constants.
  52  */
  53 public class IntegerStampTest extends GraphTest {
  54 
  55     private StructuredGraph graph;
  56 
  57     private static Stamp addIntStamp(Stamp a, Stamp b) {
  58         return IntegerStamp.OPS.getAdd().foldStamp(a, b);
  59     }
  60 
  61     @Before
  62     public void before() {
  63         OptionValues options = getInitialOptions();
  64         DebugContext debug = getDebug(options);
  65         graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES).build();
  66     }
  67 
  68     @Test
  69     public void testBooleanConstant() {
  70         assertEquals(IntegerStamp.create(32, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp());
  71         assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp());
  72     }
  73 
  74     @Test
  75     public void testByteConstant() {
  76         assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
  77         assertEquals(IntegerStamp.create(32, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
  78         assertEquals(IntegerStamp.create(32, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp());
  79         assertEquals(IntegerStamp.create(32, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
  80         assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp());
  81     }
  82 
  83     @Test
  84     public void testShortConstant() {
  85         assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
  86         assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
  87         assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp());
  88         assertEquals(IntegerStamp.create(32, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
  89         assertEquals(IntegerStamp.create(32, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp());
  90     }
  91 
  92     @Test
  93     public void testCharConstant() {
  94         assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp());
  95         assertEquals(IntegerStamp.create(32, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp());
  96         assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp());
  97         assertEquals(IntegerStamp.create(32, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp());
  98     }
  99 
 100     @Test
 101     public void testIntConstant() {
 102         assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp());
 103         assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp());
 104         assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp());
 105         assertEquals(IntegerStamp.create(32, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp());
 106         assertEquals(IntegerStamp.create(32, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp());
 107     }
 108 
 109     @Test
 110     public void testLongConstant() {
 111         assertEquals(IntegerStamp.create(64, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp());
 112         assertEquals(IntegerStamp.create(64, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp());
 113         assertEquals(IntegerStamp.create(64, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp());
 114         assertEquals(IntegerStamp.create(64, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp());
 115         assertEquals(IntegerStamp.create(64, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp());
 116     }
 117 
 118     @Test
 119     public void testPositiveRanges() {
 120         assertEquals(IntegerStamp.create(32, 0, 0, 0, 0), StampFactory.forInteger(JavaKind.Int, 0, 0));
 121         assertEquals(IntegerStamp.create(32, 0, 1, 0, 1), StampFactory.forInteger(JavaKind.Int, 0, 1));
 122         assertEquals(IntegerStamp.create(32, 0, 0x123, 0, 0x1ff), StampFactory.forInteger(JavaKind.Int, 0, 0x123));
 123         assertEquals(IntegerStamp.create(32, 0x120, 0x123, 0x120, 0x123), StampFactory.forInteger(JavaKind.Int, 0x120, 0x123));
 124         assertEquals(IntegerStamp.create(32, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(JavaKind.Int, 10000, 15000));
 125         assertEquals(IntegerStamp.create(64, 0, 1, 0, 1), StampFactory.forInteger(JavaKind.Long, 0, 1));
 126         assertEquals(IntegerStamp.create(64, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(JavaKind.Long, 10000, 15000));
 127         assertEquals(IntegerStamp.create(64, 140000000000L, 150000000000L, 0x2000000000L, 0x23ffffffffL), StampFactory.forInteger(JavaKind.Long, 140000000000L, 150000000000L));
 128     }
 129 
 130     @Test
 131     public void testNegativeRanges() {
 132         assertEquals(IntegerStamp.create(32, -2, -1, 0xfffffffeL, 0xffffffffL), StampFactory.forInteger(JavaKind.Int, -2, -1));
 133         assertEquals(IntegerStamp.create(32, -20, -10, 0xffffffe0L, 0xffffffffL), StampFactory.forInteger(JavaKind.Int, -20, -10));
 134         assertEquals(IntegerStamp.create(32, -10000, 0, 0, 0xffffffffL), StampFactory.forInteger(JavaKind.Int, -10000, 0));
 135         assertEquals(IntegerStamp.create(32, -10000, -1, 0xffffc000L, 0xffffffffL), StampFactory.forInteger(JavaKind.Int, -10000, -1));
 136         assertEquals(IntegerStamp.create(32, -10010, -10000, 0xffffd8e0L, 0xffffd8ffL), StampFactory.forInteger(JavaKind.Int, -10010, -10000));
 137         assertEquals(IntegerStamp.create(64, -2, -1, 0xfffffffffffffffeL, 0xffffffffffffffffL), StampFactory.forInteger(JavaKind.Long, -2, -1));
 138         assertEquals(IntegerStamp.create(64, -10010, -10000, 0xffffffffffffd8e0L, 0xffffffffffffd8ffL), StampFactory.forInteger(JavaKind.Long, -10010, -10000));
 139         assertEquals(IntegerStamp.create(64, -150000000000L, -140000000000L, 0xffffffdc00000000L, 0xffffffdfffffffffL), StampFactory.forInteger(JavaKind.Long, -150000000000L, -140000000000L));
 140     }
 141 
 142     @Test
 143     public void testMixedRanges() {
 144         assertEquals(IntegerStamp.create(32, -1, 0, 0, 0xffffffffL), StampFactory.forInteger(JavaKind.Int, -1, 0));
 145         assertEquals(IntegerStamp.create(32, -10000, 1000, 0, 0xffffffffL), StampFactory.forInteger(JavaKind.Int, -10000, 1000));
 146         assertEquals(IntegerStamp.create(64, -10000, 1000, 0, 0xffffffffffffffffL), StampFactory.forInteger(JavaKind.Long, -10000, 1000));
 147     }
 148 
 149     private static Stamp narrowingKindConversion(IntegerStamp stamp, JavaKind kind) {
 150         Stamp narrow = IntegerStamp.OPS.getNarrow().foldStamp(stamp.getBits(), kind.getBitCount(), stamp);
 151         IntegerConvertOp<?> implicitExtend = kind.isUnsigned() ? IntegerStamp.OPS.getZeroExtend() : IntegerStamp.OPS.getSignExtend();
 152         return implicitExtend.foldStamp(kind.getBitCount(), 32, narrow);
 153     }
 154 
 155     @Test
 156     public void testNarrowingConversions() {
 157         // byte cases
 158         assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 0), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, 0, 0), JavaKind.Byte));
 159         assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 10), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, 0, 10), JavaKind.Byte));
 160         assertEquals(StampFactory.forInteger(JavaKind.Int, 10, 20), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, 10, 20), JavaKind.Byte));
 161         assertEquals(StampFactory.forInteger(JavaKind.Int, -10, 0), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, -10, 0), JavaKind.Byte));
 162         assertEquals(StampFactory.forInteger(JavaKind.Int, -20, -10), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, -20, -10), JavaKind.Byte));
 163         assertEquals(StampFactory.forInteger(JavaKind.Int, Byte.MIN_VALUE, Byte.MAX_VALUE), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, 100, 200), JavaKind.Byte));
 164         assertEquals(StampFactory.forInteger(JavaKind.Int, Byte.MIN_VALUE, Byte.MAX_VALUE), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, -100, 200), JavaKind.Byte));
 165         assertEquals(StampFactory.forInteger(JavaKind.Int, Byte.MIN_VALUE, Byte.MAX_VALUE), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, -200, -100), JavaKind.Byte));
 166         // char cases
 167         assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 10), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, 0, 10), JavaKind.Char));
 168         assertEquals(StampFactory.forInteger(JavaKind.Int, 10, 20), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, 10, 20), JavaKind.Char));
 169         assertEquals(StampFactory.forInteger(JavaKind.Int, Character.MIN_VALUE, Character.MAX_VALUE), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, 20000, 80000), JavaKind.Char));
 170         assertEquals(StampFactory.forInteger(JavaKind.Int, Character.MIN_VALUE, Character.MAX_VALUE), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, -10000, 40000), JavaKind.Char));
 171         assertEquals(StampFactory.forInteger(JavaKind.Int, Character.MIN_VALUE, Character.MAX_VALUE), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, -40000, -10000), JavaKind.Char));
 172         // short cases
 173         assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 10), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, 0, 10), JavaKind.Short));
 174         assertEquals(StampFactory.forInteger(JavaKind.Int, 10, 20), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, 10, 20), JavaKind.Short));
 175         assertEquals(StampFactory.forInteger(JavaKind.Int, Short.MIN_VALUE, Short.MAX_VALUE), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, 20000, 40000), JavaKind.Short));
 176         assertEquals(StampFactory.forInteger(JavaKind.Int, Short.MIN_VALUE, Short.MAX_VALUE), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, -10000, 40000), JavaKind.Short));
 177         assertEquals(StampFactory.forInteger(JavaKind.Int, Short.MIN_VALUE, Short.MAX_VALUE), narrowingKindConversion(StampFactory.forInteger(JavaKind.Int, -40000, -10000), JavaKind.Short));
 178         // int cases
 179         assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 10), narrowingKindConversion(StampFactory.forInteger(JavaKind.Long, 0, 10), JavaKind.Int));
 180         assertEquals(StampFactory.forInteger(JavaKind.Int, 10, 20), narrowingKindConversion(StampFactory.forInteger(JavaKind.Long, 10, 20), JavaKind.Int));
 181         assertEquals(StampFactory.forInteger(JavaKind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE),
 182                         narrowingKindConversion(StampFactory.forInteger(JavaKind.Long, 20000000000L, 40000000000L), JavaKind.Int));
 183         assertEquals(StampFactory.forInteger(JavaKind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE),
 184                         narrowingKindConversion(StampFactory.forInteger(JavaKind.Long, -10000000000L, 40000000000L), JavaKind.Int));
 185         assertEquals(StampFactory.forInteger(JavaKind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE),
 186                         narrowingKindConversion(StampFactory.forInteger(JavaKind.Long, -40000000000L, -10000000000L), JavaKind.Int));
 187     }
 188 
 189     @Test
 190     public void testMaskBasedNarrowing() {
 191         IntegerStamp stamp = IntegerStamp.create(32, 1, 2, 0x2, 0x3);
 192         IntegerStamp resultStamp = IntegerStamp.create(32, 2, 2);
 193         assertEquals(resultStamp, stamp);
 194     }
 195 
 196     @Test
 197     public void testJoinWeirdMasks() {
 198         IntegerStamp minusOneOrThree = IntegerStamp.create(32, -1, 3, 0x3, 0xFFFFFFFFL);
 199         IntegerStamp twoOrThree = IntegerStamp.create(32, 2, 3, 0x2, 0x3);
 200         IntegerStamp three = IntegerStamp.create(32, 3, 3, 0x3, 0x3);
 201         assertEquals(three, minusOneOrThree.join(twoOrThree));
 202 
 203         IntegerStamp minusOneOrThreeOrOne = IntegerStamp.create(32, -1, 3, 0x1, 0xFFFFFFFFL);
 204         assertEquals(three, minusOneOrThreeOrOne.join(twoOrThree));
 205 
 206         IntegerStamp a = IntegerStamp.create(32, 0b101, 0b110, 0b100, 0b111);
 207         IntegerStamp b = IntegerStamp.create(32, 0b011, 0b110, 0b010, 0b111);
 208 
 209         // This exercises a special case:
 210         // The new lowest bound is max(0b101, 0b011) = 0b101
 211         // The new down mask is (0b100 | 0b010) = 0b110
 212         // Now based on lowest bound and down mask, we know that the new lowest bound is 0b110
 213         // Just making an or with the new down mask would give however (0b110 | 0b101) = 0b111 and
 214         // would therefore be wrong.
 215         // New upper bound is 0b110.
 216 
 217         IntegerStamp result = IntegerStamp.create(32, 0b110, 0b110, 0b110, 0b110);
 218         assertEquals(result, a.join(b));
 219     }
 220 
 221     @Test
 222     public void testXor() {
 223         assertEquals(IntegerStamp.create(32, 0, 0xff, 0, 0xff), IntegerStamp.OPS.getXor().foldStamp(IntegerStamp.create(32, 0, 0, 0, 0), IntegerStamp.create(32, 0, 0xff, 0, 0xff)));
 224         assertEquals(IntegerStamp.create(32, 0x10, 0x1f, 0x10, 0x1f), IntegerStamp.OPS.getXor().foldStamp(IntegerStamp.create(32, 0, 0, 0, 0), IntegerStamp.create(32, 0x10, 0x1f, 0x10, 0x1f)));
 225         assertEquals(IntegerStamp.create(32, 0x0, 0xf, 0x0, 0xf),
 226                         IntegerStamp.OPS.getXor().foldStamp(IntegerStamp.create(32, 0x10, 0x10, 0x10, 0x10), IntegerStamp.create(32, 0x10, 0x1f, 0x10, 0x1f)));
 227         assertEquals(IntegerStamp.create(32, 0x10, 0x1f, 0x10, 0x1f),
 228                         IntegerStamp.OPS.getXor().foldStamp(IntegerStamp.create(32, 0x10, 0x10, 0x10, 0x10), IntegerStamp.create(32, 0x0, 0xf, 0x0, 0xf)));
 229     }
 230 
 231     @Test
 232     public void testNot() {
 233         assertEquals(IntegerStamp.create(32, -11, -1, 0xffff_fff0L, 0xffff_ffffL), IntegerStamp.OPS.getNot().foldStamp(IntegerStamp.create(32, 0, 10, 0, 0xf)));
 234     }
 235 
 236     @Test
 237     public void testAddIntSimple() {
 238         assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 30, 0, 31), addIntStamp(StampFactory.forInteger(JavaKind.Int, 0, 10), StampFactory.forInteger(JavaKind.Int, 0, 20)));
 239     }
 240 
 241     @Test
 242     public void testAddNegativeOverFlowInt1() {
 243         assertEquals(StampFactory.forInteger(JavaKind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0xffff_ffffL),
 244                         addIntStamp(StampFactory.forInteger(JavaKind.Int, Integer.MIN_VALUE, 0), StampFactory.forInteger(JavaKind.Int, -1, 0)));
 245     }
 246 
 247     @Test
 248     public void testAddNegativeOverFlowInt2() {
 249         assertEquals(StampFactory.forInteger(JavaKind.Int, Integer.MAX_VALUE - 2, Integer.MAX_VALUE, 0x7fff_fffcL, 0x7fff_ffffL),
 250                         addIntStamp(StampFactory.forInteger(JavaKind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE + 1), StampFactory.forInteger(JavaKind.Int, -3, -2)));
 251     }
 252 
 253     @Test
 254     public void testAddPositiveOverFlowInt1() {
 255         assertEquals(StampFactory.forKind(JavaKind.Int), addIntStamp(StampFactory.forInteger(JavaKind.Int, 0, 1), StampFactory.forInteger(JavaKind.Int, 0, Integer.MAX_VALUE)));
 256     }
 257 
 258     @Test
 259     public void testAddPositiveOverFlowInt2() {
 260         assertEquals(StampFactory.forInteger(JavaKind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE + 2),
 261                         addIntStamp(StampFactory.forInteger(JavaKind.Int, Integer.MAX_VALUE - 1, Integer.MAX_VALUE), StampFactory.forInteger(JavaKind.Int, 2, 3)));
 262     }
 263 
 264     @Test
 265     public void testAddOverFlowsInt() {
 266         assertEquals(StampFactory.forKind(JavaKind.Int), addIntStamp(StampFactory.forInteger(JavaKind.Int, -1, 1), StampFactory.forInteger(JavaKind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE)));
 267     }
 268 
 269     @Test
 270     public void testAddLongSimple() {
 271         assertEquals(StampFactory.forInteger(JavaKind.Long, 0, 30, 0, 31), addIntStamp(StampFactory.forInteger(JavaKind.Long, 0, 10), StampFactory.forInteger(JavaKind.Long, 0, 20)));
 272     }
 273 
 274     @Test
 275     public void testAddNegativOverFlowLong1() {
 276         assertEquals(StampFactory.forInteger(JavaKind.Long, Long.MIN_VALUE, Long.MAX_VALUE, 0, 0xffff_ffff_ffff_ffffL),
 277                         addIntStamp(StampFactory.forInteger(JavaKind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(JavaKind.Long, Integer.MIN_VALUE, Integer.MAX_VALUE)));
 278     }
 279 
 280     @Test
 281     public void testAddNegativeOverFlowLong2() {
 282         assertEquals(StampFactory.forInteger(JavaKind.Long, Long.MAX_VALUE - 2, Long.MAX_VALUE),
 283                         addIntStamp(StampFactory.forInteger(JavaKind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(JavaKind.Long, -3, -2)));
 284     }
 285 
 286     @Test
 287     public void testAddPositiveOverFlowLong1() {
 288         assertEquals(StampFactory.forKind(JavaKind.Long), addIntStamp(StampFactory.forInteger(JavaKind.Long, 0, 1), StampFactory.forInteger(JavaKind.Long, 0, Long.MAX_VALUE)));
 289     }
 290 
 291     @Test
 292     public void testAddPositiveOverFlowLong2() {
 293         assertEquals(StampFactory.forInteger(JavaKind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 2),
 294                         addIntStamp(StampFactory.forInteger(JavaKind.Long, Long.MAX_VALUE - 1, Long.MAX_VALUE), StampFactory.forInteger(JavaKind.Long, 2, 3)));
 295     }
 296 
 297     @Test
 298     public void testAddOverFlowsLong() {
 299         assertEquals(StampFactory.forKind(JavaKind.Long), addIntStamp(StampFactory.forInteger(JavaKind.Long, -1, 1), StampFactory.forInteger(JavaKind.Long, Long.MIN_VALUE, Long.MAX_VALUE)));
 300     }
 301 
 302     @Test
 303     public void testAdd1() {
 304         assertEquals(StampFactory.forInteger(JavaKind.Int, Integer.MIN_VALUE + 1, 31 + (Integer.MIN_VALUE + 1)),
 305                         addIntStamp(StampFactory.forInteger(JavaKind.Int, 0, 31), StampFactory.forInteger(JavaKind.Int, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 1)));
 306     }
 307 
 308     @Test
 309     public void testAdd2() {
 310         assertEquals(StampFactory.forInteger(JavaKind.Int, 0x8000_007e, 0x8000_007f, 0x8000_007eL, 0x8000_007fL),
 311                         addIntStamp(StampFactory.forInteger(JavaKind.Int, 0x7fff_fffe, 0x7fff_ffff, 0x7fff_fffeL, 0x7ffff_fffL), StampFactory.forInteger(JavaKind.Int, 128, 128)));
 312     }
 313 
 314     @Test
 315     public void testAdd3() {
 316         assertEquals(StampFactory.forInteger(JavaKind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL),
 317                         addIntStamp(StampFactory.forInteger(JavaKind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL),
 318                                         StampFactory.forInteger(JavaKind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL)));
 319 
 320     }
 321 
 322     @Test
 323     public void testAnd() {
 324         assertEquals(IntegerStamp.create(32, Integer.MIN_VALUE, 0x40000000L, 0, 0xc0000000L),
 325                         IntegerStamp.OPS.getAnd().foldStamp(StampFactory.forKind(JavaKind.Int), StampFactory.forConstant(JavaConstant.forInt(0xc0000000))));
 326     }
 327 
 328     private static void testSignExtendShort(long lower, long upper) {
 329         Stamp shortStamp = StampFactory.forInteger(16, lower, upper);
 330         Stamp intStamp = IntegerStamp.OPS.getSignExtend().foldStamp(16, 32, shortStamp);
 331         assertEquals(StampFactory.forInteger(32, lower, upper), intStamp);
 332     }
 333 
 334     @Test
 335     public void testSignExtend() {
 336         testSignExtendShort(5, 7);
 337         testSignExtendShort(0, 42);
 338         testSignExtendShort(-42, -1);
 339         testSignExtendShort(-42, 0);
 340         testSignExtendShort(-1, 1);
 341         testSignExtendShort(Short.MIN_VALUE, Short.MAX_VALUE);
 342     }
 343 
 344     private static void testZeroExtendShort(long lower, long upper, long newLower, long newUpper) {
 345         Stamp shortStamp = StampFactory.forInteger(16, lower, upper);
 346         Stamp intStamp = IntegerStamp.OPS.getZeroExtend().foldStamp(16, 32, shortStamp);
 347         assertEquals(StampFactory.forInteger(32, newLower, newUpper), intStamp);
 348     }
 349 
 350     @Test
 351     public void testZeroExtend() {
 352         testZeroExtendShort(5, 7, 5, 7);
 353         testZeroExtendShort(0, 42, 0, 42);
 354         testZeroExtendShort(-42, -1, 0xFFFF - 41, 0xFFFF);
 355         testZeroExtendShort(-42, 0, 0, 0xFFFF);
 356         testZeroExtendShort(-1, 1, 0, 0xFFFF);
 357         testZeroExtendShort(Short.MIN_VALUE, Short.MAX_VALUE, 0, 0xFFFF);
 358     }
 359 
 360     @Test
 361     public void testIllegalJoin() {
 362         assertFalse(IntegerStamp.create(32, 0, 0xff00, 0, 0xff00).join(IntegerStamp.create(32, 1, 0xff, 0x00, 0xff)).hasValues());
 363         assertFalse(IntegerStamp.create(32, 0x100, 0xff00, 0, 0xff00).join(IntegerStamp.create(32, 0, 0xff, 0x00, 0xff)).hasValues());
 364     }
 365 
 366     @Test
 367     public void testShiftLeft() {
 368         ShiftOp<?> shl = IntegerStamp.OPS.getShl();
 369         assertEquals(IntegerStamp.create(32, 0, 0x1ff, 0, 0x1ff), shl.foldStamp(IntegerStamp.create(32, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 0, 1, 0, 1)));
 370         assertEquals(IntegerStamp.create(32, 0, 0x1fe0, 0, 0x1fe0), shl.foldStamp(IntegerStamp.create(32, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 371         assertEquals(IntegerStamp.create(32, 0x1e0, 0x1fe0, 0, 0x1fe0), shl.foldStamp(IntegerStamp.create(32, 0xf, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 372         assertEquals(IntegerStamp.create(32, -4096, -4096, -4096, -4096), shl.foldStamp(IntegerStamp.create(32, -16, -16, -16, -16), IntegerStamp.create(32, 8, 8, 8, 8)));
 373         assertEquals(StampFactory.empty(JavaKind.Int), shl.foldStamp(StampFactory.empty(JavaKind.Int), IntegerStamp.create(32, 5, 5, 5, 5)));
 374         assertEquals(StampFactory.empty(JavaKind.Int), shl.foldStamp(IntegerStamp.create(32, 0xf, 0xff, 0, 0xff), (IntegerStamp) StampFactory.empty(JavaKind.Int)));
 375 
 376         assertEquals(IntegerStamp.create(64, 0, 0x1ff, 0, 0x1ff), shl.foldStamp(IntegerStamp.create(64, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 0, 1, 0, 1)));
 377         assertEquals(IntegerStamp.create(64, 0, 0x1fe0, 0, 0x1fe0), shl.foldStamp(IntegerStamp.create(64, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 378         assertEquals(IntegerStamp.create(64, 0x1e0, 0x1fe0, 0, 0x1fe0), shl.foldStamp(IntegerStamp.create(64, 0xf, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 379         assertEquals(IntegerStamp.create(64, -4096, -4096, -4096, -4096), shl.foldStamp(IntegerStamp.create(64, -16, -16, -16, -16), IntegerStamp.create(32, 8, 8, 8, 8)));
 380         assertEquals(StampFactory.empty(JavaKind.Long), shl.foldStamp(StampFactory.empty(JavaKind.Long), IntegerStamp.create(32, 5, 5, 5, 5)));
 381         assertEquals(StampFactory.empty(JavaKind.Long), shl.foldStamp(IntegerStamp.create(64, 0xf, 0xff, 0, 0xff), (IntegerStamp) StampFactory.empty(JavaKind.Int)));
 382     }
 383 
 384     @Test
 385     public void testUnsignedShiftRight() {
 386         ShiftOp<?> ushr = IntegerStamp.OPS.getUShr();
 387         assertEquals(IntegerStamp.create(32, 0, 0xff, 0, 0xff), ushr.foldStamp(IntegerStamp.create(32, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 0, 1, 0, 1)));
 388         assertEquals(IntegerStamp.create(32, 0, 0x07, 0, 0x07), ushr.foldStamp(IntegerStamp.create(32, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 389         assertEquals(IntegerStamp.create(32, 0x0, 0x07, 0, 0x07), ushr.foldStamp(IntegerStamp.create(32, 0xf, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 390         assertEquals(IntegerStamp.create(32, 0xffffff, 0xffffff, 0xffffff, 0xffffff), ushr.foldStamp(IntegerStamp.create(32, -16, -16, -16, -16), IntegerStamp.create(32, 8, 8, 8, 8)));
 391         assertEquals(StampFactory.empty(JavaKind.Int), ushr.foldStamp(StampFactory.empty(JavaKind.Int), IntegerStamp.create(32, 5, 5, 5, 5)));
 392         assertEquals(StampFactory.empty(JavaKind.Int), ushr.foldStamp(IntegerStamp.create(32, 0xf, 0xff, 0, 0xff), (IntegerStamp) StampFactory.empty(JavaKind.Int)));
 393 
 394         assertEquals(IntegerStamp.create(64, 0, 0xff, 0, 0xff), ushr.foldStamp(IntegerStamp.create(64, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 0, 1, 0, 1)));
 395         assertEquals(IntegerStamp.create(64, 0, 0x07, 0, 0x07), ushr.foldStamp(IntegerStamp.create(64, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 396         assertEquals(IntegerStamp.create(64, 0x0, 0x07, 0, 0x07), ushr.foldStamp(IntegerStamp.create(64, 0xf, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 397         assertEquals(IntegerStamp.create(64, 0xffffffffffffffL, 0xffffffffffffffL, 0xffffffffffffffL, 0xffffffffffffffL),
 398                         ushr.foldStamp(IntegerStamp.create(64, -16, -16, -16, -16), IntegerStamp.create(32, 8, 8, 8, 8)));
 399         assertEquals(StampFactory.empty(JavaKind.Long), ushr.foldStamp(StampFactory.empty(JavaKind.Long), IntegerStamp.create(32, 5, 5, 5, 5)));
 400         assertEquals(StampFactory.empty(JavaKind.Long), ushr.foldStamp(IntegerStamp.create(64, 0xf, 0xff, 0, 0xff), (IntegerStamp) StampFactory.empty(JavaKind.Int)));
 401     }
 402 
 403     @Test
 404     public void testShiftRight() {
 405         ShiftOp<?> shr = IntegerStamp.OPS.getShr();
 406         assertEquals(IntegerStamp.create(32, 0, 0xff, 0, 0xff), shr.foldStamp(IntegerStamp.create(32, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 0, 1, 0, 1)));
 407         assertEquals(IntegerStamp.create(32, 0, 0x07, 0, 0x07), shr.foldStamp(IntegerStamp.create(32, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 408         assertEquals(IntegerStamp.create(32, 0x0, 0x07, 0, 0x07), shr.foldStamp(IntegerStamp.create(32, 0xf, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 409         assertEquals(IntegerStamp.create(32, -1, -1, -1, -1), shr.foldStamp(IntegerStamp.create(32, -16, -16, -16, -16), IntegerStamp.create(32, 8, 8, 8, 8)));
 410         assertEquals(StampFactory.empty(JavaKind.Int), shr.foldStamp(StampFactory.empty(JavaKind.Int), IntegerStamp.create(32, 5, 5, 5, 5)));
 411         assertEquals(StampFactory.empty(JavaKind.Int), shr.foldStamp(IntegerStamp.create(32, 0xf, 0xff, 0, 0xff), (IntegerStamp) StampFactory.empty(JavaKind.Int)));
 412 
 413         assertEquals(IntegerStamp.create(64, 0, 0xff, 0, 0xff), shr.foldStamp(IntegerStamp.create(64, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 0, 1, 0, 1)));
 414         assertEquals(IntegerStamp.create(64, 0, 0x07, 0, 0x07), shr.foldStamp(IntegerStamp.create(64, 0, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 415         assertEquals(IntegerStamp.create(64, 0x0, 0x07, 0, 0x07), shr.foldStamp(IntegerStamp.create(64, 0xf, 0xff, 0, 0xff), IntegerStamp.create(32, 5, 5, 5, 5)));
 416         assertEquals(IntegerStamp.create(64, -1, -1, -1, -1), shr.foldStamp(IntegerStamp.create(64, -16, -16, -16, -16), IntegerStamp.create(32, 8, 8, 8, 8)));
 417         assertEquals(StampFactory.empty(JavaKind.Long), shr.foldStamp(StampFactory.empty(JavaKind.Long), IntegerStamp.create(32, 5, 5, 5, 5)));
 418         assertEquals(StampFactory.empty(JavaKind.Long), shr.foldStamp(IntegerStamp.create(64, 0xf, 0xff, 0, 0xff), (IntegerStamp) StampFactory.empty(JavaKind.Int)));
 419     }
 420 
 421     @Test
 422     public void testMulHigh() {
 423         testSomeMulHigh(IntegerStamp.OPS.getMulHigh());
 424     }
 425 
 426     @Test
 427     public void testUMulHigh() {
 428         testSomeMulHigh(IntegerStamp.OPS.getUMulHigh());
 429     }
 430 
 431     private static void testSomeMulHigh(BinaryOp<?> someMulHigh) {
 432         // 32 bits
 433         testMulHigh(someMulHigh, 0, 0, 32);
 434 
 435         testMulHigh(someMulHigh, 1, 1, 32);
 436         testMulHigh(someMulHigh, 1, 5, 32);
 437         testMulHigh(someMulHigh, 256, 256, 32);
 438         testMulHigh(someMulHigh, 0xFFFFFFF, 0xFFFFFFA, 32);
 439         testMulHigh(someMulHigh, Integer.MAX_VALUE, 2, 32);
 440 
 441         testMulHigh(someMulHigh, -1, -1, 32);
 442         testMulHigh(someMulHigh, -1, -5, 32);
 443         testMulHigh(someMulHigh, -256, -256, 32);
 444         testMulHigh(someMulHigh, -0xFFFFFFF, -0xFFFFFFA, 32);
 445         testMulHigh(someMulHigh, Integer.MIN_VALUE, -2, 32);
 446 
 447         testMulHigh(someMulHigh, -1, 1, 32);
 448         testMulHigh(someMulHigh, -1, 5, 32);
 449         testMulHigh(someMulHigh, -256, 256, 32);
 450         testMulHigh(someMulHigh, -0xFFFFFFF, 0xFFFFFFA, 32);
 451         testMulHigh(someMulHigh, Integer.MIN_VALUE, 2, 32);
 452 
 453         testMulHigh(someMulHigh, Integer.MIN_VALUE, Integer.MIN_VALUE, 32);
 454         testMulHigh(someMulHigh, Integer.MAX_VALUE, Integer.MAX_VALUE, 32);
 455 
 456         assertEquals(StampFactory.forKind(JavaKind.Int).empty(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Int).empty(), StampFactory.forKind(JavaKind.Int).empty()));
 457         assertEquals(StampFactory.forKind(JavaKind.Int).empty(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Int).empty(), StampFactory.forKind(JavaKind.Int).unrestricted()));
 458         assertEquals(StampFactory.forKind(JavaKind.Int).empty(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Int).empty(), IntegerStamp.create(32, 0, 0)));
 459         assertEquals(StampFactory.forKind(JavaKind.Int).empty(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Int).empty(), IntegerStamp.create(32, 1, 1)));
 460         assertEquals(StampFactory.forKind(JavaKind.Int).empty(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Int).empty(), IntegerStamp.create(32, -1, -1)));
 461 
 462         assertEquals(StampFactory.forKind(JavaKind.Int).unrestricted(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Int).unrestricted(), StampFactory.forKind(JavaKind.Int).unrestricted()));
 463         assertEquals(StampFactory.forKind(JavaKind.Int).unrestricted(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Int).unrestricted(), IntegerStamp.create(32, 0, 0)));
 464         assertEquals(StampFactory.forKind(JavaKind.Int).unrestricted(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Int).unrestricted(), IntegerStamp.create(32, 1, 1)));
 465         assertEquals(StampFactory.forKind(JavaKind.Int).unrestricted(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Int).unrestricted(), IntegerStamp.create(32, -1, -1)));
 466 
 467         // 64 bits
 468         testMulHigh(someMulHigh, 0, 0, 64);
 469 
 470         testMulHigh(someMulHigh, 1, 1, 64);
 471         testMulHigh(someMulHigh, 1, 5, 64);
 472         testMulHigh(someMulHigh, 256, 256, 64);
 473         testMulHigh(someMulHigh, 0xFFFFFFF, 0xFFFFFFA, 64);
 474         testMulHigh(someMulHigh, 0xFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFAL, 64);
 475         testMulHigh(someMulHigh, Integer.MAX_VALUE, 2, 64);
 476         testMulHigh(someMulHigh, Long.MAX_VALUE, 2, 64);
 477 
 478         testMulHigh(someMulHigh, -1, -1, 64);
 479         testMulHigh(someMulHigh, -1, -5, 64);
 480         testMulHigh(someMulHigh, -256, -256, 64);
 481         testMulHigh(someMulHigh, -0xFFFFFFF, -0xFFFFFFA, 64);
 482         testMulHigh(someMulHigh, -0xFFFFFFFFFFFFFFL, -0xFFFFFFFFFFFFFAL, 64);
 483         testMulHigh(someMulHigh, Integer.MIN_VALUE, -2, 64);
 484         testMulHigh(someMulHigh, Long.MIN_VALUE, -2, 64);
 485 
 486         testMulHigh(someMulHigh, -1, 1, 64);
 487         testMulHigh(someMulHigh, -1, 5, 64);
 488         testMulHigh(someMulHigh, -256, 256, 64);
 489         testMulHigh(someMulHigh, -0xFFFFFFF, 0xFFFFFFA, 64);
 490         testMulHigh(someMulHigh, -0xFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFAL, 64);
 491         testMulHigh(someMulHigh, Integer.MIN_VALUE, 2, 64);
 492         testMulHigh(someMulHigh, Long.MIN_VALUE, 2, 64);
 493 
 494         testMulHigh(someMulHigh, Integer.MIN_VALUE, Integer.MIN_VALUE, 64);
 495         testMulHigh(someMulHigh, Long.MIN_VALUE, Long.MIN_VALUE, 64);
 496         testMulHigh(someMulHigh, Integer.MAX_VALUE, Integer.MAX_VALUE, 64);
 497         testMulHigh(someMulHigh, Long.MAX_VALUE, Long.MAX_VALUE, 64);
 498 
 499         assertEquals(StampFactory.forKind(JavaKind.Long).empty(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Long).empty(), StampFactory.forKind(JavaKind.Long).empty()));
 500         assertEquals(StampFactory.forKind(JavaKind.Long).empty(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Long).empty(), StampFactory.forKind(JavaKind.Long).unrestricted()));
 501         assertEquals(StampFactory.forKind(JavaKind.Long).empty(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Long).empty(), IntegerStamp.create(64, 0, 0)));
 502         assertEquals(StampFactory.forKind(JavaKind.Long).empty(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Long).empty(), IntegerStamp.create(64, 1, 1)));
 503         assertEquals(StampFactory.forKind(JavaKind.Long).empty(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Long).empty(), IntegerStamp.create(64, -1, -1)));
 504 
 505         assertEquals(StampFactory.forKind(JavaKind.Long).unrestricted(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Long).unrestricted(), StampFactory.forKind(JavaKind.Long).unrestricted()));
 506         assertEquals(StampFactory.forKind(JavaKind.Long).unrestricted(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Long).unrestricted(), IntegerStamp.create(64, 0, 0)));
 507         assertEquals(StampFactory.forKind(JavaKind.Long).unrestricted(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Long).unrestricted(), IntegerStamp.create(64, 1, 1)));
 508         assertEquals(StampFactory.forKind(JavaKind.Long).unrestricted(), someMulHigh.foldStamp(StampFactory.forKind(JavaKind.Long).unrestricted(), IntegerStamp.create(64, -1, -1)));
 509     }
 510 
 511     private static void testMulHigh(BinaryOp<?> someMulHigh, long a, long b, int bits) {
 512         long expectedResult = getExpectedValue(someMulHigh, a, b, bits);
 513         assertEquals(IntegerStamp.create(bits, expectedResult, expectedResult), someMulHigh.foldStamp(IntegerStamp.create(bits, a, a), IntegerStamp.create(bits, b, b)));
 514     }
 515 
 516     private static long getExpectedValue(BinaryOp<?> someMulHigh, long a, long b, int bits) {
 517         if (someMulHigh == IntegerStamp.OPS.getMulHigh()) {
 518             return mulHigh(a, b, bits);
 519         } else {
 520             assertEquals(IntegerStamp.OPS.getUMulHigh(), someMulHigh);
 521             return umulHigh(a, b, bits);
 522         }
 523     }
 524 
 525     private static long mulHigh(long a, long b, int bits) {
 526         BigInteger valA = BigInteger.valueOf(a);
 527         BigInteger valB = BigInteger.valueOf(b);
 528         BigInteger result = valA.multiply(valB).shiftRight(bits);
 529         if (bits == 32) {
 530             return result.intValue();
 531         } else {
 532             assertEquals(64, bits);
 533             return result.longValue();
 534         }
 535     }
 536 
 537     private static long umulHigh(long a, long b, int bits) {
 538         Assert.assertTrue(bits == 32 || bits == 64);
 539         BigInteger valA = BigInteger.valueOf(a);
 540         if (valA.compareTo(BigInteger.valueOf(0)) < 0) {
 541             valA = valA.add(BigInteger.ONE.shiftLeft(bits));
 542         }
 543         BigInteger valB = BigInteger.valueOf(b);
 544         if (valB.compareTo(BigInteger.valueOf(0)) < 0) {
 545             valB = valB.add(BigInteger.ONE.shiftLeft(bits));
 546         }
 547 
 548         BigInteger result = valA.multiply(valB).shiftRight(bits);
 549         if (bits == 32) {
 550             return result.intValue();
 551         } else {
 552             return result.longValue();
 553         }
 554     }
 555 
 556     @Test
 557     public void testDiv() {
 558         testDiv(32, Integer.MIN_VALUE, Integer.MAX_VALUE);
 559         testDiv(64, Long.MIN_VALUE, Long.MAX_VALUE);
 560     }
 561 
 562     private static void testDiv(int bits, long min, long max) {
 563         BinaryOp<?> div = IntegerStamp.OPS.getDiv();
 564         assertEquals(IntegerStamp.create(bits, -50, 50), div.foldStamp(IntegerStamp.create(bits, -100, 100), IntegerStamp.create(bits, 2, 5)));
 565         assertEquals(IntegerStamp.create(bits, 20, 500), div.foldStamp(IntegerStamp.create(bits, 100, 1000), IntegerStamp.create(bits, 2, 5)));
 566         assertEquals(IntegerStamp.create(bits, -500, -20), div.foldStamp(IntegerStamp.create(bits, -1000, -100), IntegerStamp.create(bits, 2, 5)));
 567         assertEquals(IntegerStamp.create(bits, min, max), div.foldStamp(IntegerStamp.create(bits, min, max), IntegerStamp.create(bits, 1, max)));
 568         assertEquals(IntegerStamp.create(bits, -100, 100), div.foldStamp(IntegerStamp.create(bits, -100, 100), IntegerStamp.create(bits, 1, max)));
 569         assertEquals(IntegerStamp.create(bits, 0, 1000), div.foldStamp(IntegerStamp.create(bits, 100, 1000), IntegerStamp.create(bits, 1, max)));
 570         assertEquals(IntegerStamp.create(bits, -1000, 0), div.foldStamp(IntegerStamp.create(bits, -1000, -100), IntegerStamp.create(bits, 1, max)));
 571     }
 572 }