diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java
index e4eabf251c08f14a3b4c68cae04097fbc6f3fcd1..e8ba62ceb910f093217c88d5664abb3c49933115 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2015, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -430,27 +430,52 @@ public class GrepFunctions {
                             value = ix < 0 ? input : input.substring(0, ix) + replacement + input.substring(ix + pattern.length());
                         }
                     } else if (perl) {
-                        int offset = 0;
+                        int lastEndOffset = 0;
+                        int lastEndIndex = 0;
                         int[] ovector = new int[30];
                         int nmatch = 0;
                         int eflag = 0;
                         int lastEnd = -1;
+                        int[] fromByteMapping = getFromByteMapping(input); // non-null if it's
+                                                                           // necessary
+
                         StringBuffer sb = new StringBuffer();
-                        while (pcreRFFINode.exec(pcre.result, 0, input, offset, eflag, ovector) >= 0) {
+                        while (pcreRFFINode.exec(pcre.result, 0, input, lastEndOffset, eflag, ovector) >= 0) {
                             nmatch++;
-                            for (int j = offset; j < ovector[0]; j++) {
+
+                            // offset == byte position
+                            // index == character position
+                            int startOffset = ovector[0];
+                            int endOffset = ovector[1];
+                            int startIndex = (fromByteMapping != null) ? fromByteMapping[startOffset] : startOffset;
+                            int endIndex = (fromByteMapping != null) ? fromByteMapping[endOffset] : endOffset;
+
+                            for (int j = lastEndIndex; j < startIndex; j++) {
                                 sb.append(input.charAt(j));
                             }
-                            if (ovector[1] > lastEnd) {
-                                pcreStringAdj(sb, input, replacement, ovector);
-                                lastEnd = ovector[1];
+                            if (endOffset > lastEnd) {
+                                pcreStringAdj(sb, input, replacement, ovector, fromByteMapping);
+                                lastEnd = endOffset;
                             }
-                            offset = ovector[1];
-                            if (offset >= input.length() || !gsub) {
+                            lastEndIndex = endIndex;
+                            lastEndOffset = endOffset;
+                            if (lastEndIndex >= input.length() || !gsub) {
                                 break;
                             }
-                            if (ovector[0] == ovector[1]) {
-                                sb.append(input.charAt(offset++));
+                            if (startOffset == endOffset) {
+                                sb.append(input.charAt(lastEndIndex));
+                                if (fromByteMapping != null) {
+                                    for (int j = lastEndOffset + 1; j < fromByteMapping.length; j++) {
+                                        if (fromByteMapping[j] > 0) {
+                                            lastEndOffset = j;
+                                            lastEndIndex = fromByteMapping[lastEndOffset];
+                                            break;
+                                        }
+                                    }
+                                } else {
+                                    lastEndOffset++;
+                                    lastEndIndex++;
+                                }
                             }
                             eflag |= PCRERFFI.NOTBOL;
                         }
@@ -458,7 +483,7 @@ public class GrepFunctions {
                             value = input;
                         } else {
                             /* copy the tail */
-                            for (int j = offset; j < input.length(); j++) {
+                            for (int j = lastEndIndex; j < input.length(); j++) {
                                 sb.append(input.charAt(j));
                             }
                             value = sb.toString();
@@ -558,7 +583,7 @@ public class GrepFunctions {
             return nonEmpty;
         }
 
-        private static void pcreStringAdj(StringBuffer sb, String input, String repl, int[] ovector) {
+        private static void pcreStringAdj(StringBuffer sb, String input, String repl, int[] ovector, int[] fromByteMapping) {
             boolean upper = false;
             boolean lower = false;
             int px = 0;
@@ -568,7 +593,9 @@ public class GrepFunctions {
                     char p1 = repl.charAt(px++);
                     if (p1 >= '1' && p1 <= '9') {
                         int k = p1 - '0';
-                        for (int i = ovector[2 * k]; i < ovector[2 * k + 1]; i++) {
+                        int startIndex = (fromByteMapping != null) ? fromByteMapping[ovector[2 * k]] : ovector[2 * k];
+                        int endIndex = (fromByteMapping != null) ? fromByteMapping[ovector[2 * k + 1]] : ovector[2 * k + 1];
+                        for (int i = startIndex; i < endIndex; i++) {
                             char c = input.charAt(i);
                             sb.append(upper ? Character.toUpperCase(c) : (lower ? Character.toLowerCase(c) : c));
                         }
@@ -1203,7 +1230,7 @@ public class GrepFunctions {
                         if (perl) {
                             resultItem = splitPerl(data, pcreSplits[i % splits.length]);
                         } else {
-                            resultItem = splitIntl(data, currentSplit);
+                            resultItem = splitIntl(data, currentSplit, fixed);
                         }
                         if (resultItem.getLength() == 0) {
                             if (fixed) {
@@ -1234,9 +1261,36 @@ public class GrepFunctions {
             }
         }
 
-        private static RStringVector splitIntl(String input, String separator) {
+        private static RStringVector splitIntl(String input, String separator, boolean fixed) {
             assert !RRuntime.isNA(input);
-            return RDataFactory.createStringVector(input.split(separator), true);
+
+            if (fixed) {
+                ArrayList<String> matches = new ArrayList<>();
+                int idx = input.indexOf(separator);
+                if (idx < 0) {
+                    return RDataFactory.createStringVector(input);
+                }
+                int lastIdx = 0;
+                while (idx > -1) {
+                    matches.add(input.substring(lastIdx, idx));
+                    lastIdx = idx + separator.length();
+                    if (lastIdx > input.length()) {
+                        break;
+                    }
+                    idx = input.indexOf(separator, lastIdx);
+                }
+                String m = input.substring(lastIdx);
+                if (!m.isEmpty()) {
+                    matches.add(m);
+                }
+                return RDataFactory.createStringVector(matches.toArray(new String[matches.size()]), false);
+            } else {
+                if (input.equals(separator)) {
+                    return RDataFactory.createStringVector("");
+                } else {
+                    return RDataFactory.createStringVector(input.split(separator), true);
+                }
+            }
         }
 
         private static RStringVector emptySplitIntl(String input) {
@@ -1274,56 +1328,56 @@ public class GrepFunctions {
             matches.toArray(result);
             return RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR);
         }
+    }
 
-        private static int getByteLength(String data) {
-            int byteLength = 0;
-            int pos = 0;
-            while (pos < data.length()) {
-                char c = data.charAt(pos);
-                if (c < 128) {
-                    byteLength++;
-                } else if (c < 2048) {
-                    byteLength += 2;
+    private static int getByteLength(String data) {
+        int byteLength = 0;
+        int pos = 0;
+        while (pos < data.length()) {
+            char c = data.charAt(pos);
+            if (c < 128) {
+                byteLength++;
+            } else if (c < 2048) {
+                byteLength += 2;
+            } else {
+                if (Character.isHighSurrogate(c)) {
+                    byteLength += 4;
+                    pos++;
                 } else {
-                    if (Character.isHighSurrogate(c)) {
-                        byteLength += 4;
-                        pos++;
-                    } else {
-                        byteLength += 3;
-                    }
+                    byteLength += 3;
                 }
-                pos++;
             }
-            return byteLength;
+            pos++;
         }
+        return byteLength;
+    }
 
-        private static int[] getFromByteMapping(String data) {
-            int byteLength = getByteLength(data);
-            if (byteLength == data.length()) {
-                return null;
-            }
-            int[] result = new int[byteLength + 1];
-            byteLength = 0;
-            int pos = 0;
-            while (pos < data.length()) {
-                result[byteLength] = pos;
-                char c = data.charAt(pos);
-                if (c < 128) {
-                    byteLength++;
-                } else if (c < 2048) {
-                    byteLength += 2;
+    private static int[] getFromByteMapping(String data) {
+        int byteLength = getByteLength(data);
+        if (byteLength == data.length()) {
+            return null;
+        }
+        int[] result = new int[byteLength + 1];
+        byteLength = 0;
+        int pos = 0;
+        while (pos < data.length()) {
+            result[byteLength] = pos;
+            char c = data.charAt(pos);
+            if (c < 128) {
+                byteLength++;
+            } else if (c < 2048) {
+                byteLength += 2;
+            } else {
+                if (Character.isHighSurrogate(c)) {
+                    byteLength += 4;
+                    pos++;
                 } else {
-                    if (Character.isHighSurrogate(c)) {
-                        byteLength += 4;
-                        pos++;
-                    } else {
-                        byteLength += 3;
-                    }
+                    byteLength += 3;
                 }
-                pos++;
             }
-            result[byteLength] = pos;
-            return result;
+            pos++;
         }
+        result[byteLength] = pos;
+        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 d79ff606a4e607bca7bc573d37156de8ec40df4e..ffa7c051833decdef5b9261fb34927a0b770d61c 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
@@ -21888,6 +21888,10 @@ Error: invalid 'pattern' argument
 #{ .Internal(grep(character(), "7", F, F, F, F, F, F)) }
 Error: invalid 'pattern' argument
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_grep.testGrep#Ignored.Unknown#
+#{ grep('^ *$', ' \n') }
+integer(0)
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_grep.testGrep#
 #{ txt<-c("1+1i", "7", "42.1", "7+42i"); grep("[0-9].*[-+][0-9].*i$", txt) }
 [1] 1 4
@@ -22114,6 +22118,18 @@ In gsub("a", "aa", "prAgue alley", fixed = TRUE, ignore.case = TRUE) :
 #{ gsub("h","", c("hello", "hi", "bye"), fixed=TRUE) }
 [1] "ello" "i"    "bye"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_gsub.testGsub#
+#{ gsub(pattern = 'a*', replacement = 'x', x = 'ÄaaaaÄ', perl = TRUE) }
+[1] "xÄxÄx"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_gsub.testGsub#
+#{ gsub(pattern = 'a*', replacement = 'x', x = 'ÄaÄ', perl = TRUE) }
+[1] "xÄxÄx"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_gsub.testGsub#Ignored.Unknown#
+#{ gsub(pattern = 'Ä*', replacement = 'x', x = 'aÄÄÄÄÄb', perl = TRUE) }
+[1] "xaxbx"
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_gsub.testgsub1#
 #argv <- list('([[:alnum:]])--([[:alnum:]])', '\\1-\\2', 'Date-Time Classes', FALSE, FALSE, FALSE, FALSE); .Internal(gsub(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))
 [1] "Date-Time Classes"
@@ -48367,6 +48383,30 @@ character(0)
 #{ strrep(c("A", "B", "C"), 1 : 3) }
 [1] "A"   "BB"  "CCC"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit('1', '1', fixed=FALSE)
+[[1]]
+[1] ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit('1', '1', fixed=TRUE)
+[[1]]
+[1] ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit('11', '11', fixed=FALSE)
+[[1]]
+[1] ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit('11', '11', fixed=TRUE)
+[[1]]
+[1] ""
+
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
 #strsplit('foo bar baz', '[f z]', perl=TRUE)
 [[1]]
@@ -48393,6 +48433,138 @@ character(0)
 [1] "Ä" "Ä"
 
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit('Ä', 'Ä', fixed=FALSE)
+[[1]]
+[1] ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit('Ä', 'Ä', fixed=TRUE)
+[[1]]
+[1] ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit('ÄÄ', 'Ä', fixed=FALSE)
+[[1]]
+[1] "" ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit('ÄÄ', 'Ä', fixed=TRUE)
+[[1]]
+[1] "" ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('1', ''), c('1', ''), fixed=FALSE)
+[[1]]
+[1] ""
+
+[[2]]
+character(0)
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('1', ''), c('1', ''), fixed=TRUE)
+[[1]]
+[1] ""
+
+[[2]]
+character(0)
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('1', '11'), c('1', '11'), fixed=FALSE)
+[[1]]
+[1] ""
+
+[[2]]
+[1] ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('1', '11'), c('1', '11'), fixed=TRUE)
+[[1]]
+[1] ""
+
+[[2]]
+[1] ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('1', 'b'), c('1', 'b'), fixed=FALSE)
+[[1]]
+[1] ""
+
+[[2]]
+[1] ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('1', 'b'), c('1', 'b'), fixed=TRUE)
+[[1]]
+[1] ""
+
+[[2]]
+[1] ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('111', '1'), c('111', '1'), fixed=FALSE)
+[[1]]
+[1] ""
+
+[[2]]
+[1] ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('111', '1'), c('111', '1'), fixed=TRUE)
+[[1]]
+[1] ""
+
+[[2]]
+[1] ""
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('a1a', 'a1b'), '1', fixed=FALSE)
+[[1]]
+[1] "a" "a"
+
+[[2]]
+[1] "a" "b"
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('a1a', 'a1b'), '1', fixed=TRUE)
+[[1]]
+[1] "a" "a"
+
+[[2]]
+[1] "a" "b"
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('a1a', 'a1b'), c('1', '1'), fixed=FALSE)
+[[1]]
+[1] "a" "a"
+
+[[2]]
+[1] "a" "b"
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit(c('a1a', 'a1b'), c('1', '1'), fixed=TRUE)
+[[1]]
+[1] "a" "a"
+
+[[2]]
+[1] "a" "b"
+
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
 #{ .Internal(strsplit("7", 42, F, F, F)) }
 Error: non-character argument
@@ -48764,6 +48936,10 @@ Error: invalid 'pattern' argument
 #{ sub('[[:space:]]+$', '', 'R (>= 3.0.3)  ') }
 [1] "R (>= 3.0.3)"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_sub.testSub#
+#{ sub('\\s*$', '', 'Ä', perl=TRUE) }
+[1] "Ä"
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_sub.testSub#
 #{ sub('^([1[:alpha:].]+).*$', '\\1', '1R.ff (>= 3.0.3)') }
 [1] "1R.ff"
@@ -48824,6 +49000,18 @@ Error: invalid 'pattern' argument
 #{ sub('^[[:space:]]*(.*)', '\\1', 'R (>= 3.0.3)') }
 [1] "R (>= 3.0.3)"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_sub.testSub#
+#{ sub(pattern = 'a*', replacement = 'x', x = 'ÄaaaaÄ', perl = TRUE) }
+[1] "xÄaaaaÄ"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_sub.testSub#
+#{ sub(pattern = 'a*', replacement = 'x', x = 'ÄaÄ', perl = TRUE) }
+[1] "xÄaÄ"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_sub.testSub#Ignored.Unknown#
+#{ sub(pattern = 'Ä*', replacement = 'x', x = 'aÄÄÄÄÄb', perl = TRUE) }
+[1] "xaÄÄÄÄÄb"
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_sub.testsub1#
 #argv <- list('^..dfd.', '', c('aa', '..dfd.row.names'), FALSE, FALSE, FALSE, FALSE); .Internal(sub(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))
 [1] "aa"        "row.names"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_grep.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_grep.java
index c3b9ada54787a3f1327676af89aff57ee31372d6..29f31b22de0b47d61c6d3c54e56641d577185d63 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_grep.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_grep.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.
  */
@@ -87,6 +87,9 @@ public class TestBuiltin_grep extends TestBase {
         assertEval("{ .Internal(grep(character(), \"7\", F, F, F, F, F, F)) }");
         assertEval("{ .Internal(grep(\"7\", 7, F, F, F, F, F, F)) }");
 
+        // Expected output: integer(0)
+        // FastR output: [1] 1
+        assertEval(Ignored.Unknown, "{ grep('^ *$', ' \\n') }");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_gsub.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_gsub.java
index 3f8abf76cf0e6cf55490d592b7e2fc4ebb83e570..bb252920c177ca247dcb87a4b837234121924516 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_gsub.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_gsub.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.
  */
@@ -186,5 +186,12 @@ public class TestBuiltin_gsub extends TestBase {
         assertEval("{ .Internal(gsub(\"7\", 42, \"7\", F, F, F, F)) }");
         assertEval("{ .Internal(gsub(\"7\", character(), \"7\", F, F, F, F)) }");
         assertEval("{ .Internal(gsub(\"7\", \"42\", 7, F, F, F, F)) }");
+
+        assertEval("{ gsub(pattern = 'a*', replacement = 'x', x = 'ÄaÄ', perl = TRUE) }");
+        assertEval("{ gsub(pattern = 'a*', replacement = 'x', x = 'ÄaaaaÄ', perl = TRUE) }");
+
+        // Expected output: [1] "xaxbx"
+        // FastR output: [1] "axxxxxb"
+        assertEval(Ignored.Unknown, "{ gsub(pattern = 'Ä*', replacement = 'x', x = 'aÄÄÄÄÄb', perl = TRUE) }");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strsplit.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strsplit.java
index f6d29dc8ce187711d5ca431f2ccac8c2555620b8..5e0ec4da3093c056a156f131e4ff324d97eefc4d 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strsplit.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strsplit.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.
  */
@@ -121,5 +121,30 @@ public class TestBuiltin_strsplit extends TestBase {
         assertEval("strsplit('oo bar baz', '[f z]', perl=TRUE)");
         assertEval("strsplit('foo \u1010ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄbar baz ', '[f z]', perl=TRUE)");
         assertEval("strsplit('Ä Ä', '[ ]', perl=TRUE)");
+
+        assertEval("strsplit('1', '1', fixed=TRUE)");
+        assertEval("strsplit('11', '11', fixed=TRUE)");
+        assertEval("strsplit(c('1', '11'), c('1', '11'), fixed=TRUE)");
+        assertEval("strsplit('Ä', 'Ä', fixed=TRUE)");
+        assertEval("strsplit('ÄÄ', 'Ä', fixed=TRUE)");
+
+        assertEval("strsplit('1', '1', fixed=FALSE)");
+        assertEval("strsplit('11', '11', fixed=FALSE)");
+        assertEval("strsplit(c('1', '11'), c('1', '11'), fixed=FALSE)");
+        assertEval("strsplit('Ä', 'Ä', fixed=FALSE)");
+        assertEval("strsplit('ÄÄ', 'Ä', fixed=FALSE)");
+
+        assertEval("strsplit(c('111', '1'), c('111', '1'), fixed=TRUE)");
+        assertEval("strsplit(c('1', ''), c('1', ''), fixed=TRUE)");
+        assertEval("strsplit(c('1', 'b'), c('1', 'b'), fixed=TRUE)");
+        assertEval("strsplit(c('a1a', 'a1b'), c('1', '1'), fixed=TRUE)");
+        assertEval("strsplit(c('a1a', 'a1b'), '1', fixed=TRUE)");
+
+        assertEval("strsplit(c('111', '1'), c('111', '1'), fixed=FALSE)");
+        assertEval("strsplit(c('1', ''), c('1', ''), fixed=FALSE)");
+        assertEval("strsplit(c('1', 'b'), c('1', 'b'), fixed=FALSE)");
+        assertEval("strsplit(c('a1a', 'a1b'), c('1', '1'), fixed=FALSE)");
+        assertEval("strsplit(c('a1a', 'a1b'), '1', fixed=FALSE)");
+
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sub.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sub.java
index 1a6d875d9a3b5ef7e2081b0ecba6042601e96ac7..9dc30129fa86232485473ccea19d4092effe7c7c 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sub.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sub.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.
  */
@@ -148,5 +148,13 @@ public class TestBuiltin_sub extends TestBase {
         assertEval("{ .Internal(sub(\"7\", character(), \"7\", F, F, F, F)) }");
         assertEval("{ .Internal(sub(\"7\", \"42\", 7, F, F, F, F)) }");
 
+        assertEval("{ sub('\\\\s*$', '', 'Ä', perl=TRUE) }");
+
+        assertEval("{ sub(pattern = 'a*', replacement = 'x', x = 'ÄaÄ', perl = TRUE) }");
+        assertEval("{ sub(pattern = 'a*', replacement = 'x', x = 'ÄaaaaÄ', perl = TRUE) }");
+
+        // Expected output: [1] "xaÄÄÄÄÄb"
+        // FastR output: [1] "axÄÄÄÄb"
+        assertEval(Ignored.Unknown, "{ sub(pattern = 'Ä*', replacement = 'x', x = 'aÄÄÄÄÄb', perl = TRUE) }");
     }
 }