diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Max.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Max.java index 34cc91da913a21f10c0e1764f45eedf4609d537b..ce41444d9eea5376957d227c1d7c315b486fc9bd 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Max.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Max.java @@ -43,7 +43,7 @@ import com.oracle.truffle.r.runtime.ops.BinaryArithmetic; public abstract class Max extends RBuiltinNode.Arg2 { private static final ReduceSemantics semantics = new ReduceSemantics(RRuntime.INT_MIN_VALUE, Double.NEGATIVE_INFINITY, false, RError.Message.NO_NONMISSING_MAX, - RError.Message.NO_NONMISSING_MAX_NA, false, true); + RError.Message.NO_NONMISSING_MAX_NA, null, false, true, true); @Child private UnaryArithmeticReduceNode reduce = UnaryArithmeticReduceNodeGen.create(semantics, BinaryArithmetic.MAX); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Min.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Min.java index ca072450b4dc9a90a731ddde7b067b3c89b1bbb3..7be389e2d1f9a0d5c6dd8173392cb9134c48f45f 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Min.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Min.java @@ -43,7 +43,7 @@ import com.oracle.truffle.r.runtime.ops.BinaryArithmetic; public abstract class Min extends RBuiltinNode.Arg2 { private static final ReduceSemantics semantics = new ReduceSemantics(RRuntime.INT_MAX_VALUE, Double.POSITIVE_INFINITY, false, RError.Message.NO_NONMISSING_MIN, - RError.Message.NO_NONMISSING_MIN_NA, false, true); + RError.Message.NO_NONMISSING_MIN_NA, null, false, true, true); @Child private UnaryArithmeticReduceNode reduce = UnaryArithmeticReduceNodeGen.create(semantics, BinaryArithmetic.MIN); 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 6350ec5ad7a4bccc759ca9235f1228849feb82fb..4dd253311b7c9e9d38b53349e1821f391d4225f7 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 @@ -341,7 +341,7 @@ public abstract class PMinMax extends RBuiltinNode.Arg2 { public abstract static class PMax extends PMinMax { public PMax() { - super(new ReduceSemantics(RRuntime.INT_MIN_VALUE, Double.NEGATIVE_INFINITY, false, RError.Message.NO_NONMISSING_MAX, RError.Message.NO_NONMISSING_MAX_NA, false, true), + super(new ReduceSemantics(RRuntime.INT_MIN_VALUE, Double.NEGATIVE_INFINITY, false, RError.Message.NO_NONMISSING_MAX, RError.Message.NO_NONMISSING_MAX_NA, null, false, true, true), BinaryArithmetic.MAX); } @@ -354,7 +354,7 @@ public abstract class PMinMax extends RBuiltinNode.Arg2 { public abstract static class PMin extends PMinMax { public PMin() { - super(new ReduceSemantics(RRuntime.INT_MAX_VALUE, Double.POSITIVE_INFINITY, false, RError.Message.NO_NONMISSING_MIN, RError.Message.NO_NONMISSING_MIN_NA, false, true), + super(new ReduceSemantics(RRuntime.INT_MAX_VALUE, Double.POSITIVE_INFINITY, false, RError.Message.NO_NONMISSING_MIN, RError.Message.NO_NONMISSING_MIN_NA, null, false, true, true), BinaryArithmetic.MIN); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java index 828b494e5f055c69e8409e6e350d7f38f7283efa..9395c6682ce00d2918381fb53a963329567b0bf6 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java @@ -45,9 +45,9 @@ import com.oracle.truffle.r.runtime.ops.BinaryArithmetic; public abstract class Range extends RBuiltinNode.Arg3 { private static final ReduceSemantics minSemantics = new ReduceSemantics(RRuntime.INT_MAX_VALUE, Double.POSITIVE_INFINITY, false, RError.Message.NO_NONMISSING_MIN, - RError.Message.NO_NONMISSING_MIN_NA, false, true); + RError.Message.NO_NONMISSING_MIN_NA, null, false, true, true); private static final ReduceSemantics maxSemantics = new ReduceSemantics(RRuntime.INT_MIN_VALUE, Double.NEGATIVE_INFINITY, false, RError.Message.NO_NONMISSING_MAX, - RError.Message.NO_NONMISSING_MAX_NA, false, true); + RError.Message.NO_NONMISSING_MAX_NA, null, false, true, true); @Child private UnaryArithmeticReduceNode minReduce = UnaryArithmeticReduceNodeGen.create(minSemantics, BinaryArithmetic.MIN); @Child private UnaryArithmeticReduceNode maxReduce = UnaryArithmeticReduceNodeGen.create(maxSemantics, BinaryArithmetic.MAX); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sum.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sum.java index a370cef06fe890197ca0c947c433846f97bcfdea..00fbadeb93c2ed6e3bb8c7923f10a38ebf9865c7 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sum.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sum.java @@ -54,7 +54,7 @@ public abstract class Sum extends RBuiltinNode.Arg2 { protected static final boolean FULL_PRECISION = FastROptions.FullPrecisionSum.getBooleanValue(); - private static final ReduceSemantics semantics = new ReduceSemantics(0, 0.0, true, null, null, Message.INTEGER_OVERFLOW_USE_SUM_NUMERIC, true, false); + private static final ReduceSemantics semantics = new ReduceSemantics(0, 0.0, true, null, null, Message.INTEGER_OVERFLOW_USE_SUM_NUMERIC, true, false, false); @Child private UnaryArithmeticReduceNode reduce = UnaryArithmeticReduceNodeGen.create(semantics, BinaryArithmetic.ADD); 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 f54f392a94f0cc3c598686beb57675199610c5b3..0a6de6adf110b05bab7041b83e8b602bd89b1389 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 @@ -72,6 +72,7 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { protected final ReduceSemantics semantics; protected final boolean supportString; protected final boolean supportComplex; + protected final boolean useDoubleStartForEmptyVector; private final NACheck na = NACheck.create(); private final ConditionProfile naRmProfile = ConditionProfile.createBinaryProfile(); @@ -82,6 +83,7 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { this.arithmetic = factory.createOperation(); this.supportString = semantics.supportString; this.supportComplex = semantics.supportComplex; + this.useDoubleStartForEmptyVector = semantics.useDoubleStartForEmptyVector; } private String handleString(RStringVector operand, boolean naRm, boolean finite, int offset) { @@ -200,6 +202,14 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { } } + @Specialization(guards = {"useDoubleStartForEmptyVector", "operand.getLength() == 0"}) + protected double doIntVectorEmpty(@SuppressWarnings("unused") RIntVector operand, + @SuppressWarnings("unused") boolean naRm, + @SuppressWarnings("unused") boolean finite) { + emptyWarning(); + return semantics.getDoubleStart(); + } + @Specialization protected int doIntVector(RIntVector operand, boolean naRm, boolean finite) { RBaseNode.reportWork(this, operand.getLength()); @@ -267,6 +277,14 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { return result; } + @Specialization(guards = {"useDoubleStartForEmptyVector", "operand.getLength() == 0"}) + protected double doLogicalVectorEmpty(@SuppressWarnings("unused") RLogicalVector operand, + @SuppressWarnings("unused") boolean naRm, + @SuppressWarnings("unused") boolean finite) { + emptyWarning(); + return semantics.getDoubleStart(); + } + @Specialization protected int doLogicalVector(RLogicalVector operand, boolean naRm, @SuppressWarnings("unused") boolean finite) { RBaseNode.reportWork(this, operand.getLength()); @@ -298,6 +316,14 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { return result; } + @Specialization(guards = {"useDoubleStartForEmptyVector", "operand.getLength() == 0"}) + protected double doIntSequenceEmpty(@SuppressWarnings("unused") RIntSequence operand, + @SuppressWarnings("unused") boolean naRm, + @SuppressWarnings("unused") boolean finite) { + emptyWarning(); + return semantics.getDoubleStart(); + } + @Specialization protected int doIntSequence(RIntSequence operand, @SuppressWarnings("unused") boolean naRm, @SuppressWarnings("unused") boolean finite) { RBaseNode.reportWork(this, operand.getLength()); @@ -421,9 +447,10 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { private final RError.Message naResultWarning; private final boolean supportComplex; private final boolean supportString; + private final boolean useDoubleStartForEmptyVector; public ReduceSemantics(int intStart, double doubleStart, boolean nullInt, RError.Message emptyWarning, RError.Message emptyWarningCharacter, RError.Message naResultWarning, - boolean supportComplex, boolean supportString) { + boolean supportComplex, boolean supportString, boolean useDoubleStartForEmptyVector) { this.intStart = intStart; this.doubleStart = doubleStart; this.nullInt = nullInt; @@ -432,10 +459,7 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { this.naResultWarning = naResultWarning; this.supportComplex = supportComplex; this.supportString = supportString; - } - - public ReduceSemantics(int intStart, double doubleStart, boolean nullInt, RError.Message emptyWarning, RError.Message emptyWarningCharacter, boolean supportComplex, boolean supportString) { - this(intStart, doubleStart, nullInt, emptyWarning, emptyWarningCharacter, null, supportComplex, supportString); + this.useDoubleStartForEmptyVector = useDoubleStartForEmptyVector; } public int getIntStart() { @@ -465,6 +489,10 @@ public abstract class UnaryArithmeticReduceNode extends RBaseNode { public RError.Message getNAResultWarning() { return naResultWarning; } + + public boolean isUseDoubleStartForEmptyVector() { + return useDoubleStartForEmptyVector; + } } private static final class MultiElemStringHandlerNode extends RBaseNode { 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 2ef82b83787b10a5a3b9d7ef72082dc4572a1fe0..d3334b70c56dba338a29ab5b440a8725a577cf75 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 @@ -36185,18 +36185,30 @@ In max(double()) : no non-missing arguments to max; returning -Inf Warning message: In max(double(0)) : no non-missing arguments to max; returning -Inf -##com.oracle.truffle.r.test.builtins.TestBuiltin_max.testMaximum#Ignored.ImplementationError# +##com.oracle.truffle.r.test.builtins.TestBuiltin_max.testMaximum# #{ max(integer()) } [1] -Inf Warning message: In max(integer()) : no non-missing arguments to max; returning -Inf -##com.oracle.truffle.r.test.builtins.TestBuiltin_max.testMaximum#Ignored.ImplementationError# +##com.oracle.truffle.r.test.builtins.TestBuiltin_max.testMaximum# #{ max(integer(0)) } [1] -Inf Warning message: In max(integer(0)) : no non-missing arguments to max; returning -Inf +##com.oracle.truffle.r.test.builtins.TestBuiltin_max.testMaximum# +#{ max(logical(0)) } +[1] -Inf +Warning message: +In max(logical(0)) : no non-missing arguments to max; returning -Inf + +##com.oracle.truffle.r.test.builtins.TestBuiltin_max.testMaximum# +#{ max(seq_len(0)) } +[1] -Inf +Warning message: +In max(seq_len(0)) : no non-missing arguments to max; returning -Inf + ##com.oracle.truffle.r.test.builtins.TestBuiltin_max.testmax1# #argv <- list(10L, 1L);max(argv[[1]],argv[[2]]); [1] 10 diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_max.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_max.java index f8cf0fa9290e9d365144f4525544fb88e1679f04..a06988258f0a840ece5e0a48bd64118334cf823e 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_max.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_max.java @@ -214,15 +214,15 @@ public class TestBuiltin_max extends TestBase { assertEval("max(v<-42)"); - // FIXME -2147483647 returned instead of -Inf - assertEval(Ignored.ImplementationError, "{ max(integer(0)) }"); - // FIXME -2147483647 returned instead of -Inf - assertEval(Ignored.ImplementationError, "{ max(integer()) }"); + assertEval("{ max(integer(0)) }"); + assertEval("{ max(integer()) }"); assertEval("{ max(as.double(NA), na.rm=TRUE) }"); // FIXME -2147483647 returned instead of -Inf assertEval(Ignored.ImplementationError, "{ max(as.integer(NA), na.rm=TRUE) }"); // FIXME -2147483647 returned instead of -Inf assertEval(Ignored.ImplementationError, "{ max(as.integer(NA), as.integer(NA), na.rm=TRUE) }"); + assertEval("{ max(logical(0)) }"); + assertEval("{ max(seq_len(0)) }"); assertEval("max(c(1,NA,2), na.rm=NA)"); }