diff --git a/gcc/testsuite/gdc.dg/link.d b/gcc/testsuite/gdc.dg/link.d
index a8ca4ed5cb6..5efd0ad347f 100644
--- a/gcc/testsuite/gdc.dg/link.d
+++ b/gcc/testsuite/gdc.dg/link.d
@@ -1,4 +1,4 @@
-// { dg-do link { target d_runtime } }
+// { dg-do link { target d_runtime_has_std_library } }
 
 /******************************************/
 
diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d
index 484a9709bf3..7307e09a645 100644
--- a/gcc/testsuite/gdc.dg/runnable.d
+++ b/gcc/testsuite/gdc.dg/runnable.d
@@ -9,20 +9,6 @@ import core.stdc.stdio;
 import gcc.attribute;
 
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=2
-
-struct S
-{
-    string toString() { return "foo"; }
-}
-
-void test2()
-{
-    import std.string : format;
-    assert(format("%s", S()) == "foo");
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=4
 
@@ -33,35 +19,6 @@ void test4()
     static assert(!__traits(compiles, str.sort));
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=15
-
-class B
-{
-    class A { }
-    A a;
-}
-
-class C
-{
-    void visit(B b)
-    {
-        import std.algorithm : map;
-        auto as = [b.a];
-        as.map!(d => d);
-    }
-}
-
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=16
-
-void test16()
-{
-    import std.parallelism : taskPool;
-
-    taskPool.reduce!"a+b"([0, 1, 2, 3]);
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=17
 
@@ -99,59 +56,6 @@ void test17()
   (new ModuleWriter()).save ("test.0.mci");
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=18
-
-class C18
-{
-    struct Link
-    {
-        int x;
-        int y;
-    }
-
-    void sort_links()
-    {
-        import std.algorithm : sort;
-        import std.array : empty;
-        import std.exception : enforce;
-
-        enforce(!_link.empty);
-
-        bool lt(Link a, Link b)
-        {
-            if(a.x > b.x)
-                return false;
-            if(a.x < b.x)
-                return true;
-            if(a.y >= b.y)
-                return false;
-            else
-                return true;
-        }
-        sort!(lt)(_link);
-    }
-
-    this()
-    {
-        _link ~= Link(8, 3);
-        _link ~= Link(4, 7);
-        _link ~= Link(4, 6);
-        _link ~= Link(3, 7);
-        _link ~= Link(2, 7);
-        _link ~= Link(2, 2);
-        _link ~= Link(4, 1);
-    }
-
-    Link[] _link;
-}
-
-void test18()
-{
-    C18 foo = new C18;
-    foo.sort_links();
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=19
 
@@ -177,22 +81,6 @@ void test24()
         return;
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=29
-
-void test29()
-{
-    import std.string : format;
-    import std.conv : text;
-
-    string s;
-    for (auto i = 0; i < 100000; i++)
-    {
-        s = format("%d", i);
-        s = text(i);
-    }
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=31
 
@@ -499,54 +387,6 @@ void test51()
     assert (s.x == 0);
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=52
-
-class C52
-{
-    C52 a;
-
-    this()
-    {
-        printf("Construct: this=%p\n", cast(void*)this);
-        a = this;
-    }
-
-    bool check()
-    {
-        printf("Check: this=%p a=%p\n", cast(void*)this, cast(void*)a);
-        return this is a;
-    }
-}
-
-auto test52a()
-{
-    import std.conv, std.traits;
-
-    struct Scoped
-    {
-        void[__traits (classInstanceSize, C52) ] Scoped_store = void;
-
-        inout(C52) Scoped_payload() inout
-        {
-            void* alignedStore = cast(void*) Scoped_store.ptr;
-            return cast(inout (C52)) alignedStore;
-        }
-        alias Scoped_payload this;
-    }
-
-    Scoped result;
-    emplace!(Unqual!C52)(result.Scoped_store);
-    assert(result.Scoped_payload().check);
-    return result;
-}
-
-void test52()
-{
-    auto a1 = test52a();
-    assert(a1.Scoped_payload().check);
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=57
 
@@ -588,54 +428,6 @@ void test66()
 __vector(float[4]) d[2];  // ICE
 
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=71
-
-struct Leaf
-{
-    ubyte symbol;
-    ubyte codeLen;
-}
-
-struct CanonicalHuffman
-{
-    Leaf[] table;
-
-    void print()
-    {
-        import std.algorithm;
-        import std.range;
-
-        auto list = zip(iota(table.length), table.dup).array
-            .sort!((a, b) => a[1].symbol < b[1].symbol)
-            .uniq!((a, b) => (a[0] & (1 << a[1].codeLen) - 1) == (b[0] & (1 << b[1].codeLen) - 1));
-    }
-}
-
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=77
-
-void fun(ubyte[3] buf)
-{
-    import std.bitmanip : bigEndianToNative;
-    bigEndianToNative!ushort(buf[0..2]);
-}
-
-void test77()
-{
-    fun([1,2,3]);
-}
-
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=108
-
-@attribute("forceinline")
-void test108()
-{
-    import std.stdio : writeln;
-    writeln("Here");
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=115
 
@@ -657,21 +449,6 @@ void test115()
 
 immutable char C121 = void; // ICE
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=122
-
-void test122()
-{
-    import std.algorithm : map;
-    import std.parallelism : taskPool;
-    import std.range : iota;
-
-    immutable n = 10000;
-    enum delta = 1.0 / n;       // XBUG: was 'immutable delta' https://issues.dlang.org/show_bug.cgi?id=17092
-    immutable pi = 4.0 * delta * taskPool.reduce!"a + b"(
-        map!((int i) { immutable x = (i - 0.5) * delta; return 1.0 / (1.0 + x * x); })(iota(n)));
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=127
 
@@ -1584,20 +1361,14 @@ void test309()
 
 void main()
 {
-    test2();
     test4();
-    test16();
     test17();
-    test18();
     test35();
     test36();
     test43();
     test51();
-    test52();
     test57();
     test66();
-    test77();
-    test108();
     test115();
     test131();
     test133();
diff --git a/gcc/testsuite/gdc.dg/runnable2.d b/gcc/testsuite/gdc.dg/runnable2.d
new file mode 100644
index 00000000000..d9463e337c1
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/runnable2.d
@@ -0,0 +1,244 @@
+// { dg-do run { target { hw && d_runtime_has_std_library } } }
+
+module runnable;
+
+import core.stdc.stdio;
+import gcc.attribute;
+
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=2
+
+struct S
+{
+    string toString() { return "foo"; }
+}
+
+void test2()
+{
+    import std.string : format;
+    assert(format("%s", S()) == "foo");
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=15
+
+class B
+{
+    class A { }
+    A a;
+}
+
+class C
+{
+    void visit(B b)
+    {
+        import std.algorithm : map;
+        auto as = [b.a];
+        as.map!(d => d);
+    }
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=16
+
+void test16()
+{
+    import std.parallelism : taskPool;
+
+    taskPool.reduce!"a+b"([0, 1, 2, 3]);
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=18
+
+class C18
+{
+    struct Link
+    {
+        int x;
+        int y;
+    }
+
+    void sort_links()
+    {
+        import std.algorithm : sort;
+        import std.array : empty;
+        import std.exception : enforce;
+
+        enforce(!_link.empty);
+
+        bool lt(Link a, Link b)
+        {
+            if(a.x > b.x)
+                return false;
+            if(a.x < b.x)
+                return true;
+            if(a.y >= b.y)
+                return false;
+            else
+                return true;
+        }
+        sort!(lt)(_link);
+    }
+
+    this()
+    {
+        _link ~= Link(8, 3);
+        _link ~= Link(4, 7);
+        _link ~= Link(4, 6);
+        _link ~= Link(3, 7);
+        _link ~= Link(2, 7);
+        _link ~= Link(2, 2);
+        _link ~= Link(4, 1);
+    }
+
+    Link[] _link;
+}
+
+void test18()
+{
+    C18 foo = new C18;
+    foo.sort_links();
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=29
+
+void test29()
+{
+    import std.string : format;
+    import std.conv : text;
+
+    string s;
+    for (auto i = 0; i < 100000; i++)
+    {
+        s = format("%d", i);
+        s = text(i);
+    }
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=52
+
+class C52
+{
+    C52 a;
+
+    this()
+    {
+        printf("Construct: this=%p\n", cast(void*)this);
+        a = this;
+    }
+
+    bool check()
+    {
+        printf("Check: this=%p a=%p\n", cast(void*)this, cast(void*)a);
+        return this is a;
+    }
+}
+
+auto test52a()
+{
+    import std.conv, std.traits;
+
+    struct Scoped
+    {
+        void[__traits (classInstanceSize, C52) ] Scoped_store = void;
+
+        inout(C52) Scoped_payload() inout
+        {
+            void* alignedStore = cast(void*) Scoped_store.ptr;
+            return cast(inout (C52)) alignedStore;
+        }
+        alias Scoped_payload this;
+    }
+
+    Scoped result;
+    emplace!(Unqual!C52)(result.Scoped_store);
+    assert(result.Scoped_payload().check);
+    return result;
+}
+
+void test52()
+{
+    auto a1 = test52a();
+    assert(a1.Scoped_payload().check);
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=71
+
+struct Leaf
+{
+    ubyte symbol;
+    ubyte codeLen;
+}
+
+struct CanonicalHuffman
+{
+    Leaf[] table;
+
+    void print()
+    {
+        import std.algorithm;
+        import std.range;
+
+        auto list = zip(iota(table.length), table.dup).array
+            .sort!((a, b) => a[1].symbol < b[1].symbol)
+            .uniq!((a, b) => (a[0] & (1 << a[1].codeLen) - 1) == (b[0] & (1 << b[1].codeLen) - 1));
+    }
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=77
+
+void fun(ubyte[3] buf)
+{
+    import std.bitmanip : bigEndianToNative;
+    bigEndianToNative!ushort(buf[0..2]);
+}
+
+void test77()
+{
+    fun([1,2,3]);
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=108
+
+@attribute("forceinline")
+void test108()
+{
+    import std.stdio : writeln;
+    writeln("Here");
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=122
+
+void test122()
+{
+    import std.algorithm : map;
+    import std.parallelism : taskPool;
+    import std.range : iota;
+
+    immutable n = 10000;
+    enum delta = 1.0 / n;       // XBUG: was 'immutable delta' https://issues.dlang.org/show_bug.cgi?id=17092
+    immutable pi = 4.0 * delta * taskPool.reduce!"a + b"(
+        map!((int i) { immutable x = (i - 0.5) * delta; return 1.0 / (1.0 + x * x); })(iota(n)));
+}
+
+/******************************************/
+
+void main()
+{
+    test2();
+    test16();
+    test18();
+    test52();
+    test77();
+    test108();
+
+    printf("Success!\n");
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 3758bb3a91d..5704a2fc583 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -8069,6 +8069,21 @@ proc check_effective_target_d_runtime { } {
     }]
 }
 
+# Return 1 if the target provides the D standard library.
+
+proc check_effective_target_d_runtime_has_std_library { } {
+    return [check_no_compiler_messages d_runtime_has_std_library executable {
+	// D
+	module mod;
+
+	extern(C) int main() {
+	    import std.math;
+	    real function(real) pcos = &cos;
+	    return 0;
+	}
+    }]
+}
+
 # Return 1 if  target wchar_t is at least 4 bytes.
 
 proc check_effective_target_4byte_wchar_t { } {
diff --git a/libphobos/testsuite/libphobos.phobos/phobos.exp b/libphobos/testsuite/libphobos.phobos/phobos.exp
index 3d876acf27b..aad877c24c2 100644
--- a/libphobos/testsuite/libphobos.phobos/phobos.exp
+++ b/libphobos/testsuite/libphobos.phobos/phobos.exp
@@ -19,6 +19,11 @@ if { ![isnative] || ![is-effective-target static] } {
     return
 }
 
+# Skip running test if phobos was not built on the target.
+if { ![is-effective-target d_runtime_has_std_library] } {
+    return
+}
+
 # Gather a list of all tests.
 set tests [lsort [filter_libphobos_unittests [find $srcdir/../src "*.d"]]]
 
diff --git a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
index 43b9772d6f2..a00ecf11ac9 100644
--- a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
+++ b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
@@ -19,6 +19,11 @@ if { ![isnative] || ![is-effective-target shared] } {
     return
 }
 
+# Skip running test if phobos was not built on the target.
+if { ![is-effective-target d_runtime_has_std_library] } {
+    return
+}
+
 # Gather a list of all tests.
 set tests [lsort [filter_libphobos_unittests [find $srcdir/../src "*.d"]]]
 
