< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java

Print this page
rev 56282 : [mq]: graal

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -24,16 +24,18 @@
 
 package org.graalvm.compiler.nodes.calc;
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
 
+import org.graalvm.compiler.core.common.calc.CanonicalCondition;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp.Narrow;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp.SignExtend;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.PrimitiveStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.NodeView;

@@ -73,14 +75,37 @@
         }
     }
 
     @Override
     public boolean isLossless() {
+        return checkLossless(this.getResultBits());
+    }
+
+    private boolean checkLossless(int bits) {
+        Stamp valueStamp = this.getValue().stamp(NodeView.DEFAULT);
+        if (bits > 0 && valueStamp instanceof IntegerStamp) {
+            IntegerStamp integerStamp = (IntegerStamp) valueStamp;
+            long valueUpMask = integerStamp.upMask();
+            if ((valueUpMask & CodeUtil.mask(bits)) == valueUpMask) {
+                return true;
+            }
+        }
         return false;
     }
 
     @Override
+    public boolean preservesOrder(CanonicalCondition cond) {
+        switch (cond) {
+            case LT:
+                // Must guarantee that also sign bit does not flip.
+                return checkLossless(this.getResultBits() - 1);
+            default:
+                return checkLossless(this.getResultBits());
+        }
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forValue);
         if (ret != this) {
             return ret;
< prev index next >