From bdc04c6efe0a02f47f5dabfcc8ffe7b93743694b Mon Sep 17 00:00:00 2001
From: Adam Welc <adam.welc@oracle.com>
Date: Thu, 2 Oct 2014 11:54:37 -0700
Subject: [PATCH] Removed slow-pathed code, added branch profiles, and fixed
 additionale problems in the implementations of UnaryArithmeticReduceNode and
 of PMinMax.

---
 .../truffle/r/nodes/builtin/base/PMinMax.java | 220 ++++++++++++------
 .../unary/UnaryArithmeticReduceNode.java      | 172 +++++++++-----
 .../truffle/r/test/ExpectedTestOutput.test    | 115 +++++++++
 .../truffle/r/test/failing/FailingTests.java  | 105 ---------
 .../r/test/testrgen/TestrGenBuiltinpmax.java  |  16 +-
 .../r/test/testrgen/TestrGenBuiltinpmin.java  |  13 +-
 6 files changed, 385 insertions(+), 256 deletions(-)

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMinMax.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMinMax.java
index fa35843bb2..d3dbb5f203 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMinMax.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMinMax.java
@@ -25,7 +25,6 @@ package com.oracle.truffle.r.nodes.builtin.base;
 import static com.oracle.truffle.r.runtime.RBuiltinKind.*;
 
 import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.*;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.utilities.*;
@@ -39,33 +38,44 @@ import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
 import com.oracle.truffle.r.runtime.ops.*;
 import com.oracle.truffle.r.runtime.ops.na.*;
+import com.oracle.truffle.r.nodes.builtin.base.PMinMaxFactory.MultiElemStringHandlerFactory;
 
 public abstract class PMinMax extends RBuiltinNode {
 
+    @Child private MultiElemStringHandler stringHandler;
     @Child private CastToVectorNode castVector;
     @Child private CastIntegerNode castInteger;
     @Child private CastDoubleNode castDouble;
     @Child private CastStringNode castString;
     @Child private PrecedenceNode precedenceNode = PrecedenceNodeFactory.create(null, null);
     private final ReduceSemantics semantics;
+    private final BinaryArithmeticFactory factory;
+    @Child private BinaryArithmetic op;
     private final NACheck na = NACheck.create();
     final ConditionProfile lengthProfile = ConditionProfile.createBinaryProfile();
+    final ConditionProfile naRmProfile = ConditionProfile.createBinaryProfile();
 
     @Override
     public RNode[] getParameterValues() {
         return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance)};
     }
 
-    private final BinaryArithmetic op;
-
-    public PMinMax(BinaryArithmetic op, ReduceSemantics semantics) {
-        this.op = op;
+    public PMinMax(ReduceSemantics semantics, BinaryArithmeticFactory factory) {
         this.semantics = semantics;
+        this.factory = factory;
+        this.op = factory.create();
     }
 
     public PMinMax(PMinMax other) {
-        this.op = other.op;
-        this.semantics = other.semantics;
+        this(other.semantics, other.factory);
+    }
+
+    private byte handleString(VirtualFrame frame, Object[] argValues, byte naRm, int offset, int ind, int maxLength, byte warning, Object data) {
+        if (stringHandler == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            stringHandler = insert(MultiElemStringHandlerFactory.create(semantics, factory, na, null, null, null, null, null, null, null));
+        }
+        return stringHandler.executeByte(frame, argValues, naRm, offset, ind, maxLength, warning, data);
     }
 
     private RAbstractVector castVector(VirtualFrame frame, Object value) {
@@ -117,12 +127,18 @@ public abstract class PMinMax extends RBuiltinNode {
         return length;
     }
 
-    @Specialization(guards = "isIntegerPrecedence")
+    @Specialization(guards = {"isIntegerPrecedence", "oneVector"})
+    protected Object pMinMaxOneVecInt(@SuppressWarnings("unused") byte naRm, RArgsValuesAndNames args) {
+        return args.getValues()[0];
+    }
+
+    @Specialization(guards = {"isIntegerPrecedence", "!oneVector"})
     protected RIntVector pMinMaxInt(VirtualFrame frame, byte naRm, RArgsValuesAndNames args) {
         int maxLength = convertToVectorAndEnableNACheck(frame, args, getIntegerCastNode());
         if (lengthProfile.profile(maxLength == 0)) {
             return RDataFactory.createEmptyIntVector();
         } else {
+            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
             int[] data = new int[maxLength];
             Object[] argValues = args.getValues();
             boolean warningAdded = false;
@@ -130,13 +146,13 @@ public abstract class PMinMax extends RBuiltinNode {
                 int result = semantics.getIntStart();
                 for (int j = 0; j < argValues.length; j++) {
                     RAbstractIntVector vec = (RAbstractIntVector) argValues[j];
-                    if (vec.getLength() < maxLength && !warningAdded) {
+                    if (vec.getLength() > 1 && vec.getLength() < maxLength && !warningAdded) {
                         RError.warning(RError.Message.ARG_RECYCYLED);
                         warningAdded = true;
                     }
                     int v = vec.getDataAt(i % vec.getLength());
                     if (na.check(v)) {
-                        if (naRm == RRuntime.LOGICAL_TRUE) {
+                        if (profiledNaRm) {
                             continue;
                         } else {
                             result = RRuntime.INT_NA;
@@ -148,21 +164,32 @@ public abstract class PMinMax extends RBuiltinNode {
                 }
                 data[i] = result;
             }
-            return RDataFactory.createIntVector(data, na.neverSeenNA() || naRm == RRuntime.LOGICAL_TRUE);
+            return RDataFactory.createIntVector(data, na.neverSeenNA() || profiledNaRm);
         }
     }
 
-    @Specialization(guards = "isLogicalPrecedence")
+    @Specialization(guards = {"isLogicalPrecedence", "oneVector"})
+    protected Object pMinMaxOneVecLogical(@SuppressWarnings("unused") byte naRm, RArgsValuesAndNames args) {
+        return args.getValues()[0];
+    }
+
+    @Specialization(guards = {"isLogicalPrecedence", "!oneVector"})
     protected RIntVector pMinMaxLogical(VirtualFrame frame, byte naRm, RArgsValuesAndNames args) {
         return pMinMaxInt(frame, naRm, args);
     }
 
-    @Specialization(guards = "isDoublePrecedence")
+    @Specialization(guards = {"isDoublePrecedence", "oneVector"})
+    protected Object pMinMaxOneVecDouble(@SuppressWarnings("unused") byte naRm, RArgsValuesAndNames args) {
+        return args.getValues()[0];
+    }
+
+    @Specialization(guards = {"isDoublePrecedence", "!oneVector"})
     protected RDoubleVector pMinMaxDouble(VirtualFrame frame, byte naRm, RArgsValuesAndNames args) {
         int maxLength = convertToVectorAndEnableNACheck(frame, args, getDoubleCastNode());
         if (lengthProfile.profile(maxLength == 0)) {
             return RDataFactory.createEmptyDoubleVector();
         } else {
+            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
             double[] data = new double[maxLength];
             Object[] argValues = args.getValues();
             boolean warningAdded = false;
@@ -170,13 +197,13 @@ public abstract class PMinMax extends RBuiltinNode {
                 double result = semantics.getDoubleStart();
                 for (int j = 0; j < argValues.length; j++) {
                     RAbstractDoubleVector vec = (RAbstractDoubleVector) argValues[j];
-                    if (vec.getLength() < maxLength && !warningAdded) {
+                    if (vec.getLength() > 1 && vec.getLength() < maxLength && !warningAdded) {
                         RError.warning(RError.Message.ARG_RECYCYLED);
                         warningAdded = true;
                     }
                     double v = vec.getDataAt(i % vec.getLength());
                     if (na.check(v)) {
-                        if (naRm == RRuntime.LOGICAL_TRUE) {
+                        if (profiledNaRm) {
                             continue;
                         } else {
                             result = RRuntime.DOUBLE_NA;
@@ -188,77 +215,29 @@ public abstract class PMinMax extends RBuiltinNode {
                 }
                 data[i] = result;
             }
-            return RDataFactory.createDoubleVector(data, na.neverSeenNA() || naRm == RRuntime.LOGICAL_TRUE);
+            return RDataFactory.createDoubleVector(data, na.neverSeenNA() || profiledNaRm);
         }
     }
 
-    @SlowPath
-    private boolean doStringVectorMultiElem(Object[] argValues, byte naRm, int offset, int ind, int maxLength, boolean warning, String[] data) {
-        boolean warningAdded = warning;
-        RAbstractStringVector vec = (RAbstractStringVector) argValues[offset];
-        if (vec.getLength() < maxLength && !warningAdded) {
-            RError.warning(RError.Message.ARG_RECYCYLED);
-            warningAdded = true;
-        }
-        String result = vec.getDataAt(ind % vec.getLength());
-        na.enable(result);
-        if (naRm == RRuntime.LOGICAL_TRUE) {
-            if (na.check(result)) {
-                // the following is meant to eliminate leading NA-s
-                if (offset == argValues.length - 1) {
-                    // last element - all other are NAs
-                    data[ind] = semantics.getStringStart();
-                } else {
-                    return doStringVectorMultiElem(argValues, naRm, offset + 1, ind, maxLength, warningAdded, data);
-                }
-                return warningAdded;
-            }
-        } else {
-            if (na.check(result)) {
-                data[ind] = result;
-                return warningAdded;
-            }
-        }
-        // when we reach here, it means that we have already seen one non-NA element
-        assert !RRuntime.isNA(result);
-        for (int i = offset + 1; i < argValues.length; ++i) {
-            vec = (RAbstractStringVector) argValues[i];
-            if (vec.getLength() < maxLength && !warningAdded) {
-                RError.warning(RError.Message.ARG_RECYCYLED);
-                warningAdded = true;
-            }
-
-            String current = vec.getDataAt(ind % vec.getLength());
-            na.enable(current);
-            if (na.check(current)) {
-                if (naRm == RRuntime.LOGICAL_TRUE) {
-                    // skip NA-s
-                    continue;
-                } else {
-                    data[ind] = RRuntime.STRING_NA;
-                    return warningAdded;
-                }
-            } else {
-                result = op.op(result, current);
-            }
-        }
-        data[ind] = result;
-        return warningAdded;
+    @Specialization(guards = {"isStringPrecedence", "oneVector"})
+    protected Object pMinMaxOneVecString(@SuppressWarnings("unused") byte naRm, RArgsValuesAndNames args) {
+        return args.getValues()[0];
     }
 
-    @Specialization(guards = "isStringPrecedence")
+    @Specialization(guards = {"isStringPrecedence", "!oneVector"})
     protected RStringVector pMinMaxString(VirtualFrame frame, byte naRm, RArgsValuesAndNames args) {
         int maxLength = convertToVectorAndEnableNACheck(frame, args, getStringCastNode());
         if (lengthProfile.profile(maxLength == 0)) {
             return RDataFactory.createEmptyStringVector();
         } else {
+            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
             String[] data = new String[maxLength];
             Object[] argValues = args.getValues();
-            boolean warningAdded = false;
+            byte warningAdded = RRuntime.LOGICAL_FALSE;
             for (int i = 0; i < maxLength; i++) {
-                warningAdded = doStringVectorMultiElem(argValues, naRm, 0, i, maxLength, warningAdded, data);
+                warningAdded = handleString(frame, argValues, naRm, 0, i, maxLength, warningAdded, data);
             }
-            return RDataFactory.createStringVector(data, na.neverSeenNA() || naRm == RRuntime.LOGICAL_TRUE);
+            return RDataFactory.createStringVector(data, na.neverSeenNA() || profiledNaRm);
         }
     }
 
@@ -278,7 +257,7 @@ public abstract class PMinMax extends RBuiltinNode {
     public abstract static class PMax extends PMinMax {
 
         public PMax() {
-            super(BinaryArithmetic.MAX.create(), new ReduceSemantics(RRuntime.INT_MIN_VALUE, Double.NEGATIVE_INFINITY, false, RError.Message.NO_NONMISSING_MAX, false, true));
+            super(new ReduceSemantics(RRuntime.INT_MIN_VALUE, Double.NEGATIVE_INFINITY, false, RError.Message.NO_NONMISSING_MAX, false, true), BinaryArithmetic.MAX);
         }
 
     }
@@ -287,7 +266,7 @@ public abstract class PMinMax extends RBuiltinNode {
     public abstract static class PMin extends PMinMax {
 
         public PMin() {
-            super(BinaryArithmetic.MIN.create(), new ReduceSemantics(RRuntime.INT_MAX_VALUE, Double.POSITIVE_INFINITY, false, RError.Message.NO_NONMISSING_MIN, false, true));
+            super(new ReduceSemantics(RRuntime.INT_MAX_VALUE, Double.POSITIVE_INFINITY, false, RError.Message.NO_NONMISSING_MIN, false, true), BinaryArithmetic.MIN);
         }
 
     }
@@ -316,6 +295,10 @@ public abstract class PMinMax extends RBuiltinNode {
         return precedence(frame, args) == PrecedenceNode.RAW_PRECEDENCE;
     }
 
+    protected boolean oneVector(@SuppressWarnings("unused") byte naRm, RArgsValuesAndNames args) {
+        return args.length() == 1;
+    }
+
     private int precedence(VirtualFrame frame, RArgsValuesAndNames args) {
         int precedence = -1;
         Object[] array = args.getValues();
@@ -325,4 +308,93 @@ public abstract class PMinMax extends RBuiltinNode {
         return precedence;
     }
 
+    @NodeChildren({@NodeChild("argValues"), @NodeChild("naRm"), @NodeChild("offset"), @NodeChild("ind"), @NodeChild("maxLength"), @NodeChild("warning"), @NodeChild("data")})
+    protected abstract static class MultiElemStringHandler extends RNode {
+
+        public abstract byte executeByte(VirtualFrame frame, Object[] argValues, byte naRm, int offset, int ind, int maxLength, byte warning, Object data);
+
+        @Child private MultiElemStringHandler recursiveStringHandler;
+        private final ReduceSemantics semantics;
+        private final BinaryArithmeticFactory factory;
+        @Child private BinaryArithmetic op;
+        private final NACheck na;
+        final ConditionProfile naRmProfile = ConditionProfile.createBinaryProfile();
+
+        public MultiElemStringHandler(ReduceSemantics semantics, BinaryArithmeticFactory factory, NACheck na) {
+            this.semantics = semantics;
+            this.factory = factory;
+            this.op = factory.create();
+            this.na = na;
+        }
+
+        public MultiElemStringHandler(MultiElemStringHandler other) {
+            this(other.semantics, other.factory, other.na);
+        }
+
+        private byte handleString(VirtualFrame frame, Object[] argValues, byte naRm, int offset, int ind, int maxLength, byte warning, Object data) {
+            if (recursiveStringHandler == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                recursiveStringHandler = insert(MultiElemStringHandlerFactory.create(semantics, factory, na, null, null, null, null, null, null, null));
+            }
+            return recursiveStringHandler.executeByte(frame, argValues, naRm, offset, ind, maxLength, warning, data);
+        }
+
+        @Specialization
+        protected byte doStringVectorMultiElem(VirtualFrame frame, Object[] argValues, byte naRm, int offset, int ind, int maxLength, byte warning, Object d) {
+            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
+            String[] data = (String[]) d;
+            byte warningAdded = warning;
+            RAbstractStringVector vec = (RAbstractStringVector) argValues[offset];
+            if (vec.getLength() > 1 && vec.getLength() < maxLength && warningAdded == RRuntime.LOGICAL_FALSE) {
+                RError.warning(RError.Message.ARG_RECYCYLED);
+                warningAdded = RRuntime.LOGICAL_TRUE;
+            }
+            String result = vec.getDataAt(ind % vec.getLength());
+            na.enable(result);
+            if (profiledNaRm) {
+                if (na.check(result)) {
+                    // the following is meant to eliminate leading NA-s
+                    if (offset == argValues.length - 1) {
+                        // last element - all other are NAs
+                        data[ind] = semantics.getStringStart();
+                    } else {
+                        return handleString(frame, argValues, naRm, offset + 1, ind, maxLength, warningAdded, data);
+                    }
+                    return warningAdded;
+                }
+            } else {
+                if (na.check(result)) {
+                    data[ind] = result;
+                    return warningAdded;
+                }
+            }
+            // when we reach here, it means that we have already seen one non-NA element
+            assert !RRuntime.isNA(result);
+            for (int i = offset + 1; i < argValues.length; ++i) {
+                vec = (RAbstractStringVector) argValues[i];
+                if (vec.getLength() > 1 && vec.getLength() < maxLength && warningAdded == RRuntime.LOGICAL_FALSE) {
+                    RError.warning(RError.Message.ARG_RECYCYLED);
+                    warningAdded = RRuntime.LOGICAL_TRUE;
+                }
+
+                String current = vec.getDataAt(ind % vec.getLength());
+                na.enable(current);
+                if (na.check(current)) {
+                    if (profiledNaRm) {
+                        // skip NA-s
+                        continue;
+                    } else {
+                        data[ind] = RRuntime.STRING_NA;
+                        return warningAdded;
+                    }
+                } else {
+                    result = op.op(result, current);
+                }
+            }
+            data[ind] = result;
+            return warningAdded;
+        }
+
+    }
+
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java
index 816f7b1a58..c750848f8d 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java
@@ -22,9 +22,13 @@
  */
 package com.oracle.truffle.r.nodes.unary;
 
-import com.oracle.truffle.api.CompilerDirectives.SlowPath;
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.source.*;
+import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.nodes.*;
+import com.oracle.truffle.r.nodes.unary.UnaryArithmeticReduceNodeFactory.MultiElemStringHandlerFactory;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.ops.*;
@@ -33,6 +37,8 @@ import com.oracle.truffle.r.runtime.ops.na.*;
 @NodeChild(value = "naRm", type = RNode.class)
 public abstract class UnaryArithmeticReduceNode extends UnaryNode {
 
+    @Child private MultiElemStringHandler stringHandler;
+
     private final BinaryArithmeticFactory factory;
 
     @Child private BinaryArithmetic arithmetic;
@@ -41,6 +47,8 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
 
     private final NACheck na = NACheck.create();
 
+    final ConditionProfile naRmProfile = ConditionProfile.createBinaryProfile();
+
     public UnaryArithmeticReduceNode(ReduceSemantics semantics, BinaryArithmeticFactory factory) {
         this.factory = factory;
         this.semantics = semantics;
@@ -53,6 +61,14 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
         this(op.semantics, op.factory);
     }
 
+    private String handleString(VirtualFrame frame, RStringVector operand, byte naRm, int offset) {
+        if (stringHandler == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            stringHandler = insert(MultiElemStringHandlerFactory.create(semantics, factory, na, null, null, null));
+        }
+        return stringHandler.executeString(frame, operand, naRm, offset);
+    }
+
     protected boolean isNullInt() {
         return semantics.isNullInt();
     }
@@ -77,8 +93,9 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
 
     @Specialization
     protected int doInt(int operand, byte naRm) {
+        boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
         na.enable(operand);
-        if (naRm == RRuntime.LOGICAL_TRUE) {
+        if (profiledNaRm) {
             if (na.check(operand)) {
                 if (semantics.getEmptyWarning() != null) {
                     RError.warning(semantics.emptyWarning);
@@ -94,8 +111,9 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
 
     @Specialization
     protected double doDouble(double operand, byte naRm) {
+        boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
         na.enable(operand);
-        if (naRm == RRuntime.LOGICAL_TRUE) {
+        if (profiledNaRm) {
             if (na.check(operand)) {
                 if (semantics.getEmptyWarning() != null) {
                     RError.warning(semantics.emptyWarning);
@@ -111,8 +129,9 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
 
     @Specialization
     protected int doLogical(byte operand, byte naRm) {
+        boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
         na.enable(operand);
-        if (naRm == RRuntime.LOGICAL_TRUE) {
+        if (profiledNaRm) {
             if (na.check(operand)) {
                 if (semantics.getEmptyWarning() != null) {
                     RError.warning(semantics.emptyWarning);
@@ -129,8 +148,9 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
     @Specialization
     protected RComplex doComplex(RComplex operand, byte naRm) {
         if (semantics.supportComplex) {
+            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
             na.enable(operand);
-            if (naRm == RRuntime.LOGICAL_TRUE) {
+            if (profiledNaRm) {
                 if (na.check(operand)) {
                     if (semantics.getEmptyWarning() != null) {
                         RError.warning(semantics.emptyWarning);
@@ -150,8 +170,9 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
     @Specialization
     protected String doString(String operand, byte naRm) {
         if (semantics.supportString) {
+            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
             na.enable(operand);
-            if (naRm == RRuntime.LOGICAL_TRUE) {
+            if (profiledNaRm) {
                 if (na.check(operand)) {
                     if (semantics.getEmptyWarning() != null) {
                         RError.warning(semantics.emptyWarning);
@@ -176,6 +197,7 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
 
     @Specialization
     protected int doIntVector(RIntVector operand, byte naRm) {
+        boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
         int result = semantics.getIntStart();
         na.enable(operand);
         int opCount = 0;
@@ -183,7 +205,7 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
             int d = operand.getDataAt(i);
             na.enable(d);
             if (na.check(d)) {
-                if (naRm == RRuntime.LOGICAL_TRUE) {
+                if (profiledNaRm) {
                     continue;
                 } else {
                     return RRuntime.INT_NA;
@@ -201,6 +223,7 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
 
     @Specialization
     protected double doDoubleVector(RDoubleVector operand, byte naRm) {
+        boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
         double result = semantics.getDoubleStart();
         na.enable(operand);
         int opCount = 0;
@@ -208,7 +231,7 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
             double d = operand.getDataAt(i);
             na.enable(d);
             if (na.check(d)) {
-                if (naRm == RRuntime.LOGICAL_TRUE) {
+                if (profiledNaRm) {
                     continue;
                 } else {
                     return RRuntime.DOUBLE_NA;
@@ -226,6 +249,7 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
 
     @Specialization
     protected int doLogicalVector(RLogicalVector operand, byte naRm) {
+        boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
         int result = semantics.getIntStart();
         na.enable(operand);
         int opCount = 0;
@@ -233,7 +257,7 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
             byte d = operand.getDataAt(i);
             na.enable(d);
             if (na.check(d)) {
-                if (naRm == RRuntime.LOGICAL_TRUE) {
+                if (profiledNaRm) {
                     continue;
                 } else {
                     return RRuntime.INT_NA;
@@ -282,13 +306,14 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
     @Specialization
     protected RComplex doComplexVector(RComplexVector operand, byte naRm) {
         if (semantics.supportComplex) {
+            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
             RComplex result = RRuntime.double2complex(semantics.getDoubleStart());
             int opCount = 0;
             for (int i = 0; i < operand.getLength(); ++i) {
                 RComplex current = operand.getDataAt(i);
                 na.enable(current);
                 if (na.check(current)) {
-                    if (naRm == RRuntime.LOGICAL_TRUE) {
+                    if (profiledNaRm) {
                         continue;
                     } else {
                         return RRuntime.createComplexNA();
@@ -313,23 +338,28 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
     // "largest" String for the implementation of max function
 
     @SuppressWarnings("unused")
-    @Specialization(guards = "empty")
-    protected String doStringVectorEmpty(RStringVector operand, byte naRm) {
+    protected static String doStringVectorEmptyInternal(RStringVector operand, byte naRm, ReduceSemantics semantics, SourceSection sourceSection) {
         if (semantics.supportString) {
             if (semantics.getEmptyWarning() != null) {
                 RError.warning(semantics.emptyWarning);
             }
             return semantics.getStringStart();
         } else {
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_TYPE_ARGUMENT, "character");
+            throw RError.error(sourceSection, RError.Message.INVALID_TYPE_ARGUMENT, "character");
         }
     }
 
+    @Specialization(guards = "empty")
+    protected String doStringVectorEmpty(RStringVector operand, byte naRm) {
+        return doStringVectorEmptyInternal(operand, naRm, semantics, getEncapsulatingSourceSection());
+    }
+
     @Specialization(guards = "lengthOne")
     protected String doStringVectorOneElem(RStringVector operand, byte naRm) {
         if (semantics.supportString) {
+            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
             String result = operand.getDataAt(0);
-            if (naRm == RRuntime.LOGICAL_TRUE) {
+            if (profiledNaRm) {
                 na.enable(result);
                 if (na.check(result)) {
                     return doStringVectorEmpty(operand, naRm);
@@ -341,48 +371,10 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
         }
     }
 
-    @SlowPath
-    private String doStringVectorMultiElem(RStringVector operand, byte naRm, int offset) {
-        String result = operand.getDataAt(offset);
-        na.enable(result);
-        if (naRm == RRuntime.LOGICAL_TRUE) {
-            if (na.check(result)) {
-                // the following is meant to eliminate leading NA-s
-                if (offset == operand.getLength() - 1) {
-                    // last element - all other are NAs
-                    return doStringVectorEmpty(operand, naRm);
-                } else {
-                    return doStringVectorMultiElem(operand, naRm, offset + 1);
-                }
-            }
-        } else {
-            if (na.check(result)) {
-                return result;
-            }
-        }
-        // when we reach here, it means that we have already seen one non-NA element
-        assert !RRuntime.isNA(result);
-        for (int i = offset + 1; i < operand.getLength(); ++i) {
-            String current = operand.getDataAt(i);
-            na.enable(current);
-            if (na.check(current)) {
-                if (naRm == RRuntime.LOGICAL_TRUE) {
-                    // skip NA-s
-                    continue;
-                } else {
-                    return RRuntime.STRING_NA;
-                }
-            } else {
-                result = arithmetic.op(result, current);
-            }
-        }
-        return result;
-    }
-
     @Specialization(guards = "longerThanOne")
-    protected String doStringVector(RStringVector operand, byte naRm) {
+    protected String doStringVector(VirtualFrame frame, RStringVector operand, byte naRm) {
         if (semantics.supportString) {
-            return doStringVectorMultiElem(operand, naRm, 0);
+            return handleString(frame, operand, naRm, 0);
         } else {
             throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_TYPE_ARGUMENT, "character");
         }
@@ -455,4 +447,76 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
 
     }
 
+    @NodeChildren({@NodeChild("operand"), @NodeChild("naRm"), @NodeChild("offset")})
+    protected abstract static class MultiElemStringHandler extends RNode {
+
+        public abstract String executeString(VirtualFrame frame, RStringVector operand, byte naRm, int offset);
+
+        @Child private MultiElemStringHandler recursiveStringHandler;
+        private final ReduceSemantics semantics;
+        private final BinaryArithmeticFactory factory;
+        @Child private BinaryArithmetic arithmetic;
+        private final NACheck na;
+        final ConditionProfile naRmProfile = ConditionProfile.createBinaryProfile();
+
+        public MultiElemStringHandler(ReduceSemantics semantics, BinaryArithmeticFactory factory, NACheck na) {
+            this.semantics = semantics;
+            this.factory = factory;
+            this.arithmetic = factory.create();
+            this.na = na;
+        }
+
+        public MultiElemStringHandler(MultiElemStringHandler other) {
+            this(other.semantics, other.factory, other.na);
+        }
+
+        private String handleString(VirtualFrame frame, RStringVector operand, byte naRm, int offset) {
+            if (recursiveStringHandler == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                recursiveStringHandler = insert(MultiElemStringHandlerFactory.create(semantics, factory, na, null, null, null));
+            }
+            return recursiveStringHandler.executeString(frame, operand, naRm, offset);
+        }
+
+        @Specialization
+        protected String doStringVectorMultiElem(VirtualFrame frame, RStringVector operand, byte naRm, int offset) {
+            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
+            String result = operand.getDataAt(offset);
+            na.enable(result);
+            if (profiledNaRm) {
+                if (na.check(result)) {
+                    // the following is meant to eliminate leading NA-s
+                    if (offset == operand.getLength() - 1) {
+                        // last element - all other are NAs
+                        return doStringVectorEmptyInternal(operand, naRm, semantics, getEncapsulatingSourceSection());
+                    } else {
+                        return handleString(frame, operand, naRm, offset + 1);
+                    }
+                }
+            } else {
+                if (na.check(result)) {
+                    return result;
+                }
+            }
+            // when we reach here, it means that we have already seen one non-NA element
+            assert !RRuntime.isNA(result);
+            for (int i = offset + 1; i < operand.getLength(); ++i) {
+                String current = operand.getDataAt(i);
+                na.enable(current);
+                if (na.check(current)) {
+                    if (profiledNaRm) {
+                        // skip NA-s
+                        continue;
+                    } else {
+                        return RRuntime.STRING_NA;
+                    }
+                } else {
+                    result = arithmetic.op(result, current);
+                }
+            }
+            return result;
+        }
+
+    }
+
 }
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 3dcc90774a..aedba11722 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
@@ -64100,6 +64100,121 @@ character(0)
 #argv <- list(character(0), c('labels', 'col', 'alpha', 'adj', 'cex', 'lineheight', 'font'), NA_integer_, TRUE); .Internal(pmatch(argv[[1]], argv[[2]], argv[[3]], argv[[4]]))
 integer(0)
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax1
+#argv <- list(FALSE, 5L, 12); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))
+[1] 12
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax10
+#argv <- list(FALSE, c(1.05, 1.92, 0.36, 4.98, 4.56, 0.69, -5.97, 1.26, 5.58, -0.06, -4.92, -1.38, -0.3, 3.75, 1.11, 0.93, 3.33, 4.95, 0.99, 2.67, -0.75, -2.61, -0.66, 2.13, -6.78, 2.31, -0.15, 0.96, -1.92, 1.17, 0.57, -4.86, 1.11, 0.06, 2.91, -7.86, 0.45, 4.65, -4.23, -7.05, -1.29, 1.71, -1.98, -0.24, 0.06, 0.72, -0.99, -0.09, -3.39, 0.96, 4.65, 6.39, -0.3, -0.96, -2.01, 4.32, 0.12, -3.3, -2.85, -0.57, -2.04, -1.29, -2.52, 2.07, -1.95, 2.13, 0.57, 1.35, 1.35, -3.57, 3.9, 0.42, -1.08, -1.5, -1.41, -3.93, -3.06, 3.51, 4.53, -0.99, -0.03, -1.77, -0.84, -0.54, -3.21, 1.98, -2.13, 5.64, -0.42, -0.57, 2.52, 1.32, 3.99, -0.6, -1.35, 4.38, 3, -3.06, 2.04, 2.52), 0); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))
+  [1] 1.05 1.92 0.36 4.98 4.56 0.69 0.00 1.26 5.58 0.00 0.00 0.00 0.00 3.75 1.11
+ [16] 0.93 3.33 4.95 0.99 2.67 0.00 0.00 0.00 2.13 0.00 2.31 0.00 0.96 0.00 1.17
+ [31] 0.57 0.00 1.11 0.06 2.91 0.00 0.45 4.65 0.00 0.00 0.00 1.71 0.00 0.00 0.06
+ [46] 0.72 0.00 0.00 0.00 0.96 4.65 6.39 0.00 0.00 0.00 4.32 0.12 0.00 0.00 0.00
+ [61] 0.00 0.00 0.00 2.07 0.00 2.13 0.57 1.35 1.35 0.00 3.90 0.42 0.00 0.00 0.00
+ [76] 0.00 0.00 3.51 4.53 0.00 0.00 0.00 0.00 0.00 0.00 1.98 0.00 5.64 0.00 0.00
+ [91] 2.52 1.32 3.99 0.00 0.00 4.38 3.00 0.00 2.04 2.52
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax11
+#argv <- list(FALSE, c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L), 7L, c(7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 6L)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]], argv[[4]]))
+[1] 7 7 7 7 7 7 7 7 7
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax12
+#argv <- list(FALSE, 1:7, structure(c(2, 3, 4, 2, 2, 2), .Dim = c(3L, 2L), .Dimnames = list(NULL, c('a', '')))); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))
+[1] 2 3 4 4 5 6 7
+Warning message:
+an argument will be fractionally recycled
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax13
+#argv <- list(FALSE, c(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)); .Internal(pmax(argv[[1]], argv[[2]]))
+  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
+ [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
+ [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
+ [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
+ [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
+ [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
+ [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
+ [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
+ [97] FALSE FALSE FALSE FALSE
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax3
+#argv <- list(FALSE, c(0L, 1L, 1L, 1L, 2L), 5L, c(6L, 5L, 5L, 5L, 4L)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]], argv[[4]]))
+[1] 6 5 5 5 5
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax4
+#argv <- list(FALSE, 0, numeric(0)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))
+numeric(0)
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax5
+#argv <- list(FALSE, structure(c(63.5607991023966, 46.8465846258113, 40.7088275958184, 31.3395189414991, 42.5666751143734, 47.0610532806931, 23.9315410227325, 43.0690616089581, 66.7869292908986, 49.2243580808943, 31.6784834018036, 24.3875466143556, 48.4619434336134, 53.5787701502931, 25.0466211495357, 45.0758464889871, 66.9256619232735, 49.3266089980428, 31.7843035976521, 24.4690118450696, 50.7406402769298, 56.0980619029545, 17.201254072711, 30.956714016252), .Names = c('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24')), 2.22044604925031e-16); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))
+ [1] 63.56080 46.84658 40.70883 31.33952 42.56668 47.06105 23.93154 43.06906
+ [9] 66.78693 49.22436 31.67848 24.38755 48.46194 53.57877 25.04662 45.07585
+[17] 66.92566 49.32661 31.78430 24.46901 50.74064 56.09806 17.20125 30.95671
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax6
+#argv <- list(FALSE, FALSE, FALSE); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))
+[1] 0
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax7
+#argv <- list(FALSE, 1L, c(15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))
+[1] 15 15 15 15 15 15 15 15 15
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax8
+#argv <- list(FALSE, structure(c(0.0193057433072215, 0.00434780301273374, 0.0549750394687487, 0.510714717273168, 0.0482077179041234, 0.349752997299534, 0.15114556457294, 0.614610341225044, 0.270367074042314, 0.376738504472563, 0.00100006670765362, 0.616978737736246, 0.000115089535300671, 0.114479803728228, 0.0345012755277619, 0.520238904129887, 0.0177036726480846, 0.00345369763623826, 0.0372744005491215, 0.245210198359521, 0.0651842100459408, 0.4506670448926, 0.178923774229777, 0.332256206500317, 0.402299202627705, 0.380395198873703, 0.000984316947253816, 0.403063829062269, 0.000174431720286923, 0.138958543973059, 0.0379750520636422, 0.379247258699123), .Names = c('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32')), 0); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))
+ [1] 0.0193057433 0.0043478030 0.0549750395 0.5107147173 0.0482077179
+ [6] 0.3497529973 0.1511455646 0.6146103412 0.2703670740 0.3767385045
+[11] 0.0010000667 0.6169787377 0.0001150895 0.1144798037 0.0345012755
+[16] 0.5202389041 0.0177036726 0.0034536976 0.0372744005 0.2452101984
+[21] 0.0651842100 0.4506670449 0.1789237742 0.3322562065 0.4022992026
+[26] 0.3803951989 0.0009843169 0.4030638291 0.0001744317 0.1389585440
+[31] 0.0379750521 0.3792472587
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmax.testpmax9
+#argv <- list(FALSE, structure(c(35.2592591597479, 59.4999999843455, 12.4507044164935, 2.53543312099158, 10.3703703404756, 42.0000005728299, 8.14084538858294, 34.04724471918, 7.77778142338517, 26.9999999889474, 6.70422536805755, 3.62204828940961, 2.59259259558406, 14.4999999939529, 6.70422536805755, 5.79527724426002, 32.7407408614199, 59.5000000376209, 13.54929592464, 4.46456690511876, 9.62962966454155, 42.0000006104361, 8.85915523787816, 59.9527554977598, 7.22222565443263, 27.0000000131229, 7.29577463400041, 6.37795443616981, 2.40740742585304, 14.500000006936, 7.29577463400041, 10.2047270647755), .Names = c('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32')), 2.22044604925031e-16); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))
+ [1] 35.259259 59.500000 12.450704  2.535433 10.370370 42.000001  8.140845
+ [8] 34.047245  7.777781 27.000000  6.704225  3.622048  2.592593 14.500000
+[15]  6.704225  5.795277 32.740741 59.500000 13.549296  4.464567  9.629630
+[22] 42.000001  8.859155 59.952755  7.222226 27.000000  7.295775  6.377954
+[29]  2.407407 14.500000  7.295775 10.204727
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmin.testpmin1
+#argv <- list(FALSE, c(0, 0.25, 0.5, 0.75, 1), 1); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))
+[1] 0.00 0.25 0.50 0.75 1.00
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmin.testpmin10
+#argv <- list(FALSE, 1, 0.341867139159); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))
+[1] 0.3418671
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmin.testpmin3
+#argv <- list(FALSE, c(19.7787405591752, 12504507.4953993, 12504507.4953993, 5.96190157728191e+41), 1); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))
+[1] 1 1 1 1
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmin.testpmin4
+#argv <- list(FALSE, structure(c(2, 3, 4, 2, 2, 2), .Dim = c(3L, 2L), .Dimnames = list(NULL, c('a', ''))), 1:7); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))
+[1] 1 2 3 2 2 2 2
+Warning message:
+an argument will be fractionally recycled
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmin.testpmin5
+#argv <- list(FALSE, structure(c(-2.30560410637911, -1.56788329848973, -0.885216282233891, -0.246592299284877, 0.350190802022645, 0.913941628350052, 1.44466017969734, 1.94895291106052), .Names = c('1', '2', '3', '4', '5', '6', '7', '8')), 700); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))
+[1] -2.3056041 -1.5678833 -0.8852163 -0.2465923  0.3501908  0.9139416  1.4446602
+[8]  1.9489529
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmin.testpmin6
+#argv <- list(FALSE, 1, structure(numeric(0), .Dim = c(4L, 0L))); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))
+numeric(0)
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmin.testpmin7
+#argv <- list(FALSE, FALSE, FALSE); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))
+[1] 0
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmin.testpmin8
+#argv <- list(FALSE, FALSE); .Internal(pmin(argv[[1]], argv[[2]]))
+[1] FALSE
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinpmin.testpmin9
+#argv <- list(FALSE, 48L, 19L); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))
+[1] 19
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinprod.testprod1
 #argv <- list(9L);prod(argv[[1]]);
 [1] 9
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java
index 8798bcc472..f25342203e 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java
@@ -11333,31 +11333,6 @@ public class FailingTests extends TestBase {
         assertEval("argv <- list(list('  ‘help.search()’ or ‘', '??'), NULL); .Internal(paste0(argv[[1]], argv[[2]]))");
     }
 
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax1_577dbb437ac154628f077467816101fe() {
-        assertEval("argv <- list(FALSE, 5L, 12); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax10_e76c5f2bff2d1ed705c10245445ec187() {
-        assertEval("argv <- list(FALSE, c(1.05, 1.92, 0.36, 4.98, 4.56, 0.69, -5.97, 1.26, 5.58, -0.06, -4.92, -1.38, -0.3, 3.75, 1.11, 0.93, 3.33, 4.95, 0.99, 2.67, -0.75, -2.61, -0.66, 2.13, -6.78, 2.31, -0.15, 0.96, -1.92, 1.17, 0.57, -4.86, 1.11, 0.06, 2.91, -7.86, 0.45, 4.65, -4.23, -7.05, -1.29, 1.71, -1.98, -0.24, 0.06, 0.72, -0.99, -0.09, -3.39, 0.96, 4.65, 6.39, -0.3, -0.96, -2.01, 4.32, 0.12, -3.3, -2.85, -0.57, -2.04, -1.29, -2.52, 2.07, -1.95, 2.13, 0.57, 1.35, 1.35, -3.57, 3.9, 0.42, -1.08, -1.5, -1.41, -3.93, -3.06, 3.51, 4.53, -0.99, -0.03, -1.77, -0.84, -0.54, -3.21, 1.98, -2.13, 5.64, -0.42, -0.57, 2.52, 1.32, 3.99, -0.6, -1.35, 4.38, 3, -3.06, 2.04, 2.52), 0); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax11_4028665897dd35dd481469eba539d54c() {
-        assertEval("argv <- list(FALSE, c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L), 7L, c(7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 6L)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]], argv[[4]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax12_e6edb5d0881bbda799bf365556658391() {
-        assertEval("argv <- list(FALSE, 1:7, structure(c(2, 3, 4, 2, 2, 2), .Dim = c(3L, 2L), .Dimnames = list(NULL, c('a', '')))); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax13_1600b3cabda6c0beb7c32b97933824dd() {
-        assertEval("argv <- list(FALSE, c(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)); .Internal(pmax(argv[[1]], argv[[2]]))");
-    }
-
     @Ignore
     public void TestrGenBuiltinpmax_testpmax14_80e524df95a2776589a3d3ad4eea1117() {
         assertEval("argv <- list(FALSE, structure(c(0, 0, -0.0906283137921162, -0.0801994352402973, -0.0235093686536505, -0.131187875867331, -0.131187875867331, -0.131187875867331, -0.131187875867331, 0, 0, 0, -0.106539777104723, -0.106539777104723, -0.106539777104723, 0, 0, 0.126786975893341, 0.126786975893341, 0.126786975893341, 0, -0.131187875867331, -0.131187875867331, -0.131187875867331, 0, -0.106539777104723, -0.106539777104723, -0.106539777104723, 0, 0, 0, -0.106539777104723, 0.172297822926899, 0.172297822926899, 0, 0, 0, 0, 0, -0.106539777104723, -0.106539777104723, -0.106539777104723, -0.106539777104723, 0, 0, 0, 0.172297822926899, 0.172297822926899), .Dim = c(12L, 4L)), 0); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
@@ -11368,51 +11343,6 @@ public class FailingTests extends TestBase {
         assertEval("argv <- list(FALSE, -100, structure(c(-Inf, 82.9775012103133, 8.55983483385341e+101, -Inf, 79.3831968838961, 8.55983483385341e+101), .Names = c('', '', '', '', '', ''))); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax3_e2111b6921e28636ab438e66f1b7aceb() {
-        assertEval("argv <- list(FALSE, c(0L, 1L, 1L, 1L, 2L), 5L, c(6L, 5L, 5L, 5L, 4L)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]], argv[[4]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax4_c2a123a6b1fc765eba27203547ed16a4() {
-        assertEval("argv <- list(FALSE, 0, numeric(0)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax5_53770b6669953d0dc54a256d5f75a6d1() {
-        assertEval("argv <- list(FALSE, structure(c(63.5607991023966, 46.8465846258113, 40.7088275958184, 31.3395189414991, 42.5666751143734, 47.0610532806931, 23.9315410227325, 43.0690616089581, 66.7869292908986, 49.2243580808943, 31.6784834018036, 24.3875466143556, 48.4619434336134, 53.5787701502931, 25.0466211495357, 45.0758464889871, 66.9256619232735, 49.3266089980428, 31.7843035976521, 24.4690118450696, 50.7406402769298, 56.0980619029545, 17.201254072711, 30.956714016252), .Names = c('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24')), 2.22044604925031e-16); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax6_463977440101226b958d5647d70733a7() {
-        assertEval("argv <- list(FALSE, FALSE, FALSE); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax7_12e4d25d490485d4ce70627b29b17cf2() {
-        assertEval("argv <- list(FALSE, 1L, c(15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax8_e23c4e0c8028a272a8a0fabc6dfc87cd() {
-        assertEval("argv <- list(FALSE, structure(c(0.0193057433072215, 0.00434780301273374, 0.0549750394687487, 0.510714717273168, 0.0482077179041234, 0.349752997299534, 0.15114556457294, 0.614610341225044, 0.270367074042314, 0.376738504472563, 0.00100006670765362, 0.616978737736246, 0.000115089535300671, 0.114479803728228, 0.0345012755277619, 0.520238904129887, 0.0177036726480846, 0.00345369763623826, 0.0372744005491215, 0.245210198359521, 0.0651842100459408, 0.4506670448926, 0.178923774229777, 0.332256206500317, 0.402299202627705, 0.380395198873703, 0.000984316947253816, 0.403063829062269, 0.000174431720286923, 0.138958543973059, 0.0379750520636422, 0.379247258699123), .Names = c('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32')), 0); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmax_testpmax9_c038e74f3e217137c0de9c9808766677() {
-        assertEval("argv <- list(FALSE, structure(c(35.2592591597479, 59.4999999843455, 12.4507044164935, 2.53543312099158, 10.3703703404756, 42.0000005728299, 8.14084538858294, 34.04724471918, 7.77778142338517, 26.9999999889474, 6.70422536805755, 3.62204828940961, 2.59259259558406, 14.4999999939529, 6.70422536805755, 5.79527724426002, 32.7407408614199, 59.5000000376209, 13.54929592464, 4.46456690511876, 9.62962966454155, 42.0000006104361, 8.85915523787816, 59.9527554977598, 7.22222565443263, 27.0000000131229, 7.29577463400041, 6.37795443616981, 2.40740742585304, 14.500000006936, 7.29577463400041, 10.2047270647755), .Names = c('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32')), 2.22044604925031e-16); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmin_testpmin1_72e68bfc3fae179c2ac94236955f06ae() {
-        assertEval("argv <- list(FALSE, c(0, 0.25, 0.5, 0.75, 1), 1); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmin_testpmin10_04ee451767a8d8cae02fb34ae2a41eae() {
-        assertEval("argv <- list(FALSE, 1, 0.341867139159); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
     @Ignore
     public void TestrGenBuiltinpmin_testpmin11_96e9aae810452d3c92e783cf262716d8() {
         assertEval("argv <- list(FALSE, c(2.35405350797934e-06, 0.000210159024072429, 0.000257684187404011, 0.000981478332360736, 0.00105260958830543, 0.00124148072892802, 0.00132598801923585, 0.00156850331255678, 0.00225455732762676, 0.003795380309271, 0.00611494315340942, 0.0161395372907077, 0.0330242962313738, 0.0353834177611007, 0.0523699658057458, 0.068319089314331, 0.0705922565893261, 0.0880512860101142, 0.0940103983967277, 0.112979808322889, 0.211501681388388, 0.492273640304204, 0.605329775053071, 0.626223946736039, 0.739515289321684, 0.828110328240387, 0.86333312789587, 1.19065433061771, 1.89079625396729, 2.05849377808347, 2.20921371984431, 2.85600042559897, 3.04889487308354, 4.66068200259841, 4.83080935233713, 4.92175460488491, 5.31945286062773, 5.75155046407955, 5.78319462345744), 0.943789021783783); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
@@ -11423,41 +11353,6 @@ public class FailingTests extends TestBase {
         assertEval("argv <- list(FALSE, c(1.01547865839261, 1.01252937204691, 1.00644625408792, 0.998699246049516, 0.989861830865133, 0.980229984263028, 0.969980509594864, 0.959229159804225, 0.948056660278026, 0.948056660278026, 0.936413637553504, 0.924430242566905, 0.924430242566905, 0.912012661079992, 0.912012661079992, 0.912012661079992, 0.912012661079992, 0.912012661079992, 0.912012661079992, 0.89856564301575, 0.89856564301575, 0.89856564301575, 0.89856564301575, 0.884221004526004, 0.884221004526004, 0.884221004526004, 0.884221004526004, 0.868846889674391, 0.852918138766346, 0.852918138766346, 0.852918138766346, 0.836013989965276, 0.836013989965276, 0.818281118997659, 0.818281118997659, 0.799674858806929, 0.78048190648179, 0.760752205123712, 0.740524405390135, 0.698688252548957, 0.677121358432204, 0.677121358432204, 0.677121358432204, 0.653968759838845, 0.630226345284056, 0.60591293760604, 0.5810405538867, 0.5810405538867, 0.554772713636871, 0.554772713636871, 0.526885054753327, 0.526885054753327, 0.497124929362659, 0.497124929362659, 0.465290373327728, 0.431410832191818, 0.395597572090297, 0.358012869967492, 0.358012869967492, 0.358012869967492, 0.390645999939295, 0.390645999939295, 1.00856963764107, 1.00691545377429, 1.00354783420184, 0.994430782349702, 0.989161076962549, 0.983568844113983, 0.971651869906627, 0.965403818059832, 0.958998025317496, 0.952453588123512, 0.945785731840592, 0.939006829762577, 0.932127100227826, 0.925155098145928, 0.918098070593368, 0.910962219832367, 0.903752901643838, 0.896474777439562, 0.889131932689408, 0.874266085562073, 0.866749125736792, 0.85917963981466, 0.85917963981466, 0.85917963981466, 0.851432533571458, 0.851432533571458, 0.835646571743332, 0.819657377450186, 0.811591248493136, 0.811591248493136, 0.803403072648503, 0.803403072648503, 0.803403072648503, 0.79500789222886, 0.79500789222886, 0.78647848620035, 0.777810139927498, 0.777810139927498, 0.768997769554365, 0.760132009504045, 0.751214427604144, 0.751214427604144, 0.751214427604144, 0.742042333451995, 0.742042333451995, 0.732706928458195, 0.723314130803801, 0.713865427684027, 0.713865427684027, 0.704242881823747, 0.704242881823747, 0.694438026993695, 0.684573363315093, 0.674650164742493, 0.664669564073024, 0.664669564073024, 0.664669564073024, 0.654342845821626, 0.643951412016272, 0.633496370097346, 0.633496370097346, 0.622814395282618, 0.622814395282618, 0.611712238653597, 0.600530813249145, 0.589271296091113, 0.577934661160654, 0.577934661160654, 0.554603983179207, 0.542813560886543, 0.530698712197854, 0.530698712197854, 0.518231810914377, 0.518231810914377, 0.518231810914377, 0.505091485230836, 0.491816896403255, 0.478408881208852, 0.464867758182769, 0.464867758182769, 0.450831087639633, 0.43663736059032, 0.422285766886131, 0.422285766886131, 0.407334269006221, 0.392187384239101, 0.376842383287708, 0.376842383287708, 0.36074886771613, 0.344393472477708, 0.327769800745284, 0.310869313273075, 0.293681131444043, 0.27619182464681, 0.258385252532011, 0.240242648154923, 0.221743435532848, 0.202868148187672, 0.183607543425597, 0.183607543425597, 0.16434288099768, 0.16434288099768, 0.16434288099768, 0.16434288099768, 1.01958384078021, 1.0158820929578, 1.00818641731953, 0.998355892450852, 0.98711678103063, 0.974844224342501, 0.961762390694789, 0.94801800556359, 0.933713296997721, 0.918922795982771, 0.918922795982771, 0.903505632185222, 0.887664218536847, 0.8714385967694, 0.854601072478364, 0.837400228461143, 0.81986117753083, 0.80200434269104, 0.783846415628184, 0.765401054645917, 0.746679400612251, 0.727690462294359, 0.70844140545579, 0.688937769124757, 0.669183625153216, 0.649181692191925, 0.628933411668998, 0.608438990755048, 0.608438990755048, 0.587078835123946, 0.565417411428399, 0.543452081149807, 0.521178337588507, 0.498589701519445, 0.475677565090786, 0.475677565090786, 0.451501204504207, 0.426861888982249, 0.401742325799741, 0.376120821121693, 0.349971441565183, 0.323265236972233, 0.323265236972233, 0.294966951140867, 0.265661696527275, 0.265661696527275, 0.24198035833067, 0.229359831745471, NA, NA), 1); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
-    @Ignore
-    public void TestrGenBuiltinpmin_testpmin3_897bd631d9a55fa318b4b3de23375478() {
-        assertEval("argv <- list(FALSE, c(19.7787405591752, 12504507.4953993, 12504507.4953993, 5.96190157728191e+41), 1); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmin_testpmin4_47bf1e411d8a55724829d60837438c00() {
-        assertEval("argv <- list(FALSE, structure(c(2, 3, 4, 2, 2, 2), .Dim = c(3L, 2L), .Dimnames = list(NULL, c('a', ''))), 1:7); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmin_testpmin5_2406b271107468c875aa9afae3f93b53() {
-        assertEval("argv <- list(FALSE, structure(c(-2.30560410637911, -1.56788329848973, -0.885216282233891, -0.246592299284877, 0.350190802022645, 0.913941628350052, 1.44466017969734, 1.94895291106052), .Names = c('1', '2', '3', '4', '5', '6', '7', '8')), 700); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmin_testpmin6_b00af5eb9844ca72a2a0c5e51c4b6be1() {
-        assertEval("argv <- list(FALSE, 1, structure(numeric(0), .Dim = c(4L, 0L))); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmin_testpmin7_12e21777f7ad77dd64c735ce36ccc26c() {
-        assertEval("argv <- list(FALSE, FALSE, FALSE); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmin_testpmin8_636bcd8067c2ba4023c0db564bad03dc() {
-        assertEval("argv <- list(FALSE, FALSE); .Internal(pmin(argv[[1]], argv[[2]]))");
-    }
-
-    @Ignore
-    public void TestrGenBuiltinpmin_testpmin9_4ec25d509351b9f32214421601e1a414() {
-        assertEval("argv <- list(FALSE, 48L, 19L); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
-    }
-
     @Ignore
     public void TestrGenBuiltinpolyroot_testpolyroot1_a4e8741b0d2003d978ab0e51bbe41355() {
         assertEval("argv <- list(1:2); .Internal(polyroot(argv[[1]]))");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinpmax.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinpmax.java
index 7f669d7952..9e9e0195aa 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinpmax.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinpmax.java
@@ -2,7 +2,7 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
  * Copyright (c) 2014, Oracle and/or its affiliates
  *
@@ -17,7 +17,6 @@ import com.oracle.truffle.r.test.*;
 public class TestrGenBuiltinpmax extends TestBase {
 
     @Test
-    @Ignore
     public void testpmax1() {
         assertEval("argv <- list(FALSE, 5L, 12); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
@@ -25,71 +24,61 @@ public class TestrGenBuiltinpmax extends TestBase {
     @Test
     @Ignore
     public void testpmax2() {
+        // problem with number formatting
         assertEval("argv <- list(FALSE, -100, structure(c(-Inf, 82.9775012103133, 8.55983483385341e+101, -Inf, 79.3831968838961, 8.55983483385341e+101), .Names = c(\'\', \'\', \'\', \'\', \'\', \'\'))); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmax3() {
         assertEval("argv <- list(FALSE, c(0L, 1L, 1L, 1L, 2L), 5L, c(6L, 5L, 5L, 5L, 4L)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]], argv[[4]]))");
     }
 
     @Test
-    @Ignore
     public void testpmax4() {
         assertEval("argv <- list(FALSE, 0, numeric(0)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmax5() {
         assertEval("argv <- list(FALSE, structure(c(63.5607991023966, 46.8465846258113, 40.7088275958184, 31.3395189414991, 42.5666751143734, 47.0610532806931, 23.9315410227325, 43.0690616089581, 66.7869292908986, 49.2243580808943, 31.6784834018036, 24.3875466143556, 48.4619434336134, 53.5787701502931, 25.0466211495357, 45.0758464889871, 66.9256619232735, 49.3266089980428, 31.7843035976521, 24.4690118450696, 50.7406402769298, 56.0980619029545, 17.201254072711, 30.956714016252), .Names = c(\'1\', \'2\', \'3\', \'4\', \'5\', \'6\', \'7\', \'8\', \'9\', \'10\', \'11\', \'12\', \'13\', \'14\', \'15\', \'16\', \'17\', \'18\', \'19\', \'20\', \'21\', \'22\', \'23\', \'24\')), 2.22044604925031e-16); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmax6() {
         assertEval("argv <- list(FALSE, FALSE, FALSE); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmax7() {
         assertEval("argv <- list(FALSE, 1L, c(15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmax8() {
         assertEval("argv <- list(FALSE, structure(c(0.0193057433072215, 0.00434780301273374, 0.0549750394687487, 0.510714717273168, 0.0482077179041234, 0.349752997299534, 0.15114556457294, 0.614610341225044, 0.270367074042314, 0.376738504472563, 0.00100006670765362, 0.616978737736246, 0.000115089535300671, 0.114479803728228, 0.0345012755277619, 0.520238904129887, 0.0177036726480846, 0.00345369763623826, 0.0372744005491215, 0.245210198359521, 0.0651842100459408, 0.4506670448926, 0.178923774229777, 0.332256206500317, 0.402299202627705, 0.380395198873703, 0.000984316947253816, 0.403063829062269, 0.000174431720286923, 0.138958543973059, 0.0379750520636422, 0.379247258699123), .Names = c(\'1\', \'2\', \'3\', \'4\', \'5\', \'6\', \'7\', \'8\', \'9\', \'10\', \'11\', \'12\', \'13\', \'14\', \'15\', \'16\', \'17\', \'18\', \'19\', \'20\', \'21\', \'22\', \'23\', \'24\', \'25\', \'26\', \'27\', \'28\', \'29\', \'30\', \'31\', \'32\')), 0); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmax9() {
         assertEval("argv <- list(FALSE, structure(c(35.2592591597479, 59.4999999843455, 12.4507044164935, 2.53543312099158, 10.3703703404756, 42.0000005728299, 8.14084538858294, 34.04724471918, 7.77778142338517, 26.9999999889474, 6.70422536805755, 3.62204828940961, 2.59259259558406, 14.4999999939529, 6.70422536805755, 5.79527724426002, 32.7407408614199, 59.5000000376209, 13.54929592464, 4.46456690511876, 9.62962966454155, 42.0000006104361, 8.85915523787816, 59.9527554977598, 7.22222565443263, 27.0000000131229, 7.29577463400041, 6.37795443616981, 2.40740742585304, 14.500000006936, 7.29577463400041, 10.2047270647755), .Names = c(\'1\', \'2\', \'3\', \'4\', \'5\', \'6\', \'7\', \'8\', \'9\', \'10\', \'11\', \'12\', \'13\', \'14\', \'15\', \'16\', \'17\', \'18\', \'19\', \'20\', \'21\', \'22\', \'23\', \'24\', \'25\', \'26\', \'27\', \'28\', \'29\', \'30\', \'31\', \'32\')), 2.22044604925031e-16); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmax10() {
         assertEval("argv <- list(FALSE, c(1.05, 1.92, 0.36, 4.98, 4.56, 0.69, -5.97, 1.26, 5.58, -0.06, -4.92, -1.38, -0.3, 3.75, 1.11, 0.93, 3.33, 4.95, 0.99, 2.67, -0.75, -2.61, -0.66, 2.13, -6.78, 2.31, -0.15, 0.96, -1.92, 1.17, 0.57, -4.86, 1.11, 0.06, 2.91, -7.86, 0.45, 4.65, -4.23, -7.05, -1.29, 1.71, -1.98, -0.24, 0.06, 0.72, -0.99, -0.09, -3.39, 0.96, 4.65, 6.39, -0.3, -0.96, -2.01, 4.32, 0.12, -3.3, -2.85, -0.57, -2.04, -1.29, -2.52, 2.07, -1.95, 2.13, 0.57, 1.35, 1.35, -3.57, 3.9, 0.42, -1.08, -1.5, -1.41, -3.93, -3.06, 3.51, 4.53, -0.99, -0.03, -1.77, -0.84, -0.54, -3.21, 1.98, -2.13, 5.64, -0.42, -0.57, 2.52, 1.32, 3.99, -0.6, -1.35, 4.38, 3, -3.06, 2.04, 2.52), 0); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmax11() {
         assertEval("argv <- list(FALSE, c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L), 7L, c(7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 6L)); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]], argv[[4]]))");
     }
 
     @Test
-    @Ignore
     public void testpmax12() {
         assertEval("argv <- list(FALSE, 1:7, structure(c(2, 3, 4, 2, 2, 2), .Dim = c(3L, 2L), .Dimnames = list(NULL, c(\'a\', \'\')))); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmax13() {
         assertEval("argv <- list(FALSE, c(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)); .Internal(pmax(argv[[1]], argv[[2]]))");
     }
@@ -97,6 +86,7 @@ public class TestrGenBuiltinpmax extends TestBase {
     @Test
     @Ignore
     public void testpmax14() {
+        // problem with number formatting
         assertEval("argv <- list(FALSE, structure(c(0, 0, -0.0906283137921162, -0.0801994352402973, -0.0235093686536505, -0.131187875867331, -0.131187875867331, -0.131187875867331, -0.131187875867331, 0, 0, 0, -0.106539777104723, -0.106539777104723, -0.106539777104723, 0, 0, 0.126786975893341, 0.126786975893341, 0.126786975893341, 0, -0.131187875867331, -0.131187875867331, -0.131187875867331, 0, -0.106539777104723, -0.106539777104723, -0.106539777104723, 0, 0, 0, -0.106539777104723, 0.172297822926899, 0.172297822926899, 0, 0, 0, 0, 0, -0.106539777104723, -0.106539777104723, -0.106539777104723, -0.106539777104723, 0, 0, 0, 0.172297822926899, 0.172297822926899), .Dim = c(12L, 4L)), 0); .Internal(pmax(argv[[1]], argv[[2]], argv[[3]]))");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinpmin.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinpmin.java
index 32202d8dab..9cb4cc2291 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinpmin.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinpmin.java
@@ -2,7 +2,7 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
  * Copyright (c) 2014, Oracle and/or its affiliates
  *
@@ -17,7 +17,6 @@ import com.oracle.truffle.r.test.*;
 public class TestrGenBuiltinpmin extends TestBase {
 
     @Test
-    @Ignore
     public void testpmin1() {
         assertEval("argv <- list(FALSE, c(0, 0.25, 0.5, 0.75, 1), 1); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
     }
@@ -25,53 +24,46 @@ public class TestrGenBuiltinpmin extends TestBase {
     @Test
     @Ignore
     public void testpmin2() {
+        // problem with number formatting
         assertEval("argv <- list(FALSE, c(1.01547865839261, 1.01252937204691, 1.00644625408792, 0.998699246049516, 0.989861830865133, 0.980229984263028, 0.969980509594864, 0.959229159804225, 0.948056660278026, 0.948056660278026, 0.936413637553504, 0.924430242566905, 0.924430242566905, 0.912012661079992, 0.912012661079992, 0.912012661079992, 0.912012661079992, 0.912012661079992, 0.912012661079992, 0.89856564301575, 0.89856564301575, 0.89856564301575, 0.89856564301575, 0.884221004526004, 0.884221004526004, 0.884221004526004, 0.884221004526004, 0.868846889674391, 0.852918138766346, 0.852918138766346, 0.852918138766346, 0.836013989965276, 0.836013989965276, 0.818281118997659, 0.818281118997659, 0.799674858806929, 0.78048190648179, 0.760752205123712, 0.740524405390135, 0.698688252548957, 0.677121358432204, 0.677121358432204, 0.677121358432204, 0.653968759838845, 0.630226345284056, 0.60591293760604, 0.5810405538867, 0.5810405538867, 0.554772713636871, 0.554772713636871, 0.526885054753327, 0.526885054753327, 0.497124929362659, 0.497124929362659, 0.465290373327728, 0.431410832191818, 0.395597572090297, 0.358012869967492, 0.358012869967492, 0.358012869967492, 0.390645999939295, 0.390645999939295, 1.00856963764107, 1.00691545377429, 1.00354783420184, 0.994430782349702, 0.989161076962549, 0.983568844113983, 0.971651869906627, 0.965403818059832, 0.958998025317496, 0.952453588123512, 0.945785731840592, 0.939006829762577, 0.932127100227826, 0.925155098145928, 0.918098070593368, 0.910962219832367, 0.903752901643838, 0.896474777439562, 0.889131932689408, 0.874266085562073, 0.866749125736792, 0.85917963981466, 0.85917963981466, 0.85917963981466, 0.851432533571458, 0.851432533571458, 0.835646571743332, 0.819657377450186, 0.811591248493136, 0.811591248493136, 0.803403072648503, 0.803403072648503, 0.803403072648503, 0.79500789222886, 0.79500789222886, 0.78647848620035, 0.777810139927498, 0.777810139927498, 0.768997769554365, 0.760132009504045, 0.751214427604144, 0.751214427604144, 0.751214427604144, 0.742042333451995, 0.742042333451995, 0.732706928458195, 0.723314130803801, 0.713865427684027, 0.713865427684027, 0.704242881823747, 0.704242881823747, 0.694438026993695, 0.684573363315093, 0.674650164742493, 0.664669564073024, 0.664669564073024, 0.664669564073024, 0.654342845821626, 0.643951412016272, 0.633496370097346, 0.633496370097346, 0.622814395282618, 0.622814395282618, 0.611712238653597, 0.600530813249145, 0.589271296091113, 0.577934661160654, 0.577934661160654, 0.554603983179207, 0.542813560886543, 0.530698712197854, 0.530698712197854, 0.518231810914377, 0.518231810914377, 0.518231810914377, 0.505091485230836, 0.491816896403255, 0.478408881208852, 0.464867758182769, 0.464867758182769, 0.450831087639633, 0.43663736059032, 0.422285766886131, 0.422285766886131, 0.407334269006221, 0.392187384239101, 0.376842383287708, 0.376842383287708, 0.36074886771613, 0.344393472477708, 0.327769800745284, 0.310869313273075, 0.293681131444043, 0.27619182464681, 0.258385252532011, 0.240242648154923, 0.221743435532848, 0.202868148187672, 0.183607543425597, 0.183607543425597, 0.16434288099768, 0.16434288099768, 0.16434288099768, 0.16434288099768, 1.01958384078021, 1.0158820929578, 1.00818641731953, 0.998355892450852, 0.98711678103063, 0.974844224342501, 0.961762390694789, 0.94801800556359, 0.933713296997721, 0.918922795982771, 0.918922795982771, 0.903505632185222, 0.887664218536847, 0.8714385967694, 0.854601072478364, 0.837400228461143, 0.81986117753083, 0.80200434269104, 0.783846415628184, 0.765401054645917, 0.746679400612251, 0.727690462294359, 0.70844140545579, 0.688937769124757, 0.669183625153216, 0.649181692191925, 0.628933411668998, 0.608438990755048, 0.608438990755048, 0.587078835123946, 0.565417411428399, 0.543452081149807, 0.521178337588507, 0.498589701519445, 0.475677565090786, 0.475677565090786, 0.451501204504207, 0.426861888982249, 0.401742325799741, 0.376120821121693, 0.349971441565183, 0.323265236972233, 0.323265236972233, 0.294966951140867, 0.265661696527275, 0.265661696527275, 0.24198035833067, 0.229359831745471, NA, NA), 1); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmin3() {
         assertEval("argv <- list(FALSE, c(19.7787405591752, 12504507.4953993, 12504507.4953993, 5.96190157728191e+41), 1); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmin4() {
         assertEval("argv <- list(FALSE, structure(c(2, 3, 4, 2, 2, 2), .Dim = c(3L, 2L), .Dimnames = list(NULL, c(\'a\', \'\'))), 1:7); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmin5() {
         assertEval("argv <- list(FALSE, structure(c(-2.30560410637911, -1.56788329848973, -0.885216282233891, -0.246592299284877, 0.350190802022645, 0.913941628350052, 1.44466017969734, 1.94895291106052), .Names = c(\'1\', \'2\', \'3\', \'4\', \'5\', \'6\', \'7\', \'8\')), 700); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmin6() {
         assertEval("argv <- list(FALSE, 1, structure(numeric(0), .Dim = c(4L, 0L))); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmin7() {
         assertEval("argv <- list(FALSE, FALSE, FALSE); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmin8() {
         assertEval("argv <- list(FALSE, FALSE); .Internal(pmin(argv[[1]], argv[[2]]))");
     }
 
     @Test
-    @Ignore
     public void testpmin9() {
         assertEval("argv <- list(FALSE, 48L, 19L); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
-    @Ignore
     public void testpmin10() {
         assertEval("argv <- list(FALSE, 1, 0.341867139159); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
     }
@@ -79,6 +71,7 @@ public class TestrGenBuiltinpmin extends TestBase {
     @Test
     @Ignore
     public void testpmin11() {
+        // problem with number formatting
         assertEval("argv <- list(FALSE, c(2.35405350797934e-06, 0.000210159024072429, 0.000257684187404011, 0.000981478332360736, 0.00105260958830543, 0.00124148072892802, 0.00132598801923585, 0.00156850331255678, 0.00225455732762676, 0.003795380309271, 0.00611494315340942, 0.0161395372907077, 0.0330242962313738, 0.0353834177611007, 0.0523699658057458, 0.068319089314331, 0.0705922565893261, 0.0880512860101142, 0.0940103983967277, 0.112979808322889, 0.211501681388388, 0.492273640304204, 0.605329775053071, 0.626223946736039, 0.739515289321684, 0.828110328240387, 0.86333312789587, 1.19065433061771, 1.89079625396729, 2.05849377808347, 2.20921371984431, 2.85600042559897, 3.04889487308354, 4.66068200259841, 4.83080935233713, 4.92175460488491, 5.31945286062773, 5.75155046407955, 5.78319462345744), 0.943789021783783); .Internal(pmin(argv[[1]], argv[[2]], argv[[3]]))");
     }
 }
-- 
GitLab