summaryrefslogtreecommitdiff
path: root/chapter14
diff options
context:
space:
mode:
Diffstat (limited to 'chapter14')
-rw-r--r--chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java4
-rw-r--r--chapter14/src/test/java/com/seaofnodes/simple/Chapter14Test.java18
2 files changed, 20 insertions, 2 deletions
diff --git a/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java
index 8a2c9406..8ba45d26 100644
--- a/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java
+++ b/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java
@@ -22,7 +22,9 @@ public class MinusNode extends Node {
public Type compute() {
if( in(1)._type instanceof TypeInteger i0 ) {
if( i0.isHigh() ) return TypeInteger.TOP;
- return i0==TypeInteger.BOT ? TypeInteger.BOT : TypeInteger.make(-i0._max,-i0._min);
+ // Catch overflow wrapping on `-Long.MIN_VALUE`
+ if( i0 == TypeInteger.BOT || i0._min == Long.MIN_VALUE ) return TypeInteger.BOT;
+ return TypeInteger.make(-i0._max,-i0._min);
}
return TypeInteger.TOP.meet(in(1)._type);
}
diff --git a/chapter14/src/test/java/com/seaofnodes/simple/Chapter14Test.java b/chapter14/src/test/java/com/seaofnodes/simple/Chapter14Test.java
index 5f7cf954..5a62b905 100644
--- a/chapter14/src/test/java/com/seaofnodes/simple/Chapter14Test.java
+++ b/chapter14/src/test/java/com/seaofnodes/simple/Chapter14Test.java
@@ -15,7 +15,7 @@ public class Chapter14Test {
"""
return 3.14;
""");
- StopNode stop = parser.parse(false).iterate(false);
+ StopNode stop = parser.parse(false).iterate(true);
assertEquals("return 3.14;", stop.toString());
assertEquals(3.14, Evaluator.evaluate(stop, 0));
}
@@ -142,6 +142,22 @@ return c; //
}
@Test
+ public void testWrapMinus() {
+ Parser parser = new Parser(
+"""
+int MAX = 9223372036854775807; //0x7FFFFFFFFFFFFFFF;
+int i = (arg&MAX) + -MAX + -1; // Basically (e0) + Long.MIN_VALUE
+int j = -i; // Negating Long.MIN_VALUE wraps, cannot constant fold
+if (arg) j = 1;
+return j;
+""");
+ StopNode stop = parser.parse(false).iterate(true);
+ assertEquals("return Phi(Region28,1,(-((arg&9223372036854775807)+-9223372036854775808)));", stop.toString());
+ assertEquals(-9223372036854775808L, Evaluator.evaluate(stop, 0));
+ assertEquals(1, Evaluator.evaluate(stop, 1));
+ }
+
+ @Test
public void testOr() {
Parser parser = new Parser(
"""