diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java
index 2cdaa424d967533c38b78414ca0ec0bd4deb251b..a16c52363c9303dd5989ea0ef4e50f67daefab72 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java
@@ -21,7 +21,7 @@ import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
-import com.oracle.truffle.r.runtime.ops.BinaryArithmetic;
+import com.oracle.truffle.r.runtime.nmath.RMath;
 
 /**
  * Internal functions for the spline function in the stats package. These are originally called
@@ -393,7 +393,7 @@ public class SplineFunctions {
         if (method == 1 && n > 1) { /* periodic */
             dx = x[nm1] - x[0];
             for (l = 0; l < nu; l++) {
-                v[l] = BinaryArithmetic.fmod(u[l] - x[0], dx);
+                v[l] = RMath.fmod(u[l] - x[0], dx);
                 if (v[l] < 0.0) {
                     v[l] += dx;
                 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java
index 9e7dd3f66dfe6a6934ea999c8f84a41ad78fb4dd..708b1ab7175ac9ec65b11ae534c40b12e53e474d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java
@@ -97,44 +97,46 @@ public abstract class CumMax extends RBuiltinNode {
     @Specialization
     protected RDoubleVector cummax(RAbstractDoubleVector v) {
         double[] cmaxV = new double[v.getLength()];
+        na.enable(v);
         double max = v.getDataAt(0);
         cmaxV[0] = max;
-        na.enable(v);
-        int i;
-        for (i = 1; i < v.getLength(); i++) {
-            if (v.getDataAt(i) > max) {
-                max = v.getDataAt(i);
+        na.check(max);
+        for (int i = 1; i < v.getLength(); i++) {
+            double value = v.getDataAt(i);
+            if (na.check(value)) {
+                Arrays.fill(cmaxV, i, cmaxV.length, RRuntime.DOUBLE_NA);
+                break;
             }
-            if (na.check(v.getDataAt(i))) {
+            if (na.checkNAorNaN(value)) {
+                Arrays.fill(cmaxV, i, cmaxV.length, Double.NaN);
                 break;
             }
+            if (value > max) {
+                max = value;
+            }
             cmaxV[i] = max;
         }
-        if (!na.neverSeenNA()) {
-            Arrays.fill(cmaxV, i, cmaxV.length, RRuntime.DOUBLE_NA);
-        }
         return RDataFactory.createDoubleVector(cmaxV, na.neverSeenNA(), getNamesNode.getNames(v));
     }
 
     @Specialization(contains = "cummaxIntSequence")
     protected RIntVector cummax(RAbstractIntVector v) {
         int[] cmaxV = new int[v.getLength()];
+        na.enable(v);
         int max = v.getDataAt(0);
+        na.check(max);
         cmaxV[0] = max;
-        na.enable(v);
-        int i;
-        for (i = 1; i < v.getLength(); i++) {
-            if (v.getDataAt(i) > max) {
-                max = v.getDataAt(i);
-            }
-            if (na.check(v.getDataAt(i))) {
+        for (int i = 1; i < v.getLength(); i++) {
+            int value = v.getDataAt(i);
+            if (na.check(value)) {
+                Arrays.fill(cmaxV, i, cmaxV.length, RRuntime.INT_NA);
                 break;
             }
+            if (value > max) {
+                max = value;
+            }
             cmaxV[i] = max;
         }
-        if (!na.neverSeenNA()) {
-            Arrays.fill(cmaxV, i, cmaxV.length, RRuntime.INT_NA);
-        }
         return RDataFactory.createIntVector(cmaxV, na.neverSeenNA(), getNamesNode.getNames(v));
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java
index ebfc0003b81405ae6cb6f9b2dd0e7dbc6e6d0245..4a050a9f594aae6ac723cf0697741ed34eb3b6ce 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java
@@ -97,44 +97,46 @@ public abstract class CumMin extends RBuiltinNode {
     @Specialization
     protected RDoubleVector cummin(RAbstractDoubleVector v) {
         double[] cminV = new double[v.getLength()];
+        na.enable(v);
         double min = v.getDataAt(0);
+        na.check(min);
         cminV[0] = min;
-        na.enable(v);
-        int i;
-        for (i = 1; i < v.getLength(); i++) {
-            if (v.getDataAt(i) < min) {
-                min = v.getDataAt(i);
+        for (int i = 1; i < v.getLength(); i++) {
+            double value = v.getDataAt(i);
+            if (na.check(value)) {
+                Arrays.fill(cminV, i, cminV.length, RRuntime.DOUBLE_NA);
+                break;
             }
-            if (na.check(v.getDataAt(i))) {
+            if (na.checkNAorNaN(value)) {
+                Arrays.fill(cminV, i, cminV.length, Double.NaN);
                 break;
             }
+            if (value < min) {
+                min = value;
+            }
             cminV[i] = min;
         }
-        if (!na.neverSeenNA()) {
-            Arrays.fill(cminV, i, cminV.length, RRuntime.DOUBLE_NA);
-        }
         return RDataFactory.createDoubleVector(cminV, na.neverSeenNA(), getNamesNode.getNames(v));
     }
 
     @Specialization(contains = "cumminIntSequence")
     protected RIntVector cummin(RAbstractIntVector v) {
         int[] cminV = new int[v.getLength()];
+        na.enable(v);
         int min = v.getDataAt(0);
+        na.check(min);
         cminV[0] = min;
-        na.enable(v);
-        int i;
-        for (i = 1; i < v.getLength(); i++) {
-            if (v.getDataAt(i) < min) {
-                min = v.getDataAt(i);
-            }
-            if (na.check(v.getDataAt(i))) {
+        for (int i = 1; i < v.getLength(); i++) {
+            int value = v.getDataAt(i);
+            if (na.check(value)) {
+                Arrays.fill(cminV, i, cminV.length, RRuntime.INT_NA);
                 break;
             }
+            if (value < min) {
+                min = value;
+            }
             cminV[i] = min;
         }
-        if (!na.neverSeenNA()) {
-            Arrays.fill(cminV, i, cminV.length, RRuntime.INT_NA);
-        }
         return RDataFactory.createIntVector(cminV, na.neverSeenNA(), getNamesNode.getNames(v));
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java
index 352ea43b6c226ffdf434592d8cd457c9688d622b..20dcf0d352f48b882e8b8647c7df88148d5d2269 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java
@@ -28,11 +28,9 @@ import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RComplexVector;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
-import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.ops.BinaryArithmetic;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
@@ -82,19 +80,19 @@ public abstract class CumProd extends RBuiltinNode {
         double prev = 1;
         int i;
         for (i = 0; i < arg.getLength(); i++) {
-            if (na.check(arg.getDataAt(i))) {
+            double value = arg.getDataAt(i);
+            if (na.check(value)) {
+                Arrays.fill(array, i, array.length, RRuntime.DOUBLE_NA);
                 break;
             }
-            prev = mul.op(prev, arg.getDataAt(i));
-            if (na.check(prev)) {
+            if (na.checkNAorNaN(value)) {
+                Arrays.fill(array, i, array.length, Double.NaN);
                 break;
             }
+            prev = mul.op(prev, value);
             array[i] = prev;
         }
-        if (!na.neverSeenNA()) {
-            Arrays.fill(array, i, array.length, RRuntime.DOUBLE_NA);
-        }
-        return RDataFactory.createDoubleVector(array, !na.neverSeenNA(), getNamesNode.getNames(arg));
+        return RDataFactory.createDoubleVector(array, na.neverSeenNA(), getNamesNode.getNames(arg));
     }
 
     @Specialization
@@ -104,10 +102,11 @@ public abstract class CumProd extends RBuiltinNode {
         RComplex prev = RDataFactory.createComplex(1, 0);
         int i;
         for (i = 0; i < arg.getLength(); i++) {
-            if (na.check(arg.getDataAt(i))) {
+            RComplex value = arg.getDataAt(i);
+            if (na.check(value)) {
                 break;
             }
-            prev = mul.op(prev.getRealPart(), prev.getImaginaryPart(), arg.getDataAt(i).getRealPart(), arg.getDataAt(i).getImaginaryPart());
+            prev = mul.op(prev.getRealPart(), prev.getImaginaryPart(), value.getRealPart(), value.getImaginaryPart());
             if (na.check(prev)) {
                 break;
             }
@@ -117,6 +116,6 @@ public abstract class CumProd extends RBuiltinNode {
         if (!na.neverSeenNA()) {
             Arrays.fill(array, 2 * i, array.length, RRuntime.DOUBLE_NA);
         }
-        return RDataFactory.createComplexVector(array, !na.neverSeenNA(), getNamesNode.getNames(arg));
+        return RDataFactory.createComplexVector(array, na.neverSeenNA(), getNamesNode.getNames(arg));
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java
index d0cbc951399a56dabd528d34af1cbf57a1b7f802..92649d60d5859fa40764a4b7a5322bfe26eb14d4 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java
@@ -103,19 +103,16 @@ public abstract class CumSum extends RBuiltinNode {
         int[] res = new int[arg.getLength()];
         int current = arg.getStart();
         int prev = 0;
-        int i;
         na.enable(true);
-        for (i = 0; i < arg.getLength(); i++) {
+        for (int i = 0; i < arg.getLength(); i++) {
             prev = add.op(prev, current);
             if (na.check(prev)) {
+                Arrays.fill(res, i, res.length, RRuntime.INT_NA);
                 break;
             }
             current += arg.getStride();
             res[i] = prev;
         }
-        if (!na.neverSeenNA()) {
-            Arrays.fill(res, i, res.length, RRuntime.INT_NA);
-        }
         return RDataFactory.createIntVector(res, na.neverSeenNA(), getNamesNode.getNames(arg));
     }
 
@@ -124,17 +121,16 @@ public abstract class CumSum extends RBuiltinNode {
         double[] res = new double[arg.getLength()];
         double prev = 0.0;
         na.enable(true);
-        int i;
-        for (i = 0; i < arg.getLength(); i++) {
-            prev = add.op(prev, arg.getDataAt(i));
-            if (na.check(arg.getDataAt(i))) {
+        for (int i = 0; i < arg.getLength(); i++) {
+            double value = arg.getDataAt(i);
+            // cumsum behaves different than cumprod for NaNs:
+            if (na.checkNAorNaN(value)) {
+                Arrays.fill(res, i, res.length, RRuntime.DOUBLE_NA);
                 break;
             }
+            prev = add.op(prev, value);
             res[i] = prev;
         }
-        if (!na.neverSeenNA()) {
-            Arrays.fill(res, i, res.length, RRuntime.DOUBLE_NA);
-        }
         return RDataFactory.createDoubleVector(res, na.neverSeenNA(), getNamesNode.getNames(arg));
     }
 
@@ -164,19 +160,16 @@ public abstract class CumSum extends RBuiltinNode {
     protected RComplexVector cumsum(RAbstractComplexVector arg) {
         double[] res = new double[arg.getLength() * 2];
         RComplex prev = RDataFactory.createComplex(0.0, 0.0);
-        int i;
         na.enable(true);
-        for (i = 0; i < arg.getLength(); i++) {
+        for (int i = 0; i < arg.getLength(); i++) {
             prev = add.op(prev.getRealPart(), prev.getImaginaryPart(), arg.getDataAt(i).getRealPart(), arg.getDataAt(i).getImaginaryPart());
             if (na.check(arg.getDataAt(i))) {
+                Arrays.fill(res, 2 * i, res.length, RRuntime.DOUBLE_NA);
                 break;
             }
             res[2 * i] = prev.getRealPart();
             res[2 * i + 1] = prev.getImaginaryPart();
         }
-        if (!na.neverSeenNA()) {
-            Arrays.fill(res, 2 * i, res.length, RRuntime.DOUBLE_NA);
-        }
         return RDataFactory.createComplexVector(res, na.neverSeenNA(), getNamesNode.getNames(arg));
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
index 7d3922f68eadb96f02f8a5aca34ad7f73e54bcd5..497b3d09277ed57c7bac6b5e1062a25c30c2a2ac 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
@@ -195,7 +195,7 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
                 }
             }
         }
-        RDoubleVector ret = RDataFactory.createDoubleVector(result, !seenNA);
+        RDoubleVector ret = RDataFactory.createDoubleVector(result, !seenNA, getPreservedDimensions(list), getPreservedNames(list));
         if (preserveAttributes()) {
             ret.copyRegAttributesFrom(list);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
index 506169e0075b79f73b127e549bf332ab67542ab5..28966f1ed7f7e23a34f530cad207887c528ec2fd 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
@@ -203,7 +203,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
                 }
             }
         }
-        RIntVector ret = RDataFactory.createIntVector(result, !seenNA);
+        RIntVector ret = RDataFactory.createIntVector(result, !seenNA, getPreservedDimensions(list), getPreservedNames(list));
         if (preserveAttributes()) {
             ret.copyRegAttributesFrom(list);
         }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
index 4dc0d3ea79964500f619c71890b9937cea168c9b..f0a8433fdbc67f01c81da9b60ed8dcf87b58853a 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
@@ -635,8 +635,8 @@ public final class RError extends RuntimeException {
         RNG_NOT_IMPL_KIND("unimplemented RNG kind %d"),
         RNG_READ_SEEDS("cannot read seeds unless 'user_unif_nseed' is supplied"),
         RNG_SYMBOL("%s not found in user rng library"),
-        CUMMAX_UNDEFINED_FOR_COMPLEX("'cummin' not defined for complex numbers"),
-        CUMMIN_UNDEFINED_FOR_COMPLEX("'cummax' not defined for complex numbers"),
+        CUMMAX_UNDEFINED_FOR_COMPLEX("'cummax' not defined for complex numbers"),
+        CUMMIN_UNDEFINED_FOR_COMPLEX("'cummin' not defined for complex numbers"),
         NMAX_LESS_THAN_ONE("'nmax' must be positive"),
         CHAR_VEC_ARGUMENT("a character vector argument expected"),
         QUOTE_G_ONE("only the first character of 'quote' will be used"),
@@ -780,7 +780,8 @@ public final class RError extends RuntimeException {
         TOO_MANY_ARGS("too many arguments"),
         ARG_MUST_BE_CHARACTER("argument '%s' must be character"),
         INCORRECT_NOF_ARGS("Incorrect number of arguments (%d), expecting %d for '%s'"),
-        MACRO_CAN_BE_APPLIED_TO("%s can only be applied to a '%s', not a '%s'");
+        MACRO_CAN_BE_APPLIED_TO("%s can only be applied to a '%s', not a '%s'"),
+        LOSS_OF_ACCURACY_MOD("probable complete loss of accuracy in modulus");
 
         public final String message;
         final boolean hasArgs;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/GammaFunctions.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/GammaFunctions.java
index 16916dcb88c5ebf8ef2b35918ce9eb1a0ba1c4b2..38a90070f967b34cf55c8ebb326ffa52cd895289 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/GammaFunctions.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/GammaFunctions.java
@@ -41,7 +41,6 @@ import com.oracle.truffle.r.runtime.nmath.distr.DNorm;
 import com.oracle.truffle.r.runtime.nmath.distr.DPois;
 import com.oracle.truffle.r.runtime.nmath.distr.Pnorm;
 import com.oracle.truffle.r.runtime.nmath.distr.Qnorm;
-import com.oracle.truffle.r.runtime.ops.BinaryArithmetic;
 
 /**
  * Java implementation of the qgamma and related functions. The logic was derived from GNU R (see
@@ -270,7 +269,7 @@ public abstract class GammaFunctions {
             return x;
         }
 
-        if (x < 0 && BinaryArithmetic.fmod(Math.floor(-x), 2.) == 0) {
+        if (x < 0 && RMath.fmod(Math.floor(-x), 2.) == 0) {
             if (sgn[0] != 0) {
                 sgn[0] = 1;
             }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMath.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMath.java
index 2bf3e10c46b4c3a16f7876bb1ad89a3fcc850d8a..81b7431c9f99b82c0006d6af8d9c629416124903 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMath.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMath.java
@@ -16,7 +16,10 @@ import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN;
 import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN_SQRT_2PI;
 import static com.oracle.truffle.r.runtime.nmath.TOMS708.fabs;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.nmath.RMathError.MLError;
 
@@ -62,18 +65,17 @@ public final class RMath {
         return ((y >= 0) ? fabs(x) : -fabs(x));
     }
 
-    private static double fmod(double a, double b) {
-        double q = a / b;
-        if (b != 0) {
-            double tmp = a - Math.floor(q) * b;
-            if (RRuntime.isFinite(q) && Math.abs(q) > 1 / RRuntime.EPSILON) {
-                // TODO support warning here
-                throw new UnsupportedOperationException();
-            }
-            return tmp - Math.floor(tmp / b) * b;
-        } else {
+    public static double fmod(double a, double b) {
+        if (b == 0) {
             return Double.NaN;
         }
+        double q = a / b;
+        if (RRuntime.isFinite(q) && Math.abs(q) > 1 / RRuntime.EPSILON) {
+            CompilerDirectives.transferToInterpreter();
+            RError.warning(RError.SHOW_CALLER, Message.LOSS_OF_ACCURACY_MOD);
+        }
+        double tmp = a - Math.floor(q) * b;
+        return tmp - Math.floor(tmp / b) * b;
     }
 
     public static double tanpi(double x) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java
index 61f4d37db613eaea17888de632841a8ede12bb57..5f020f50ee708aa8060364812124c3eb4bf4c6ba 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java
@@ -33,6 +33,7 @@ import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.nmath.RMath;
 
 /*
  * Logic derived from GNU-R, Purdue FastR and gcc.
@@ -109,22 +110,6 @@ public abstract class BinaryArithmetic extends Operation {
 
     public abstract String op(String left, String right);
 
-    public static double fmod(double a, double b) {
-        // TODO: this is duplicated in RMath, once RMath is moved to runtime, this should be
-        // replaced
-        double q = a / b;
-        if (b != 0) {
-            double tmp = a - Math.floor(q) * b;
-            if (RRuntime.isFinite(q) && Math.abs(q) > 1 / RRuntime.EPSILON) {
-                // TODO support warning here
-                throw new UnsupportedOperationException();
-            }
-            return tmp - Math.floor(tmp / b) * b;
-        } else {
-            return Double.NaN;
-        }
-    }
-
     private static double convertInf(double d) {
         // This code is transcribed from Purdue FastR.
         return Math.copySign(Double.isInfinite(d) ? 1 : 0, d);
@@ -459,6 +444,12 @@ public abstract class BinaryArithmetic extends Operation {
 
     public static final class Mod extends BinaryArithmetic {
 
+        @CompilationFinal private boolean tryInt = true;
+        private final BranchProfile isNaProfile = BranchProfile.create();
+        private final BranchProfile isZeroProfile = BranchProfile.create();
+        private final ConditionProfile resultZeroProfile = ConditionProfile.createBinaryProfile();
+        private final ConditionProfile simpleProfile = ConditionProfile.createBinaryProfile();
+
         public Mod() {
             super(false, false, true);
         }
@@ -476,20 +467,42 @@ public abstract class BinaryArithmetic extends Operation {
         @Override
         public int op(int left, int right) {
             // LICENSE: transcribed code from GNU R, which is licensed under GPL
-            if (right != 0) {
-                if (left >= 0 && right > 0) {
-                    return left % right;
-                } else {
-                    return (int) fmod(left, right);
-                }
-            } else {
+            if (right == 0) {
+                isNaProfile.enter();
                 return RRuntime.INT_NA;
             }
+            if (left == 0) {
+                isZeroProfile.enter();
+                return 0;
+            }
+            int result = left % right;
+            if (resultZeroProfile.profile(result == 0)) {
+                return 0;
+            }
+            if (simpleProfile.profile((right > 0) == (result > 0))) {
+                return result;
+            } else {
+                // in R, the result always has the same sign as the divisor
+                return result + right;
+            }
         }
 
         @Override
         public double op(double left, double right) {
-            return fmod(left, right);
+            if (right == 0) {
+                isNaProfile.enter();
+                return Double.NaN;
+            }
+            if (tryInt) {
+                int leftInt = (int) left;
+                int rightInt = (int) right;
+                if (left == leftInt && right == rightInt) {
+                    return op(leftInt, rightInt);
+                }
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                tryInt = false;
+            }
+            return RMath.fmod(left, right);
         }
 
         @Override
@@ -919,7 +932,7 @@ public abstract class BinaryArithmetic extends Operation {
                     if (b < 0) {
                         return 0;
                     }
-                    return fmod(b, 2) != 0 ? a : -a;
+                    return RMath.fmod(b, 2) != 0 ? a : -a;
                 }
             }
             if (infiniteB.profile(!isFinite(b))) {
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index fd0bc58414949badf9651378c51a4a05d354ca46..5a78a24238a49b9cb83bcb8db332d22c0c54a8c2 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -14981,12 +14981,12 @@ Error in cospi(argv[[1]]) : unimplemented complex function
 Warning message:
 In cospi(argv[[1]]) : NaNs produced
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call#Ignored.ImplementationError#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call#
 #.Call(utils:::C_crc64)
 Error in .Call(utils:::C_crc64) :
   Incorrect number of arguments (0), expecting 1 for 'crc64'
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call#Ignored.ImplementationError#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call#
 #.Call(utils:::C_crc64, 'a', 'b')
 Error in .Call(utils:::C_crc64, "a", "b") :
   Incorrect number of arguments (2), expecting 1 for 'crc64'
@@ -15059,7 +15059,7 @@ Error: input must be a character string
 #.Internal(crc64('a'))
 [1] "330284772e652b05"
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal#Ignored.ImplementationError#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal#
 #.Internal(crc64('a', 'b'))
 Error: 2 arguments passed to .Internal(crc64) which requires 1
 
@@ -15231,6 +15231,16 @@ Error: could not find function "crc64"
 [2,] 6.208008e+00 -25013.757
 [3,] 1.665335e-16   8362.723
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testCumulativeMax#
+#values <- c(1,2,NA,1, NaN); cummax(values); cummax(as.integer(values))
+[1]  1  2 NA NA NA
+[1]  1  2 NA NA NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testCumulativeMax#
+#values <- c(1,2,NaN,1, NA); cummax(values); cummax(as.integer(values))
+[1]   1   2 NaN NaN NaN
+[1]  1  2 NA NA NA
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testCumulativeMax#
 #{ cummax(1:10) }
  [1]  1  2  3  4  5  6  7  8  9 10
@@ -15243,12 +15253,12 @@ Error: could not find function "crc64"
 #{ cummax(as.logical(-2:2)) }
 [1] 1 1 1 1 1
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testCumulativeMax#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testCumulativeMax#
 #{ cummax(c(1+1i, NA, 2+3i)) }
 Error in cummax(c(1 + (0+1i), NA, 2 + (0+3i))) :
   'cummax' not defined for complex numbers
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testCumulativeMax#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testCumulativeMax#
 #{ cummax(c(1+1i,2-3i,4+5i)) }
 Error in cummax(c(1 + (0+1i), 2 - (0+3i), 4 + (0+5i))) :
   'cummax' not defined for complex numbers
@@ -15286,7 +15296,7 @@ Error in cummax(c(1 + (0+1i), 2 - (0+3i), 4 + (0+5i))) :
 [41] 1.322857e+01 1.322857e+01 1.322857e+01 1.322857e+01 1.322857e+01
 [46] 1.322857e+01 1.322857e+01 1.322857e+01 1.322857e+01 1.322857e+01
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testcummax3#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testcummax3#
 #argv <- list(list());cummax(argv[[1]]);
 numeric(0)
 
@@ -15294,7 +15304,7 @@ numeric(0)
 #argv <- list(FALSE);cummax(argv[[1]]);
 [1] 0
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testcummax5#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testcummax5#
 #argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cummax(argv[[1]]);
 c0
 NA
@@ -15303,14 +15313,24 @@ NA
 #argv <- list(NULL);cummax(argv[[1]]);
 numeric(0)
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testcummax7#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testcummax7#
 #argv <- list(character(0));cummax(argv[[1]]);
 numeric(0)
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testcummax8#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummax.testcummax8#
 #argv <- list(structure(numeric(0), .Dim = c(0L, 0L)));cummax(argv[[1]]);
 numeric(0)
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testCumulativeMin#
+#values <- c(1,2,NA,1, NaN); cummin(values); cummin(as.integer(values))
+[1]  1  1 NA NA NA
+[1]  1  1 NA NA NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testCumulativeMin#
+#values <- c(1,2,NaN,1, NA); cummin(values); cummin(as.integer(values))
+[1]   1   1 NaN NaN NaN
+[1]  1  1 NA NA NA
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testCumulativeMin#
 #{ cummin(1:10) }
  [1] 1 1 1 1 1 1 1 1 1 1
@@ -15323,12 +15343,12 @@ numeric(0)
 #{ cummin(as.logical(-2:2)) }
 [1] 1 1 0 0 0
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testCumulativeMin#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testCumulativeMin#
 #{ cummin(c(1+1i, NA, 2+3i)) }
 Error in cummin(c(1 + (0+1i), NA, 2 + (0+3i))) :
   'cummin' not defined for complex numbers
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testCumulativeMin#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testCumulativeMin#
 #{ cummin(c(1+1i,2-3i,4+5i)) }
 Error in cummin(c(1 + (0+1i), 2 - (0+3i), 4 + (0+5i))) :
   'cummin' not defined for complex numbers
@@ -15353,7 +15373,7 @@ Error in cummin(c(1 + (0+1i), 2 - (0+3i), 4 + (0+5i))) :
 #argv <- list(c(3L, 2L, 1L, 2L, 1L, 0L, 4L, 3L, 2L));cummin(argv[[1]]);
 [1] 3 2 1 1 1 0 0 0 0
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testcummin2#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testcummin2#
 #argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cummin(argv[[1]]);
 c0
 NA
@@ -15371,15 +15391,15 @@ NA
 [41] 9.411020e-04 9.092489e-04 9.092489e-04 9.092489e-04 9.092489e-04
 [46] 4.122947e-04 4.122947e-04 1.129946e-05
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testcummin4#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testcummin4#
 #argv <- list(structure(numeric(0), .Dim = c(0L, 0L)));cummin(argv[[1]]);
 numeric(0)
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testcummin5#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testcummin5#
 #argv <- list(logical(0));cummin(argv[[1]]);
 integer(0)
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testcummin6#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cummin.testcummin6#
 #argv <- list(character(0));cummin(argv[[1]]);
 numeric(0)
 
@@ -15391,6 +15411,16 @@ numeric(0)
 #argv <- list(FALSE);cummin(argv[[1]]);
 [1] 0
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cumprod.testCumProd#
+#values <- c(1,2,NA,1, NaN); cumprod(values); cumprod(as.integer(values))
+[1]  1  2 NA NA NA
+[1]  1  2 NA NA NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cumprod.testCumProd#
+#values <- c(1,2,NaN,1, NA); cumprod(values); cumprod(as.integer(values))
+[1]   1   2 NaN NaN NaN
+[1]  1  2 NA NA NA
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_cumprod.testcumprod1#
 #argv <- list(structure(c(1, 60, 60, 24, 7), .Names = c('secs', 'mins', 'hours', 'days', 'weeks')));cumprod(argv[[1]]);
   secs   mins  hours   days  weeks
@@ -15431,7 +15461,7 @@ numeric(0)
 l0
  0
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cumprod.testcumprod5#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cumprod.testcumprod5#
 #argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cumprod(argv[[1]]);
 c0
 NA
@@ -15440,7 +15470,7 @@ NA
 #argv <- list(structure(numeric(0), .Dim = c(0L, 0L)));cumprod(argv[[1]]);
 numeric(0)
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cumprod.testcumprod7#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cumprod.testcumprod7#
 #argv <- list(structure(list(), .Names = character(0)));cumprod(argv[[1]]);
 named numeric(0)
 
@@ -15452,6 +15482,16 @@ numeric(0)
 #argv <- list(character(0));cumprod(argv[[1]]);
 numeric(0)
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cumsum.testCumulativeSum#
+#values <- c(1,2,NA,1, NaN); cumsum(values); cumsum(as.integer(values))
+[1]  1  3 NA NA NA
+[1]  1  3 NA NA NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cumsum.testCumulativeSum#
+#values <- c(1,2,NaN,1, NA); cumsum(values); cumsum(as.integer(values))
+[1]  1  3 NA NA NA
+[1]  1  3 NA NA NA
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_cumsum.testCumulativeSum#
 #{ cumsum((1:6)*(1+1i)) }
 [1]  1+ 1i  3+ 3i  6+ 6i 10+10i 15+15i 21+21i
@@ -15494,7 +15534,7 @@ integer overflow in 'cumsum'; use 'cumsum(as.numeric(.))'
 #{ cumsum(c(1,2,3)) }
 [1] 1 3 6
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cumsum.testCumulativeSum#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cumsum.testCumulativeSum#
 #{ cumsum(c(1,2,3,0/0,5)) }
 [1]  1  3  6 NA NA
 
@@ -15615,7 +15655,7 @@ numeric(0)
    52    53    54    55
  9964  9974  9981 10000
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cumsum.testcumsum7#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cumsum.testcumsum7#
 #argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cumsum(argv[[1]]);
 c0
 NA
@@ -38683,7 +38723,7 @@ FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 #{ options(continue="abc"); identical(getOption("continue"), "abc") }
 [1] TRUE
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_options.testContinue#Ignored.WrongCaller#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_options.testContinue#
 #{ options(continue=NULL) }
 Error in options(continue = NULL) : invalid value for 'continue'
 
@@ -38691,7 +38731,7 @@ Error in options(continue = NULL) : invalid value for 'continue'
 #{ f<-function(){}; options(editor=f); identical(getOption("editor"), f) }
 [1] TRUE
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_options.testEditor#Ignored.WrongCaller#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_options.testEditor#
 #{ options(editor="") }
 Error in options(editor = "") : invalid value for 'editor'
 
@@ -38724,7 +38764,7 @@ $width
 #{ options(prompt="abc"); identical(getOption("prompt"), "abc") }
 [1] TRUE
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_options.testPrompt#Ignored.WrongCaller#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_options.testPrompt#
 #{ options(prompt=NULL) }
 Error in options(prompt = NULL) : invalid value for 'prompt'
 
@@ -60878,7 +60918,7 @@ In strsplit("abc", ".", fixed = TRUE, perl = TRUE) :
 [1] "exNSS4"
 
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.teststrsplit10#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.teststrsplit10#
 #argv <- list('A shell of class documentation has been written to the file \'./myTst2/man/DocLink-class.Rd\'.\n', '[ \t\n]', FALSE, TRUE, TRUE); .Internal(strsplit(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]]))
 [[1]]
  [1] "A"                                "shell"
@@ -62907,7 +62947,7 @@ In sum(argv[[1]], argv[[2]]) : Integer overflow - use sum(as.numeric(.))
 #argv <- list(structure(c(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), .Tsp = c(1, 101, 1), class = 'ts'));sum(argv[[1]]);
 [1] 1
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_sum.testsum18#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_sum.testsum18#
 #argv <- list(c(1073741824L, 1073741824L));sum(argv[[1]]);
 [1] NA
 Warning message:
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cummax.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cummax.java
index 43352fd855913cabdbe011d89dfc3529576be380..79f0191cc5ed936e7602b81288318bbc4c49e21d 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cummax.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cummax.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2012-2014, Purdue University
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -29,7 +29,7 @@ public class TestBuiltin_cummax extends TestBase {
 
     @Test
     public void testcummax3() {
-        assertEval(Ignored.Unknown, "argv <- list(list());cummax(argv[[1]]);");
+        assertEval("argv <- list(list());cummax(argv[[1]]);");
     }
 
     @Test
@@ -39,8 +39,7 @@ public class TestBuiltin_cummax extends TestBase {
 
     @Test
     public void testcummax5() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cummax(argv[[1]]);");
+        assertEval("argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cummax(argv[[1]]);");
     }
 
     @Test
@@ -50,12 +49,12 @@ public class TestBuiltin_cummax extends TestBase {
 
     @Test
     public void testcummax7() {
-        assertEval(Ignored.Unknown, "argv <- list(character(0));cummax(argv[[1]]);");
+        assertEval("argv <- list(character(0));cummax(argv[[1]]);");
     }
 
     @Test
     public void testcummax8() {
-        assertEval(Ignored.Unknown, "argv <- list(structure(numeric(0), .Dim = c(0L, 0L)));cummax(argv[[1]]);");
+        assertEval("argv <- list(structure(numeric(0), .Dim = c(0L, 0L)));cummax(argv[[1]]);");
     }
 
     @Test
@@ -68,7 +67,10 @@ public class TestBuiltin_cummax extends TestBase {
         assertEval("{ cummax(c(TRUE,FALSE,NA,TRUE)) }");
         assertEval("{ cummax(as.logical(-2:2)) }");
 
-        assertEval(Ignored.Unknown, "{ cummax(c(1+1i,2-3i,4+5i)) }");
-        assertEval(Ignored.Unknown, "{ cummax(c(1+1i, NA, 2+3i)) }");
+        assertEval("{ cummax(c(1+1i,2-3i,4+5i)) }");
+        assertEval("{ cummax(c(1+1i, NA, 2+3i)) }");
+
+        assertEval("values <- c(1,2,NaN,1, NA); cummax(values); cummax(as.integer(values))");
+        assertEval("values <- c(1,2,NA,1, NaN); cummax(values); cummax(as.integer(values))");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cummin.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cummin.java
index 247a4b6c9a2a773291727a47eadee3c6dc663b1b..d6a462e391d8f69bda7a900a845598efbec4a165 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cummin.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cummin.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2012-2014, Purdue University
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -24,8 +24,7 @@ public class TestBuiltin_cummin extends TestBase {
 
     @Test
     public void testcummin2() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cummin(argv[[1]]);");
+        assertEval("argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cummin(argv[[1]]);");
     }
 
     @Test
@@ -35,17 +34,17 @@ public class TestBuiltin_cummin extends TestBase {
 
     @Test
     public void testcummin4() {
-        assertEval(Ignored.Unknown, "argv <- list(structure(numeric(0), .Dim = c(0L, 0L)));cummin(argv[[1]]);");
+        assertEval("argv <- list(structure(numeric(0), .Dim = c(0L, 0L)));cummin(argv[[1]]);");
     }
 
     @Test
     public void testcummin5() {
-        assertEval(Ignored.Unknown, "argv <- list(logical(0));cummin(argv[[1]]);");
+        assertEval("argv <- list(logical(0));cummin(argv[[1]]);");
     }
 
     @Test
     public void testcummin6() {
-        assertEval(Ignored.Unknown, "argv <- list(character(0));cummin(argv[[1]]);");
+        assertEval("argv <- list(character(0));cummin(argv[[1]]);");
     }
 
     @Test
@@ -67,9 +66,10 @@ public class TestBuiltin_cummin extends TestBase {
         assertEval("{ cummin(c(TRUE,FALSE,TRUE)) }");
         assertEval("{ cummin(c(TRUE,FALSE,NA,TRUE)) }");
         assertEval("{ cummin(as.logical(-2:2)) }");
+        assertEval("{ cummin(c(1+1i,2-3i,4+5i)) }");
+        assertEval("{ cummin(c(1+1i, NA, 2+3i)) }");
 
-        // Error message mismatch.
-        assertEval(Ignored.Unknown, "{ cummin(c(1+1i,2-3i,4+5i)) }");
-        assertEval(Ignored.Unknown, "{ cummin(c(1+1i, NA, 2+3i)) }");
+        assertEval("values <- c(1,2,NaN,1, NA); cummin(values); cummin(as.integer(values))");
+        assertEval("values <- c(1,2,NA,1, NaN); cummin(values); cummin(as.integer(values))");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cumprod.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cumprod.java
index 033eb601b4781e29fe58f2a2741846d6c8d1f077..4a3dd190b5ae4ade5904660e8cecd9f983a90816 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cumprod.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cumprod.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -39,8 +39,7 @@ public class TestBuiltin_cumprod extends TestBase {
 
     @Test
     public void testcumprod5() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cumprod(argv[[1]]);");
+        assertEval("argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cumprod(argv[[1]]);");
     }
 
     @Test
@@ -50,7 +49,7 @@ public class TestBuiltin_cumprod extends TestBase {
 
     @Test
     public void testcumprod7() {
-        assertEval(Ignored.Unknown, "argv <- list(structure(list(), .Names = character(0)));cumprod(argv[[1]]);");
+        assertEval("argv <- list(structure(list(), .Names = character(0)));cumprod(argv[[1]]);");
     }
 
     @Test
@@ -67,4 +66,10 @@ public class TestBuiltin_cumprod extends TestBase {
     public void testcumprod10() {
         assertEval("argv <- list(c(0.982149602642989, 0.91866776738084, 0.859369083800704, 0.921182928974104));cumprod(argv[[1]]);");
     }
+
+    @Test
+    public void testCumProd() {
+        assertEval("values <- c(1,2,NaN,1, NA); cumprod(values); cumprod(as.integer(values))");
+        assertEval("values <- c(1,2,NA,1, NaN); cumprod(values); cumprod(as.integer(values))");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cumsum.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cumsum.java
index b0a4a9fa33352790bad83148684027ac44dcc723..92b68c48857b5db42a25b7fb000acdfd0226a46b 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cumsum.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cumsum.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2012-2014, Purdue University
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -49,8 +49,7 @@ public class TestBuiltin_cumsum extends TestBase {
 
     @Test
     public void testcumsum7() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cumsum(argv[[1]]);");
+        assertEval("argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = structure('integer(0)', .Names = 'c0')));cumsum(argv[[1]]);");
     }
 
     @Test
@@ -106,7 +105,7 @@ public class TestBuiltin_cumsum extends TestBase {
         assertEval("{ cumsum(as.logical(-2:2)) }");
         assertEval("{ cumsum((1:6)*(1+1i)) }");
 
-        assertEval(Ignored.Unknown, "{ cumsum(c(1,2,3,0/0,5)) }");
+        assertEval("{ cumsum(c(1,2,3,0/0,5)) }");
         assertEval("{ cumsum(c(1,0/0,5+1i)) }");
         assertEval("{ cumsum(as.raw(1:6)) }");
         assertEval("{ cumsum(rep(1e308, 3) ) }");
@@ -115,5 +114,8 @@ public class TestBuiltin_cumsum extends TestBase {
         assertEval(Ignored.Unknown, "{ cumsum(c(2000000000L, 2000000000L)) }");
         // FIXME missing warning
         assertEval(Ignored.Unknown, "{ cumsum(c(-2147483647L, -1L)) }");
+
+        assertEval("values <- c(1,2,NaN,1, NA); cumsum(values); cumsum(as.integer(values))");
+        assertEval("values <- c(1,2,NA,1, NaN); cumsum(values); cumsum(as.integer(values))");
     }
 }