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 }