This was split out from patch 9/14.  Added test directories for ASAN
and LTO tests.

Regards
Iain.

---
diff --git a/gcc/testsuite/gdc.dg/asan/asan.exp b/gcc/testsuite/gdc.dg/asan/asan.exp
new file mode 100644
index 00000000000..83bff4693e7
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/asan/asan.exp
@@ -0,0 +1,32 @@
+#   Copyright (C) 2017 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib gdc-dg.exp
+load_lib asan-dg.exp
+
+# Initialize `dg'.
+dg-init
+asan_init
+
+# Main loop.
+if [check_effective_target_fsanitize_address] {
+  gdc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.d]] "" ""
+}
+
+# All done.
+asan_finish
+dg-finish
diff --git a/gcc/testsuite/gdc.dg/asan/gdc272.d b/gcc/testsuite/gdc.dg/asan/gdc272.d
new file mode 100644
index 00000000000..c3de64b4c82
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/asan/gdc272.d
@@ -0,0 +1,16 @@
+/* { dg-options "-fsanitize=address" } */
+/* { dg-do compile } */
+
+module asantests;
+
+
+/******************************************/
+
+// Bug 272
+
+extern(C) void my_memcmp(const(void) *s1, const(void) *s2);
+
+void bug(const(char)* p)
+{
+        my_memcmp(p, "__FILE__".ptr);
+}
diff --git a/gcc/testsuite/gdc.dg/dg.exp b/gcc/testsuite/gdc.dg/dg.exp
new file mode 100644
index 00000000000..736d09ed599
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/dg.exp
@@ -0,0 +1,50 @@
+#   Copyright (C) 2017 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gdc-dg.exp
+
+# The default option list can be overridden by
+# TORTURE_OPTIONS="{ { list1 } ... { listN } }"
+
+if ![info exists TORTURE_OPTIONS] {
+    set TORTURE_OPTIONS [list \
+        { -O0 } { -O1 } { -O2 } { -O3 } { -Os } \
+        { -O0 -frelease } { -O0 -g } { -O0 -frelease -g } \
+        { -O1 -frelease } { -O1 -g } { -O1 -frelease -g } \
+        { -O2 -frelease } { -O2 -g } { -O2 -frelease -g } \
+        { -O3 -frelease } { -O3 -g } { -O3 -frelease -g } \
+        { -Os -frelease } { -Os -g } { -Os -frelease -g }]
+}
+
+# Initialize `dg'.
+dg-init
+
+# Initialize use of torture lists.
+torture-init
+set-torture-options $TORTURE_OPTIONS
+
+# Main loop.
+gdc-dg-runtest [lsort \
+       [glob -nocomplain $srcdir/$subdir/*.d ] ] "" ""
+
+# Finalize use of torture lists.
+torture-finish
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gdc.dg/gdc170.d b/gcc/testsuite/gdc.dg/gdc170.d
new file mode 100644
index 00000000000..8ad73c5bad6
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc170.d
@@ -0,0 +1,18 @@
+// { dg-options "-I $srcdir/gdc.dg" }
+import imports.gdc170a;
+
+void main()
+{
+    foo!void.foo1!void();
+    foo!void.foo2!void();
+    foo!void.foo3();
+    foo!void.foo3!void();
+    foo!void.foo4();
+    foo!void.foo4!void();
+    foo!void.foo5!void(null);
+    foo!void.foo6!void(null);
+    foo!void.foo7(null);
+    foo!void.foo7!void(null);
+    foo!void.foo8(null);
+    foo!void.foo8!void(null);
+}
diff --git a/gcc/testsuite/gdc.dg/gdc204.d b/gcc/testsuite/gdc.dg/gdc204.d
new file mode 100644
index 00000000000..de90766da0a
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc204.d
@@ -0,0 +1,9 @@
+interface I204
+{
+      void f();
+}
+
+class C204 : I204
+{
+      void f();
+}
diff --git a/gcc/testsuite/gdc.dg/gdc212.d b/gcc/testsuite/gdc.dg/gdc212.d
new file mode 100644
index 00000000000..bfe4b960794
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc212.d
@@ -0,0 +1,45 @@
+template hasElaborateAssign(S)
+{
+    enum hasElaborateAssign = is(typeof(S.init.opAssign(rvalueOf!S))) ||
+        is(typeof(lvalueOf!S)) ;
+}
+
+T rvalueOf(T)();
+
+T lvalueOf(T)();
+
+
+template TypeTuple(TList...)
+{
+    alias TypeTuple = TList;
+}
+
+template Tuple()
+{
+    struct Tuple
+    {
+        void opAssign(R)(R)
+        {
+            if (hasElaborateAssign!R)
+            {
+            }
+        }
+    }
+}
+
+ref emplaceRef()
+{
+    static if (!hasElaborateAssign!(Tuple!()))
+        chunk;
+}
+
+class TaskPool
+{
+    void reduce()
+    {
+        Tuple!() seed = void;
+        Tuple!()[] results;
+        foreach(i; TypeTuple!(0, 1))
+            results[i] = seed;
+    }
+}
diff --git a/gcc/testsuite/gdc.dg/gdc213.d b/gcc/testsuite/gdc.dg/gdc213.d
new file mode 100644
index 00000000000..3d73add2c90
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc213.d
@@ -0,0 +1,13 @@
+import core.simd;
+
+struct S213
+{
+    int4 vec;
+}
+
+void test213()
+{
+    S213 s, b;
+
+    assert(s == b);
+}
diff --git a/gcc/testsuite/gdc.dg/gdc218.d b/gcc/testsuite/gdc.dg/gdc218.d
new file mode 100644
index 00000000000..257ec1c1f39
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc218.d
@@ -0,0 +1,38 @@
+struct S218a
+{
+    this(int* pdata_)
+    {
+        pdata = pdata_;
+    }
+
+    void opIndexAssign(int, size_t) { }
+    int* pdata;
+};
+
+struct S218
+{
+    S218a getS218a()
+    {
+        return S218a(data.ptr);
+    }
+
+    int[] data;
+    int[] tab2;
+};
+
+S218 f()
+{
+    S218 r;
+
+    for(int i = 0; i < 1; ++i)
+        r.getS218a()[0] = 0;
+
+    return r;
+}
+
+S218 var;
+
+static this()
+{
+    var = f();
+}
diff --git a/gcc/testsuite/gdc.dg/gdc223.d b/gcc/testsuite/gdc.dg/gdc223.d
new file mode 100644
index 00000000000..8e44d07a56b
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc223.d
@@ -0,0 +1,62 @@
+import gcc.attribute;
+
+/* Test all gdc supported attributes.  */
+
+@attribute("forceinline")
+void forceinline()
+{
+}
+
+@attribute("noinline")
+void noinline()
+{
+}
+
+@attribute("flatten")
+void flatten()
+{
+}
+
+
+/* Issue 223: Test comparisons which could emit a memcmp */
+struct S223
+{
+    long[8] field;
+}
+
+class C223
+{
+    long[8] field;
+}
+
+S223 test223_1();
+real test223_2();
+string[long[8]] test223_3();
+C223 test223_4();
+long test223_5();
+long[] test223_6();
+long[8] test223_7();
+C223[8] test223_8();
+void delegate() test223_9();
+
+bool test223()
+{
+    return test223_1() == test223_1() &&
+           test223_1() is test223_1() &&
+           test223_2() == test223_2() &&
+           test223_2() is test223_2() &&
+           test223_3() == test223_3() &&
+           test223_3() is test223_3() &&
+           test223_4() == test223_4() &&
+           test223_4() is test223_4() &&
+           test223_5() == test223_5() &&
+           test223_5() is test223_5() &&
+           test223_6() == test223_6() &&
+           test223_6() is test223_6() &&
+           test223_7() == test223_7() &&
+           test223_7() is test223_7() &&
+           test223_8() == test223_8() &&
+           test223_8() is test223_8() &&
+           test223_9() == test223_9() &&
+           test223_9() is test223_9();
+}
diff --git a/gcc/testsuite/gdc.dg/gdc231.d b/gcc/testsuite/gdc.dg/gdc231.d
new file mode 100644
index 00000000000..d6dc74dd03a
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc231.d
@@ -0,0 +1,16 @@
+// { dg-additional-sources "imports/gdc231a.d" }
+module gdc231;
+
+import imports.gdc231a;
+
+class Range : Widget
+{
+    override void* getStruct()
+    {
+        return null;
+    }
+}
+
+void main()
+{
+}
diff --git a/gcc/testsuite/gdc.dg/gdc239.d b/gcc/testsuite/gdc.dg/gdc239.d
new file mode 100644
index 00000000000..1294d1260b7
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc239.d
@@ -0,0 +1,7 @@
+// { dg-options "-I $srcdir/gdc.dg" }
+import imports.gdc239a;
+
+class C239
+{
+    C239a *foo;
+}
diff --git a/gcc/testsuite/gdc.dg/gdc241.d b/gcc/testsuite/gdc.dg/gdc241.d
new file mode 100644
index 00000000000..d641c88a031
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc241.d
@@ -0,0 +1,3 @@
+// { dg-options "-I $srcdir/gdc.dg" }
+import imports.gdc241a;
+import imports.gdc241b : S241, C241, E241, N241;
diff --git a/gcc/testsuite/gdc.dg/gdc242.d b/gcc/testsuite/gdc.dg/gdc242.d
new file mode 100644
index 00000000000..cc56005eec5
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc242.d
@@ -0,0 +1,21 @@
+struct S242a
+{
+    enum M = S242a();
+    void iter() { }
+}
+
+void test242a()
+{
+    return S242a.M.iter;
+}
+
+struct S242b
+{
+    enum M = S242b();
+    void iter() { }
+}
+
+void test242b()
+{
+    S242b.M.iter;
+}
diff --git a/gcc/testsuite/gdc.dg/gdc251.d b/gcc/testsuite/gdc.dg/gdc251.d
new file mode 100644
index 00000000000..884ea733d3a
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc251.d
@@ -0,0 +1,5 @@
+// { dg-options "-I $srcdir/gdc.dg" }
+module gdc251;
+
+import imports.gdc251a;
+import imports.gdc251b : C251;
diff --git a/gcc/testsuite/gdc.dg/gdc253.d b/gcc/testsuite/gdc.dg/gdc253.d
new file mode 100644
index 00000000000..8d9f9d82b78
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc253.d
@@ -0,0 +1,8 @@
+// { dg-options "-I $srcdir/gdc.dg" }
+import imports.gdc253a;
+
+class C253 : C253a
+{
+    void test253() { }
+}
+
diff --git a/gcc/testsuite/gdc.dg/gdc254.d b/gcc/testsuite/gdc.dg/gdc254.d
new file mode 100644
index 00000000000..e6accb91314
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc254.d
@@ -0,0 +1,13 @@
+// { dg-options "-I $srcdir/gdc.dg" }
+// { dg-shouldfail "interface function is not implemented" }
+
+import imports.gdc254a;
+
+interface A254
+{
+    void F();
+}
+
+class C254 : B254, A254  // { dg-error "interface function '\[^\n\r]*' is not implemented" }
+{
+}
diff --git a/gcc/testsuite/gdc.dg/gdc255.d b/gcc/testsuite/gdc.dg/gdc255.d
new file mode 100644
index 00000000000..b631f29c291
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc255.d
@@ -0,0 +1,83 @@
+// Bug 255
+
+class C255
+{
+    void f2()
+    {
+        class C1
+        {
+            void f1()
+            {
+                void f0()
+                {
+                    class C0
+                    {
+                        void test255()
+                        {
+                            f2();
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+class C255a
+{
+    void f3()
+    {
+        class C1
+        {
+            void f2()
+            {
+                void f1()
+                {
+                    void f0()
+                    {
+                        class C0
+                        {
+                            void test255a()
+                            {
+                                f3();
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+class C255b
+{
+    void f4()
+    {
+        class C2
+        {
+            void f3()
+            {
+                void f2()
+                {
+                    class C1
+                    {
+                        void f1()
+                        {
+                            void f0()
+                            {
+                                class C0
+                                {
+                                    void test255b()
+                                    {
+                                        f4();
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
diff --git a/gcc/testsuite/gdc.dg/gdc256.d b/gcc/testsuite/gdc.dg/gdc256.d
new file mode 100644
index 00000000000..dfc7cf7ed03
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc256.d
@@ -0,0 +1,4 @@
+// { dg-options "-I $srcdir/gdc.dg -I $srcdir/gdc.dg/imports" }
+module gdc256;
+
+import imports.gdcpkg256 : gdc256a;
diff --git a/gcc/testsuite/gdc.dg/gdc260.d b/gcc/testsuite/gdc.dg/gdc260.d
new file mode 100644
index 00000000000..8a8295c390e
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc260.d
@@ -0,0 +1,7 @@
+// { dg-options "-Wall -Werror" }
+import gcc.builtins;
+
+char *bug260(char *buffer)
+{
+  return __builtin_strcat(&buffer[0], "Li");
+}
diff --git a/gcc/testsuite/gdc.dg/gdc261.d b/gcc/testsuite/gdc.dg/gdc261.d
new file mode 100644
index 00000000000..4ba031b11aa
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc261.d
@@ -0,0 +1,16 @@
+void test261()
+{
+    class C1
+    {
+        void f1()
+        {
+            class C2
+            {
+                void f2()
+                {
+                    auto v = &f1;
+                }
+            }
+        }
+    }
+}
diff --git a/gcc/testsuite/gdc.dg/gdc27.d b/gcc/testsuite/gdc.dg/gdc27.d
new file mode 100644
index 00000000000..a1d32c178ac
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gdc27.d
@@ -0,0 +1,18 @@
+// { dg-additional-sources "imports/gdc27a.d" }
+module gdc27;
+
+import imports.gdc27a;
+
+interface I_B : I_A
+{
+    void b();
+}
+
+abstract class C_B : C_A, I_B
+{
+    abstract void b();
+}
+
+void main()
+{
+}
diff --git a/gcc/testsuite/gdc.dg/imports/gdc170a.d b/gcc/testsuite/gdc.dg/imports/gdc170a.d
new file mode 100644
index 00000000000..24a5399192b
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdc170a.d
@@ -0,0 +1,18 @@
+module imports.gdc170a;
+
+class bar(T)
+{
+    void undefined_reference() {}
+}
+
+template foo(T)
+{
+    bar!T foo1(T2)() if (true) body { return null; }
+    bar!T foo2(T2)() { return null; }
+    bar!T foo3(T2 = void)() if (true) body { return null; }
+    bar!T foo4(T2 = void)() { return null; }
+    void foo5(T2)(bar!T x) if (true) body {}
+    void foo6(T2)(bar!T x) {}
+    void foo7(T2 = void)(bar!T x) if (true) body {}
+    void foo8(T2 = void)(bar!T x) {}
+}
diff --git a/gcc/testsuite/gdc.dg/imports/gdc231a.d b/gcc/testsuite/gdc.dg/imports/gdc231a.d
new file mode 100644
index 00000000000..c777f1eaf3b
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdc231a.d
@@ -0,0 +1,24 @@
+module imports.gdc231a;
+
+interface ImplementorIF
+{
+    void* getImplementorStruct();
+    void* getStruct();
+}
+
+template ImplementorT()
+{
+    void* getImplementorStruct()
+    {
+        return null;
+    }
+}
+
+class Widget : ImplementorIF
+{
+    mixin ImplementorT;
+    void* getStruct()
+    {
+        return null;
+    }
+}
diff --git a/gcc/testsuite/gdc.dg/imports/gdc239a.d b/gcc/testsuite/gdc.dg/imports/gdc239a.d
new file mode 100644
index 00000000000..3378d74bd9b
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdc239a.d
@@ -0,0 +1,9 @@
+import std.path : buildNormalizedPath;
+
+class C239a
+{
+    auto bar()
+    {
+        auto path = buildNormalizedPath("/", "foo");
+    }
+}
diff --git a/gcc/testsuite/gdc.dg/imports/gdc241a.d b/gcc/testsuite/gdc.dg/imports/gdc241a.d
new file mode 100644
index 00000000000..b781e3a5394
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdc241a.d
@@ -0,0 +1,6 @@
+import gdc241;
+
+S241 *s241;     // Use indirectly imported struct
+C241 *c241;     // Use indirectly imported class
+E241 *e241;     // Use indirectly imported enum
+N241.T *n241;   // Use indirectly imported namespace
diff --git a/gcc/testsuite/gdc.dg/imports/gdc241b.d b/gcc/testsuite/gdc.dg/imports/gdc241b.d
new file mode 100644
index 00000000000..3632575ba0d
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdc241b.d
@@ -0,0 +1,8 @@
+
+class C241 { }
+
+enum E241 { a }
+
+struct S241 { }
+
+extern(C++, N241) { struct T { } }
diff --git a/gcc/testsuite/gdc.dg/imports/gdc251a.d b/gcc/testsuite/gdc.dg/imports/gdc251a.d
new file mode 100644
index 00000000000..4ba927f91a7
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdc251a.d
@@ -0,0 +1,6 @@
+module imports.gdc251a;
+
+import imports.gdc251b;
+import gdc251;
+
+C251 config;
diff --git a/gcc/testsuite/gdc.dg/imports/gdc251b.d b/gcc/testsuite/gdc.dg/imports/gdc251b.d
new file mode 100644
index 00000000000..e70823f1ed6
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdc251b.d
@@ -0,0 +1,3 @@
+module imports.gdc251b;
+
+class C251 { }
diff --git a/gcc/testsuite/gdc.dg/imports/gdc253a.d b/gcc/testsuite/gdc.dg/imports/gdc253a.d
new file mode 100644
index 00000000000..8e629102aa3
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdc253a.d
@@ -0,0 +1,23 @@
+module imports.gdc253a;
+
+interface I253a
+{
+}
+
+interface I253b
+{
+    size_t printf(...);
+    void flush();
+}
+
+class C253a : I253a , I253b
+{
+    size_t printf(...)
+    {
+        return 0;
+    }
+
+    void flush()
+    {
+    }
+}
diff --git a/gcc/testsuite/gdc.dg/imports/gdc254a.d b/gcc/testsuite/gdc.dg/imports/gdc254a.d
new file mode 100644
index 00000000000..2a2a50d2f06
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdc254a.d
@@ -0,0 +1,10 @@
+module imports.gdc254a;
+
+class B254
+{
+    void F()
+    {
+        if (Error) return;
+    }
+
+}
diff --git a/gcc/testsuite/gdc.dg/imports/gdc256a.d b/gcc/testsuite/gdc.dg/imports/gdc256a.d
new file mode 100644
index 00000000000..dfbac24bbf2
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdc256a.d
@@ -0,0 +1 @@
+module gdc256a;
diff --git a/gcc/testsuite/gdc.dg/imports/gdc27a.d b/gcc/testsuite/gdc.dg/imports/gdc27a.d
new file mode 100644
index 00000000000..ed1d76193e6
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdc27a.d
@@ -0,0 +1,14 @@
+module imports.gdc27a;
+
+interface I_A
+{
+    bool a();
+}
+
+class C_A : I_A
+{
+    bool a()
+    {
+        return false;
+    }
+}
diff --git a/gcc/testsuite/gdc.dg/imports/gdcpkg256/package.d b/gcc/testsuite/gdc.dg/imports/gdcpkg256/package.d
new file mode 100644
index 00000000000..fb9a124fa60
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/gdcpkg256/package.d
@@ -0,0 +1,3 @@
+module imports.gdcpkg256;
+
+public import gdc256a;
diff --git a/gcc/testsuite/gdc.dg/imports/runnablea.d b/gcc/testsuite/gdc.dg/imports/runnablea.d
new file mode 100644
index 00000000000..061bc41ddb8
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/runnablea.d
@@ -0,0 +1,25 @@
+module imports.runnablea;
+
+private import runnable;
+
+/******************************************/
+
+// Bug 36
+
+void test36d_1()
+{
+    auto parser = Parser!(char[])();
+}
+
+/******************************************/
+
+// Bug 253
+
+class B253 : A253
+{
+    void test253(int[int] a)
+    {
+        if (a.get(0, 1))
+            return;
+    }
+}
diff --git a/gcc/testsuite/gdc.dg/link.d b/gcc/testsuite/gdc.dg/link.d
new file mode 100644
index 00000000000..b8dce31a897
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/link.d
@@ -0,0 +1,10 @@
+// { dg-do link { target arm*-*-* i?86-*-* x86_64-*-* } }
+
+class A()
+{
+    static struct S { A a; }
+}
+
+enum e = is(A!());
+
+void main() {}
diff --git a/gcc/testsuite/gdc.dg/lto/lto.exp b/gcc/testsuite/gdc.dg/lto/lto.exp
new file mode 100644
index 00000000000..b23d7c28408
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/lto/lto.exp
@@ -0,0 +1,56 @@
+#   Copyright (C) 2017 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Test link-time optimization across multiple files.
+#
+# Programs are broken into multiple files.  Each one is compiled
+# separately with LTO information.  The final executable is generated
+# by collecting all the generated object files using regular LTO or WHOPR.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+# Load procedures from common libraries.
+load_lib standard.exp
+load_lib gdc-dg.exp
+
+# Load the language-independent compabibility support procedures.
+load_lib lto.exp
+
+# If LTO has not been enabled, bail.
+if { ![check_effective_target_lto] } {
+    return
+}
+
+lto_init no-mathlib
+
+# Define an identifier for use with this suite to avoid name conflicts
+# with other lto tests running at the same time.
+set sid "d_lto"
+
+# Main loop.
+foreach src [lsort [find $srcdir/$subdir *_0.d]] {
+    # If we're only testing specific files and this isn't one of them, skip it.
+    if ![runtest_file_p $runtests $src] then {
+        continue
+    }
+
+    lto-execute $src $sid
+}
+
+lto_finish
+
diff --git a/gcc/testsuite/gdc.dg/lto/ltotests_0.d b/gcc/testsuite/gdc.dg/lto/ltotests_0.d
new file mode 100644
index 00000000000..c10226fe12b
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/lto/ltotests_0.d
@@ -0,0 +1,76 @@
+module ltotests_0;
+
+import core.stdc.stdio;
+
+
+/******************************************/
+
+/+ XBUG: lto1: internal compiler error: in get_odr_type
+interface I284
+{
+   void m284();
+}
+
+class C284 : I284
+{
+   void m284() { }
+}
++/
+
+/******************************************/
+
+/+ XBUG: lto1: internal compiler error: in get_odr_type
+class C304
+{
+}
+
+C304 c304;
++/
+
+/******************************************/
+
+// Bug 61
+
+struct S61a
+{
+    void a() { }
+    void b() { }
+}
+
+struct S61b
+{
+    S61a other;
+
+    void foo()
+    {
+        bar();
+    }
+
+    void bar()
+    {
+        try
+            other.a();
+        catch
+            other.b();
+    }
+}
+
+/******************************************/
+
+// Bug 88
+
+extern(C) int test88a();
+
+void test88()
+{
+    test88a();
+}
+
+/******************************************/
+
+void main(string[])
+{
+    test88();
+
+    printf("Success!\n");
+}
diff --git a/gcc/testsuite/gdc.dg/lto/ltotests_1.d b/gcc/testsuite/gdc.dg/lto/ltotests_1.d
new file mode 100644
index 00000000000..1693e6a7f95
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/lto/ltotests_1.d
@@ -0,0 +1,9 @@
+module ltotests_1;
+
+/******************************************/
+// Bug 88
+
+extern(C) int test88a()
+{
+    return 0;
+}
diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d
new file mode 100644
index 00000000000..a54e8c59cfd
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/runnable.d
@@ -0,0 +1,1532 @@
+// { dg-additional-sources "imports/runnablea.d" }
+// { dg-do run { target arm*-*-* i?86-*-* x86_64-*-* } }
+
+module runnable;
+
+import imports.runnablea;
+import core.stdc.stdio;
+import gcc.attribute;
+
+
+/******************************************/
+
+// Bug 2
+
+struct S
+{
+    string toString() { return "foo"; }
+}
+
+void test2()
+{
+    import std.string : format;
+    assert(format("%s", S()) == "foo");
+}
+
+/******************************************/
+
+// Bug 4
+
+void test4()
+{
+    string str = "allo";
+    static assert(!__traits(compiles, str.reverse));
+    static assert(!__traits(compiles, str.sort));
+}
+
+/******************************************/
+
+// Bug 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);
+    }
+}
+
+/******************************************/
+
+// Bug 16
+
+void test16()
+{
+    import std.parallelism : taskPool;
+
+    taskPool.reduce!"a+b"([0, 1, 2, 3]);
+}
+
+/******************************************/
+
+// Bug 17
+
+/**
+ * Parameters are not copied into a frame to be accessed from
+ * the method's __require function.
+ */
+void contractTest(string path)
+{
+    assert(path[0] == 't');
+    assert(path.length == 9);
+    assert(path[8] == 'i');
+}
+
+interface ModuleSaver
+{
+    void save(string str)
+    in
+    {
+        contractTest(str);
+    }
+}
+
+class ModuleWriter : ModuleSaver
+{
+    void save (string str)
+    in {}
+    body
+    {
+    }
+}
+
+void test17()
+{
+  (new ModuleWriter()).save ("test.0.mci");
+}
+
+/******************************************/
+
+// Bug 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();
+}
+
+/******************************************/
+
+// Bug 19
+
+void test19()
+{
+   byte b;
+   --b = b;
+}
+
+/******************************************/
+
+// Bug 24
+
+void test24()
+{
+    struct S24
+    {
+        char[1] b;
+    }
+
+    S24 a;
+
+    if (*a.b.ptr)
+        return;
+}
+
+/******************************************/
+
+// Bug 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);
+    }
+}
+
+/******************************************/
+
+// Bug 31
+
+class RedBlackTree(T, alias less)
+{
+    struct Range
+    {
+        @property empty() { }
+    }
+
+    Range opSlice()
+    {
+        return Range();
+    }
+}
+
+auto redBlackTree(alias less, E)()
+{
+    return new RedBlackTree!(E, less);
+}
+
+void test31()
+{
+    redBlackTree!((a){}, double)();
+}
+
+/******************************************/
+
+// Bug 35
+
+/**
+ * Here the BinaryHeap instance uses an alias parameter and therefore
+ * the instance's functions (percolateDown) need to be generated in
+ * topNIndex->BinaryHeap scope and not in the declaration scope
+ * (module->BinaryHeap).
+ */
+void topNIndex()()
+{
+    bool indirectLess(int a, int b)
+    {
+        return a > b;
+    }
+
+    auto a = BinaryHeap!(indirectLess)();
+}
+
+struct BinaryHeap(alias less)
+{
+    void percolateDown()
+    {
+        less(0, 1);
+    }
+}
+
+void test35a()
+{
+    topNIndex();
+}
+
+/*
+ * Similar as test35a but with an additional indirection.
+ * The nested function chain for percolateDown should look like this:
+ * topNIndex2->BinaryHeap2->percolateDown.
+ */
+void topNIndex2()()
+{
+    bool indirectLess(int a, int b)
+    {
+        return a > b;
+    }
+    auto a = BinaryHeap2!(S35b!(indirectLess)())();
+}
+
+struct S35b(alias a)
+{
+    void foo()
+    {
+        a(0, 0);
+    }
+}
+
+struct BinaryHeap2(alias less)
+{
+    void percolateDown()
+    {
+        less.foo();
+    }
+}
+
+void test35b()
+{
+    topNIndex2();
+}
+
+void test35()
+{
+    test35a();
+    test35b();
+}
+
+/******************************************/
+
+// Bug 36
+
+/**
+ * Here getChar is a function in a template where template.isnested == false
+ * but getChar still is a nested function and needs to get a static chain
+ * containing test36a.
+ */
+void test36a()(char val)
+{
+    void error()
+    {
+    }
+
+    void getChar()()
+    {
+        error();
+    }
+
+    void parseString()
+    {
+        getChar();
+    }
+}
+
+/**
+ * Similar as test36a, but a little more complicated:
+ * Here getChar is nested in a struct template which is nested in a function.
+ * getChar's static chain still needs to contain test36b.
+ */
+void test36b()(char val)
+{
+    void error()
+    {
+    }
+
+    struct S(T)
+    {
+        void getChar()
+        {
+            error();
+        }
+    }
+
+
+    void parseString()
+    {
+        S!(int)().getChar();
+    }
+}
+
+/**
+ * If g had accessed a, the frontend would have generated a closure.
+ *
+ * As we do not access it, there's no closure. We have to be careful
+ * not to set a static chain for g containing test36c_1 though,
+ * as g can be called from outside (here from test1c). In the end
+ * we have to treat this as if everything in test36c_1 was declared
+ * at module scope.
+ */
+auto test36c_1()
+{
+    int a;
+    void c() {};
+    class Result
+    {
+        int b;
+        void g() { c(); /*a = 42;*/ }
+    }
+
+    return new Result();
+}
+
+void test36c()
+{
+    test36c_1().g();
+}
+
+/**
+ * empty is a (private) function which is nested in lightPostprocess.
+ * At the same time it's a template instance, so it has to be declared as
+ * weak or otherwise one-only. imports/runnablea.d creates another instance
+ * of Regex!char to verify that.
+ */
+struct Parser(R)
+{
+    @property program()
+    {
+        return Regex!char();
+    }
+}
+
+struct Regex(Char)
+{
+    @trusted lightPostprocess()
+    {
+        struct FixedStack(T)
+        {
+            @property empty() { return false; }
+        }
+        auto counterRange = FixedStack!uint();
+    }
+}
+
+void test36d()
+{
+    auto parser = Parser!(char[])();
+    imports.runnablea.test36d_1;
+}
+
+void test36()
+{
+  test36a('n');
+  test36b('n');
+  test36c();
+  test36d();
+}
+
+/******************************************/
+
+// Bug 37
+
+struct S37
+{
+    int bar(const S37 s)
+    {
+        return 0;
+    }
+}
+
+int test37()
+{
+    S37 s;
+    return s.bar(s);
+}
+
+/******************************************/
+
+// Bug 43
+
+void test43()
+{
+    import core.vararg;
+    import core.stdc.stdio;
+
+    void formatArray(ref va_list argptr)
+    {
+        auto a = va_arg!(const(float)[])(argptr);
+        foreach(f; a)
+        {
+            printf("%f\n", f);
+        }
+    }
+
+    void doFormat(TypeInfo[] arguments, va_list argptr)
+    {
+        formatArray(argptr);
+    }
+
+    void format(...)
+    {
+        doFormat(_arguments, _argptr);
+    }
+
+    format([1.0f, 2.0f, 3.0f]);
+}
+
+/******************************************/
+
+// Bug 47
+
+template Foo47()
+{
+    void test47()
+    {
+        asm { "nop"; }
+    }
+}
+
+mixin Foo47!();
+
+/******************************************/
+
+// Bug 51
+
+struct S51
+{
+    int x;
+    int pad;
+
+    this(this)
+    {
+        ++x;
+    }
+}
+
+void test51()
+{
+    S51 s;
+    auto sarr = new S51[1];
+    auto sarr2 = sarr;
+
+    // postblit all fields.
+    sarr2 ~= s;
+
+    assert (sarr2[0].x == 1);
+    assert (sarr2[1].x == 1);
+    assert (sarr[0].x == 0);
+    assert (s.x == 0);
+}
+
+/******************************************/
+
+// Bug 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);
+}
+
+/******************************************/
+
+// Bug 57
+
+struct S57
+{
+    int a;
+    long b;
+    // Doesn't happen for bigger structs
+}
+
+S57 bar57()
+{
+    return S57(4, 42);
+}
+
+void test57()
+{
+    S57 s = bar57();
+    assert (s is S57(4, 42));
+}
+
+/******************************************/
+
+// Bug 66
+
+void test66()
+{
+    int pos = 0;
+
+    foreach(x; 0 .. 64)
+    {
+        ++pos %= 4;
+        assert (pos != 4);
+    }
+}
+
+/******************************************/
+
+// Bug 67
+
+__vector(float[4]) d[2];  // ICE
+
+
+/******************************************/
+
+// Bug 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));
+    }
+}
+
+/******************************************/
+
+// Bug 77
+
+void fun(ubyte[3] buf)
+{
+    import std.bitmanip : bigEndianToNative;
+    bigEndianToNative!ushort(buf[0..2]);
+}
+
+void test77()
+{
+    fun([1,2,3]);
+}
+
+/******************************************/
+
+// Bug 108
+
+@attribute("forceinline")
+void test108()
+{
+    import std.stdio : writeln;
+    writeln("Here");
+}
+
+/******************************************/
+
+// Bug 115
+
+void test115()
+{
+    union U
+    {
+        float f;
+        uint i;
+    }
+    float a = 123.0;
+    const l = U(a);
+
+    assert(l.i == U(a).i);
+}
+
+/******************************************/
+
+// Bug 121
+
+immutable char C121 = void; // ICE
+
+/******************************************/
+
+// Bug 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)));
+}
+
+/******************************************/
+
+// Bug 127
+
+int[0] test127a;     // OK
+int[1][0] test127b;  // OK
+int[0][1] test127c;  // ICE
+
+/******************************************/
+
+// Bug 131
+
+struct S131
+{
+    this(string ) { }
+    string opAssign(string v) { return v; }
+}
+
+void test131()
+{
+    S131[string] s;
+    s["foo"] = "bar";
+}
+
+/******************************************/
+
+// Bug 133
+
+void delegate()[] D133;
+
+void test133a(void delegate() dg)
+{
+    D133 ~= dg;
+}
+
+void test133()
+{
+    void nested()
+    {}
+    test133a(&nested);
+}
+
+/******************************************/
+
+// Bug 141
+
+bool test141a(int a)
+{
+    return a > (a + 1);
+}
+
+void test141()
+{
+    assert(test141a(int.min) == false);
+    assert(test141a(int.max) == true);
+}
+
+/******************************************/
+
+// Bug 142
+
+@attribute("noinline")
+int test142a()()
+{
+    return 142;
+}
+
+void test142()
+{
+    enum E142 = test142a();
+}
+
+/******************************************/
+
+// Bug 171
+
+void test171a()
+{
+    int count = 0;
+    short a = -1;
+    while (a != 0)
+    {
+        a >>>= 1;
+        count++;
+        assert(count <= 16);
+    }
+}
+
+void test171b()
+{
+    uint[3] lhs = [99, 201, 300],
+            rhs = [-1, 0, 0];
+    long t = 0;
+
+    for (int i = 0; i < 3; i++)
+    {
+        t += lhs[i];
+        t -= rhs[i];
+        lhs[i] = cast(uint) t;
+        t >>= uint.sizeof * 8;
+    }
+
+    assert(lhs == [100, 200, 300]);
+}
+
+void test171()
+{
+    test171a();
+    test171b();
+}
+
+/******************************************/
+
+// Bug 179
+
+struct S179a
+{
+    @disable this(this);
+}
+
+struct S179b
+{
+    S179a s1;
+    void connect() { printf("this=%p\n", &this); }
+}
+
+class C179
+{
+    private S179b s2;
+    ref S179b value() @property
+    {
+        printf("this=%p\n", &s2);
+        return s2;
+    }
+}
+
+void test179()
+{
+    C179 a = new C179;
+    a.value.connect();
+}
+
+/******************************************/
+
+// Bug 183
+
+struct S183a
+{
+    union I183a
+    {
+        struct
+        {
+            double x, y, z;
+        }
+        struct
+        {
+            double a, b, c;
+        }
+    }
+
+    I183a inner;
+
+    this(double x, double y, double z)
+    {
+        this.inner.x = x;
+        this.inner.y = y;
+        this.inner.z = z;
+    }
+}
+
+struct S183b
+{
+    @property get()
+    {
+        union Buf
+        {
+            void[0] result;
+        }
+        const Buf buf = { };
+        return buf.result;
+    }
+}
+
+struct S183c
+{
+    @property get()
+    {
+        union Buf
+        {
+            TypeInfo info;
+            void[0] result;
+        }
+        const Buf buf = { };
+        return buf.result;
+    }
+}
+
+void test183()
+{
+    auto v1 = S183a(0, 0, 0);
+    auto v2 = S183b().get;
+    auto v3 = S183c().get;
+}
+
+/******************************************/
+
+// Bug 186
+
+struct S186
+{
+    union
+    {
+        struct
+        {
+            ubyte fieldA;
+            byte  fieldB = -1;
+            byte fieldC = -1;
+        }
+        size_t _complete;
+    }
+
+    this(size_t complete)
+    {
+        this._complete = complete;
+    }
+}
+
+void check186(in S186 obj, byte fieldB)
+{
+    assert(obj.fieldA == 2);
+    assert(obj.fieldB == 0);
+    assert(obj.fieldC == 0);
+    assert(obj._complete == 2);
+    assert(fieldB == 0);
+}
+
+void test186a(size_t val)
+{
+    S186 obj = S186(val);
+    check186(obj, obj.fieldB);
+
+    assert(obj.fieldA == 2);
+    assert(obj.fieldB == 0);
+    assert(obj.fieldC == 0);
+    assert(obj._complete == 2);
+
+    obj = S186(val);
+    check186(obj, obj.fieldB);
+
+    assert(obj.fieldA == 2);
+    assert(obj.fieldB == 0);
+    assert(obj.fieldC == 0);
+    assert(obj._complete == 2);
+}
+
+void test186()
+{
+    test186a(2);
+}
+
+/******************************************/
+
+// Bug 187
+
+align(1) struct S187b
+{
+    align(1)
+    {
+        uint unpaddedA;
+        ushort unpaddedB;
+    }
+}
+
+struct S187a
+{
+    S187b[3] unpaddedArray;
+    ubyte wontInitialize = ubyte.init;
+}
+
+struct S187
+{
+    S187a interesting;
+}
+
+
+void prepareStack()
+{
+    byte[255] stackGarbage;
+    foreach(i, ref b; stackGarbage)
+    {
+        b  = cast(byte)(-i);
+    }
+}
+
+void test187()
+{
+    prepareStack();
+    auto a = S187(S187a());
+    assert(a.interesting.wontInitialize == 0);
+}
+
+/******************************************/
+
+// Bug 191
+
+class C191
+{
+    int count = 0;
+
+    void testA()
+    {
+        class Inner
+        {
+            void test()
+            {
+                void localFunction()
+                {
+                    if (++count != 5)
+                        testA();
+                }
+                localFunction();
+            }
+        }
+        scope ic = new Inner();
+        ic.test();
+    }
+
+    void testB()
+    {
+        class Inner
+        {
+            void test()
+            {
+                void localFunction()
+                {
+                    void anotherLocalFunction()
+                    {
+                        if (++count != 10)
+                            testB();
+                    }
+                    anotherLocalFunction();
+                }
+                localFunction();
+            }
+        }
+        scope ic = new Inner();
+        ic.test();
+    }
+
+    void testC()
+    {
+        class Inner
+        {
+            int a = 1;
+
+            void test()
+            {
+                void localFunction()
+                {
+                    count += a;
+                    if (count != 15)
+                        testC();
+                    assert(a == 1);
+                }
+                localFunction();
+            }
+        }
+        scope ic = new Inner();
+        ic.test();
+    }
+
+    void testD()
+    {
+        class Inner
+        {
+            void test()
+            {
+                int a = 1;
+
+                void localFunction()
+                {
+                    count += a;
+                    if (count != 20)
+                        testD();
+                    assert(a == 1);
+                }
+                localFunction();
+            }
+        }
+        scope ic = new Inner();
+        ic.test();
+    }
+
+    void testE()
+    {
+        class Inner
+        {
+            int a = 1;
+
+            void test()
+            {
+                void localFunction()
+                {
+                    void anotherLocalFunction()
+                    {
+                        count += a;
+                        if (count != 25)
+                            testE();
+                        assert(a == 1);
+                    }
+
+                    anotherLocalFunction();
+                }
+
+                localFunction();
+            }
+        }
+        scope ic = new Inner();
+        ic.test();
+    }
+
+    void testF()
+    {
+        class Inner
+        {
+            void test()
+            {
+                int a = 1;
+
+                void localFunction()
+                {
+                    void anotherLocalFunction()
+                    {
+                        count += a;
+                        if (count != 30)
+                            testF();
+                        assert(a == 1);
+                    }
+
+                    anotherLocalFunction();
+                }
+
+                localFunction();
+            }
+        }
+        scope ic = new Inner();
+        ic.test();
+    }
+
+    void testG()
+    {
+        class Inner
+        {
+            void test()
+            {
+                void localFunction()
+                {
+                    int a = 1;
+
+                    void anotherLocalFunction()
+                    {
+                        count += a;
+                        if (count != 35)
+                            testG();
+                        assert(a == 1);
+                    }
+
+                    anotherLocalFunction();
+                }
+
+                localFunction();
+            }
+        }
+        scope ic = new Inner();
+        ic.test();
+    }
+}
+
+void test191()
+{
+    scope oc = new C191();
+    oc.testA();
+    assert(oc.count == 5);
+
+    oc.testB();
+    assert(oc.count == 10);
+
+    oc.testC();
+    assert(oc.count == 15);
+
+    oc.testD();
+    assert(oc.count == 20);
+
+    oc.testE();
+    assert(oc.count == 25);
+
+    oc.testF();
+    assert(oc.count == 30);
+
+    oc.testG();
+    assert(oc.count == 35);
+}
+
+/******************************************/
+
+// Bug 194
+
+auto test194(ref bool overflow)
+{
+    import core.checkedint;
+
+    return adds(1, 1, overflow);
+}
+
+/******************************************/
+
+// Bug 196
+
+class C196
+{
+    int a;
+}
+
+struct S196
+{
+    int a;
+}
+
+void test196()
+{
+    __gshared c = new C196();
+    __gshared s = new S196(0);
+    c.a = 1;
+    s.a = 1;
+}
+
+/******************************************/
+
+// Bug 198
+
+struct S198a
+{
+    union
+    {
+        float[3] v;
+        struct
+        {
+            float x;
+            float y;
+            float z;
+        }
+    }
+
+    this(float x_, float y_, float z_)
+    {
+        x = x_;
+        y = y_;
+        z = z_;
+    }
+
+    ref S198a opOpAssign(string op)(S198a operand)
+    if (op == "+")
+    {
+        x += operand.x;
+        y += operand.y;
+        z += operand.z;
+        return this;
+    }
+}
+
+struct S198b
+{
+    @property get()
+    {
+        union Buf
+        {
+            void[0] result;
+        }
+        const Buf buf = { };
+        return buf.result;
+    }
+}
+
+struct S198c
+{
+    @property get()
+    {
+        union Buf
+        {
+            TypeInfo info;
+            void[0] result;
+        }
+        const Buf buf = { };
+        return buf.result;
+    }
+}
+
+
+auto test198()
+{
+    S198a sum = S198a(0, 0, 0);
+
+    foreach(size_t v; 0 .. 3)
+        sum += S198a(1, 2, 3);
+
+    assert(sum.v == [3, 6, 9]);
+}
+
+/******************************************/
+
+// Bug 210
+
+struct S210
+{
+    ubyte a;
+    uint b;
+}
+
+union U210
+{
+    S210 a;
+    uint b;
+}
+
+S210 test210a()
+{
+    S210 s = S210(1, 2);
+    return s;
+}
+
+S210[2] test210b()
+{
+    S210[2] s = [S210(1, 2), S210(3, 4)];
+    return s;
+}
+
+U210 test210c()
+{
+    U210 s = U210(S210(1, 2));
+    return s;
+}
+
+U210[2] test210d()
+{
+    U210[2] s = [U210(S210(1, 2)), U210(S210(3, 4))];
+    return s;
+}
+
+void test210()
+{
+    S210 a = S210(1, 2);
+    assert(a == S210(1, 2));
+    assert(a == test210a());
+    assert(a != S210(2, 1));
+
+    S210[2] b = [S210(1, 2), S210(3, 4)];
+    assert(b == [S210(1, 2), S210(3, 4)]);
+    assert(b == test210b());
+    assert(b != [S210(2, 1), S210(3, 4)]);
+
+    U210 c = U210(S210(1, 2));
+    assert(c == U210(S210(1, 2)));
+    assert(c == test210c());
+    assert(c != U210(S210(2, 1)));
+
+    U210[2] d = [U210(S210(1, 2)), U210(S210(3, 4))];
+    assert(d == [U210(S210(1, 2)), U210(S210(3, 4))]);
+    assert(d == test210d());
+    assert(d != [U210(S210(2, 1)), U210(S210(3, 4))]);
+}
+
+/******************************************/
+
+// Bug 242
+
+struct S242
+{
+    enum M = S242();
+    int a = 42;
+
+    auto iter()
+    {
+        this.a = 24;
+        return this;
+    }
+}
+
+S242 test242a()
+{
+    return S242.M.iter;
+}
+
+void test242()
+{
+    assert(test242a() == S242(24));
+}
+
+/******************************************/
+
+// Bug 248
+
+class C248b
+{
+    bool isintegral()
+    {
+        return false;
+    }
+}
+
+class C248a
+{
+    int count = 0;
+
+    C248b getMemtype()
+    {
+        count++;
+        return new C248b();
+    }
+}
+
+class C248
+{
+    C248a sym;
+
+    this()
+    {
+        this.sym = new C248a();
+    }
+
+    bool isintegral()
+    {
+        return sym.getMemtype().isintegral();
+    }
+}
+
+void test248()
+{
+    C248 e = new C248();
+    e.isintegral();
+    assert(e.sym.count == 1);
+}
+
+/******************************************/
+
+// Bug 250
+
+void test250()
+{
+    struct S
+    {
+        string data;
+    }
+
+    auto a = S("hello");
+    auto b = S("hello".dup);
+
+    assert(a.data == b.data);
+    assert(a == b);
+    assert([a] == [b]);
+}
+
+/******************************************/
+
+// Bug 253
+
+interface A253
+{
+    void test253(int[int]);
+}
+
+interface C253 : A253
+{
+}
+
+class D253 : B253, C253
+{
+}
+
+/******************************************/
+
+// Bug 273
+
+class B273
+{
+    B273[] members;
+}
+
+class D273 : B273
+{
+}
+
+void test273()
+{
+    auto noPointers = ClassInfo.ClassFlags.noPointers;
+    assert((B273.classinfo.m_flags & noPointers) == 0);
+    assert((D273.classinfo.m_flags & noPointers) == 0);
+}
+
+/******************************************/
+
+void main()
+{
+    test2();
+    test4();
+    test16();
+    test17();
+    test18();
+    test35();
+    test36();
+    test43();
+    test51();
+    test52();
+    test57();
+    test66();
+    test77();
+    test108();
+    test115();
+    test131();
+    test133();
+    test141();
+    test179();
+    test186();
+    test187();
+    test191();
+    test196();
+    test198();
+    test210();
+    test248();
+    test250();
+    test273();
+
+    printf("Success!\n");
+}
diff --git a/gcc/testsuite/gdc.dg/simd.d b/gcc/testsuite/gdc.dg/simd.d
new file mode 100644
index 00000000000..bad4ceca139
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/simd.d
@@ -0,0 +1,1735 @@
+// { dg-do run { target arm*-*-* i?86-*-* x86_64-*-* } }
+import core.simd;
+import core.stdc.string;
+import std.stdio;
+
+alias TypeTuple(T...) = T;
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=16087
+
+static assert(void8.sizeof == 8);
+static assert(float2.sizeof == 8);
+static assert(byte8.sizeof == 8);
+static assert(ubyte8.sizeof == 8);
+static assert(short4.sizeof == 8);
+static assert(ushort4.sizeof == 8);
+static assert(int2.sizeof == 8);
+static assert(uint2.sizeof == 8);
+
+static assert(void16.alignof == 16);
+static assert(double2.alignof == 16);
+static assert(float4.alignof == 16);
+static assert(byte16.alignof == 16);
+static assert(ubyte16.alignof == 16);
+static assert(short8.alignof == 16);
+static assert(ushort8.alignof == 16);
+static assert(int4.alignof == 16);
+static assert(uint4.alignof == 16);
+static assert(long2.alignof == 16);
+static assert(ulong2.alignof == 16);
+
+static assert(void16.sizeof == 16);
+static assert(double2.sizeof == 16);
+static assert(float4.sizeof == 16);
+static assert(byte16.sizeof == 16);
+static assert(ubyte16.sizeof == 16);
+static assert(short8.sizeof == 16);
+static assert(ushort8.sizeof == 16);
+static assert(int4.sizeof == 16);
+static assert(uint4.sizeof == 16);
+static assert(long2.sizeof == 16);
+static assert(ulong2.sizeof == 16);
+
+static assert(void32.alignof == 32);
+static assert(double4.alignof == 32);
+static assert(float8.alignof == 32);
+static assert(byte32.alignof == 32);
+static assert(ubyte32.alignof == 32);
+static assert(short16.alignof == 32);
+static assert(ushort16.alignof == 32);
+static assert(int8.alignof == 32);
+static assert(uint8.alignof == 32);
+static assert(long4.alignof == 32);
+static assert(ulong4.alignof == 32);
+
+static assert(void32.sizeof == 32);
+static assert(double4.sizeof == 32);
+static assert(float8.sizeof == 32);
+static assert(byte32.sizeof == 32);
+static assert(ubyte32.sizeof == 32);
+static assert(short16.sizeof == 32);
+static assert(ushort16.sizeof == 32);
+static assert(int8.sizeof == 32);
+static assert(uint8.sizeof == 32);
+static assert(long4.sizeof == 32);
+static assert(ulong4.sizeof == 32);
+
+/*****************************************/
+
+void test1()
+{
+    void16 v1 = void,v2 = void;
+    byte16 b;
+    v2 = b;
+    v1 = v2;
+    static assert(!__traits(compiles, v1 + v2));
+    static assert(!__traits(compiles, v1 - v2));
+    static assert(!__traits(compiles, v1 * v2));
+    static assert(!__traits(compiles, v1 / v2));
+    static assert(!__traits(compiles, v1 % v2));
+    static assert(!__traits(compiles, v1 & v2));
+    static assert(!__traits(compiles, v1 | v2));
+    static assert(!__traits(compiles, v1 ^ v2));
+    static assert(!__traits(compiles, v1 ~ v2));
+    static assert(!__traits(compiles, v1 ^^ v2));
+    static assert(!__traits(compiles, v1 is v2));
+    static assert(!__traits(compiles, v1 !is v2));
+    static assert(!__traits(compiles, v1 == v2));
+    static assert(!__traits(compiles, v1 != v2));
+    static assert(!__traits(compiles, v1 < v2));
+    static assert(!__traits(compiles, v1 > v2));
+    static assert(!__traits(compiles, v1 <= v2));
+    static assert(!__traits(compiles, v1 >= v2));
+    static assert(!__traits(compiles, v1 <> v2));
+    static assert(!__traits(compiles, v1 !< v2));
+    static assert(!__traits(compiles, v1 !> v2));
+    static assert(!__traits(compiles, v1 !<> v2));
+    static assert(!__traits(compiles, v1 <>= v2));
+    static assert(!__traits(compiles, v1 !<= v2));
+    static assert(!__traits(compiles, v1 !>= v2));
+    static assert(!__traits(compiles, v1 !<>= v2));
+    static assert(!__traits(compiles, v1 << 1));
+    static assert(!__traits(compiles, v1 >> 1));
+    static assert(!__traits(compiles, v1 >>> 1));
+    static assert(!__traits(compiles, v1 && v2));
+    static assert(!__traits(compiles, v1 || v2));
+    static assert(!__traits(compiles, ~v1));
+    static assert(!__traits(compiles, -v1));
+    static assert(!__traits(compiles, +v1));
+    static assert(!__traits(compiles, !v1));
+
+    static assert(!__traits(compiles, v1 += v2));
+    static assert(!__traits(compiles, v1 -= v2));
+    static assert(!__traits(compiles, v1 *= v2));
+    static assert(!__traits(compiles, v1 /= v2));
+    static assert(!__traits(compiles, v1 %= v2));
+    static assert(!__traits(compiles, v1 &= v2));
+    static assert(!__traits(compiles, v1 |= v2));
+    static assert(!__traits(compiles, v1 ^= v2));
+    static assert(!__traits(compiles, v1 ~= v2));
+    static assert(!__traits(compiles, v1 ^^= v2));
+    static assert(!__traits(compiles, v1 <<= 1));
+    static assert(!__traits(compiles, v1 >>= 1));
+    static assert(!__traits(compiles, v1 >>>= 1));
+
+    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.
+    static assert(!__traits(compiles, cast(byte)v1));       // 1byte
+    static assert(!__traits(compiles, cast(short)v1));      // 2byte
+    static assert(!__traits(compiles, cast(int)v1));        // 4byte
+    static assert(!__traits(compiles, cast(long)v1));       // 8byte
+    static assert(!__traits(compiles, cast(float)v1));      // 4byte
+    static assert(!__traits(compiles, cast(double)v1));     // 8byte
+    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray
+    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK
+    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK
+}
+
+/*****************************************/
+
+void test2()
+{
+    byte16 v1, v2 = 1, v3 = 1;
+    v1 = v2;
+    v1 = v2 + v3;
+    v1 = v2 - v3;
+    v1 = v2 * v3;
+    v1 = v2 / v3;
+    v1 = v2 % v3;
+    v1 = v2 & v3;
+    v1 = v2 | v3;
+    v1 = v2 ^ v3;
+    static assert(!__traits(compiles, v1 ~ v2));
+    static assert(!__traits(compiles, v1 ^^ v2));
+    static assert(!__traits(compiles, v1 is v2));
+    static assert(!__traits(compiles, v1 !is v2));
+    static assert(!__traits(compiles, v1 == v2));
+    static assert(!__traits(compiles, v1 != v2));
+    static assert(!__traits(compiles, v1 < v2));
+    static assert(!__traits(compiles, v1 > v2));
+    static assert(!__traits(compiles, v1 <= v2));
+    static assert(!__traits(compiles, v1 >= v2));
+    static assert(!__traits(compiles, v1 <> v2));
+    static assert(!__traits(compiles, v1 !< v2));
+    static assert(!__traits(compiles, v1 !> v2));
+    static assert(!__traits(compiles, v1 !<> v2));
+    static assert(!__traits(compiles, v1 <>= v2));
+    static assert(!__traits(compiles, v1 !<= v2));
+    static assert(!__traits(compiles, v1 !>= v2));
+    static assert(!__traits(compiles, v1 !<>= v2));
+    v1 = v2 << 1;
+    v1 = v2 >> 1;
+    v1 = v2 >>> 1;
+    static assert(!__traits(compiles, v1 && v2));
+    static assert(!__traits(compiles, v1 || v2));
+    v1 = ~v2;
+    v1 = -v2;
+    v1 = +v2;
+    static assert(!__traits(compiles, !v1));
+
+    v1 += v2;
+    v1 -= v2;
+    v1 *= v2;
+    v1 /= v2;
+    v1 %= v2;
+    v1 &= v2;
+    v1 |= v2;
+    v1 ^= v2;
+    static assert(!__traits(compiles, v1 ~= v2));
+    static assert(!__traits(compiles, v1 ^^= v2));
+    v1 <<= 1;
+    v1 >>= 1;
+    v1 >>>= 1;
+
+    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.
+    static assert(!__traits(compiles, cast(byte)v1));       // 1byte
+    static assert(!__traits(compiles, cast(short)v1));      // 2byte
+    static assert(!__traits(compiles, cast(int)v1));        // 4byte
+    static assert(!__traits(compiles, cast(long)v1));       // 8byte
+    static assert(!__traits(compiles, cast(float)v1));      // 4byte
+    static assert(!__traits(compiles, cast(double)v1));     // 8byte
+    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray
+    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK
+    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK
+}
+
+/*****************************************/
+
+void test2b()
+{
+    ubyte16 v1, v2 = 1, v3 = 1;
+    v1 = v2;
+    v1 = v2 + v3;
+    v1 = v2 - v3;
+    v1 = v2 * v3;
+    v1 = v2 / v3;
+    v1 = v2 % v3;
+    v1 = v2 & v3;
+    v1 = v2 | v3;
+    v1 = v2 ^ v3;
+    static assert(!__traits(compiles, v1 ~ v2));
+    static assert(!__traits(compiles, v1 ^^ v2));
+    static assert(!__traits(compiles, v1 is v2));
+    static assert(!__traits(compiles, v1 !is v2));
+    static assert(!__traits(compiles, v1 == v2));
+    static assert(!__traits(compiles, v1 != v2));
+    static assert(!__traits(compiles, v1 < v2));
+    static assert(!__traits(compiles, v1 > v2));
+    static assert(!__traits(compiles, v1 <= v2));
+    static assert(!__traits(compiles, v1 >= v2));
+    static assert(!__traits(compiles, v1 <> v2));
+    static assert(!__traits(compiles, v1 !< v2));
+    static assert(!__traits(compiles, v1 !> v2));
+    static assert(!__traits(compiles, v1 !<> v2));
+    static assert(!__traits(compiles, v1 <>= v2));
+    static assert(!__traits(compiles, v1 !<= v2));
+    static assert(!__traits(compiles, v1 !>= v2));
+    static assert(!__traits(compiles, v1 !<>= v2));
+    v1 = v2 << 1;
+    v1 = v2 >> 1;
+    v1 = v2 >>> 1;
+    static assert(!__traits(compiles, v1 && v2));
+    static assert(!__traits(compiles, v1 || v2));
+    v1 = ~v2;
+    v1 = -v2;
+    v1 = +v2;
+    static assert(!__traits(compiles, !v1));
+
+    v1 += v2;
+    v1 -= v2;
+    v1 *= v2;
+    v1 /= v2;
+    v1 %= v2;
+    v1 &= v2;
+    v1 |= v2;
+    v1 ^= v2;
+    static assert(!__traits(compiles, v1 ~= v2));
+    static assert(!__traits(compiles, v1 ^^= v2));
+    v1 <<= 1;
+    v1 >>= 1;
+    v1 >>>= 1;
+
+    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.
+    static assert(!__traits(compiles, cast(byte)v1));       // 1byte
+    static assert(!__traits(compiles, cast(short)v1));      // 2byte
+    static assert(!__traits(compiles, cast(int)v1));        // 4byte
+    static assert(!__traits(compiles, cast(long)v1));       // 8byte
+    static assert(!__traits(compiles, cast(float)v1));      // 4byte
+    static assert(!__traits(compiles, cast(double)v1));     // 8byte
+    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray
+    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK
+    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK
+}
+
+/*****************************************/
+
+void test2c()
+{
+    short8 v1, v2 = 1, v3 = 1;
+    v1 = v2;
+    v1 = v2 + v3;
+    v1 = v2 - v3;
+    v1 = v2 * v3;
+    v1 = v2 / v3;
+    v1 = v2 % v3;
+    v1 = v2 & v3;
+    v1 = v2 | v3;
+    v1 = v2 ^ v3;
+    static assert(!__traits(compiles, v1 ~ v2));
+    static assert(!__traits(compiles, v1 ^^ v2));
+    static assert(!__traits(compiles, v1 is v2));
+    static assert(!__traits(compiles, v1 !is v2));
+    static assert(!__traits(compiles, v1 == v2));
+    static assert(!__traits(compiles, v1 != v2));
+    static assert(!__traits(compiles, v1 < v2));
+    static assert(!__traits(compiles, v1 > v2));
+    static assert(!__traits(compiles, v1 <= v2));
+    static assert(!__traits(compiles, v1 >= v2));
+    static assert(!__traits(compiles, v1 <> v2));
+    static assert(!__traits(compiles, v1 !< v2));
+    static assert(!__traits(compiles, v1 !> v2));
+    static assert(!__traits(compiles, v1 !<> v2));
+    static assert(!__traits(compiles, v1 <>= v2));
+    static assert(!__traits(compiles, v1 !<= v2));
+    static assert(!__traits(compiles, v1 !>= v2));
+    static assert(!__traits(compiles, v1 !<>= v2));
+    v1 = v2 << 1;
+    v1 = v2 >> 1;
+    v1 = v2 >>> 1;
+    static assert(!__traits(compiles, v1 && v2));
+    static assert(!__traits(compiles, v1 || v2));
+    v1 = ~v2;
+    v1 = -v2;
+    v1 = +v2;
+    static assert(!__traits(compiles, !v1));
+
+    v1 += v2;
+    v1 -= v2;
+    v1 *= v2;
+    v1 /= v2;
+    v1 %= v2;
+    v1 &= v2;
+    v1 |= v2;
+    v1 ^= v2;
+    static assert(!__traits(compiles, v1 ~= v2));
+    static assert(!__traits(compiles, v1 ^^= v2));
+    v1 <<= 1;
+    v1 >>= 1;
+    v1 >>>= 1;
+    v1 = v1 * 3;
+
+    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.
+    static assert(!__traits(compiles, cast(byte)v1));       // 1byte
+    static assert(!__traits(compiles, cast(short)v1));      // 2byte
+    static assert(!__traits(compiles, cast(int)v1));        // 4byte
+    static assert(!__traits(compiles, cast(long)v1));       // 8byte
+    static assert(!__traits(compiles, cast(float)v1));      // 4byte
+    static assert(!__traits(compiles, cast(double)v1));     // 8byte
+    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray
+    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK
+    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK
+}
+
+/*****************************************/
+
+void test2d()
+{
+    ushort8 v1, v2 = 1, v3 = 1;
+    v1 = v2;
+    v1 = v2 + v3;
+    v1 = v2 - v3;
+    v1 = v2 * v3;
+    v1 = v2 / v3;
+    v1 = v2 % v3;
+    v1 = v2 & v3;
+    v1 = v2 | v3;
+    v1 = v2 ^ v3;
+    static assert(!__traits(compiles, v1 ~ v2));
+    static assert(!__traits(compiles, v1 ^^ v2));
+    static assert(!__traits(compiles, v1 is v2));
+    static assert(!__traits(compiles, v1 !is v2));
+    static assert(!__traits(compiles, v1 == v2));
+    static assert(!__traits(compiles, v1 != v2));
+    static assert(!__traits(compiles, v1 < v2));
+    static assert(!__traits(compiles, v1 > v2));
+    static assert(!__traits(compiles, v1 <= v2));
+    static assert(!__traits(compiles, v1 >= v2));
+    static assert(!__traits(compiles, v1 <> v2));
+    static assert(!__traits(compiles, v1 !< v2));
+    static assert(!__traits(compiles, v1 !> v2));
+    static assert(!__traits(compiles, v1 !<> v2));
+    static assert(!__traits(compiles, v1 <>= v2));
+    static assert(!__traits(compiles, v1 !<= v2));
+    static assert(!__traits(compiles, v1 !>= v2));
+    static assert(!__traits(compiles, v1 !<>= v2));
+    v1 = v2 << 1;
+    v1 = v2 >> 1;
+    v1 = v2 >>> 1;
+    static assert(!__traits(compiles, v1 && v2));
+    static assert(!__traits(compiles, v1 || v2));
+    v1 = ~v2;
+    v1 = -v2;
+    v1 = +v2;
+    static assert(!__traits(compiles, !v1));
+
+    v1 += v2;
+    v1 -= v2;
+    v1 *= v2;
+    v1 /= v2;
+    v1 %= v2;
+    v1 &= v2;
+    v1 |= v2;
+    v1 ^= v2;
+    static assert(!__traits(compiles, v1 ~= v2));
+    static assert(!__traits(compiles, v1 ^^= v2));
+    v1 <<= 1;
+    v1 >>= 1;
+    v1 >>>= 1;
+
+    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.
+    static assert(!__traits(compiles, cast(byte)v1));       // 1byte
+    static assert(!__traits(compiles, cast(short)v1));      // 2byte
+    static assert(!__traits(compiles, cast(int)v1));        // 4byte
+    static assert(!__traits(compiles, cast(long)v1));       // 8byte
+    static assert(!__traits(compiles, cast(float)v1));      // 4byte
+    static assert(!__traits(compiles, cast(double)v1));     // 8byte
+    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray
+    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK
+    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK
+}
+
+/*****************************************/
+
+void test2e()
+{
+    int4 v1, v2 = 1, v3 = 1;
+    v1 = v2;
+    v1 = v2 + v3;
+    v1 = v2 - v3;
+    v1 = v2 * v3;
+    v1 = v2 / v3;
+    v1 = v2 % v3;
+    v1 = v2 & v3;
+    v1 = v2 | v3;
+    v1 = v2 ^ v3;
+    static assert(!__traits(compiles, v1 ~ v2));
+    static assert(!__traits(compiles, v1 ^^ v2));
+    static assert(!__traits(compiles, v1 is v2));
+    static assert(!__traits(compiles, v1 !is v2));
+    static assert(!__traits(compiles, v1 == v2));
+    static assert(!__traits(compiles, v1 != v2));
+    static assert(!__traits(compiles, v1 < v2));
+    static assert(!__traits(compiles, v1 > v2));
+    static assert(!__traits(compiles, v1 <= v2));
+    static assert(!__traits(compiles, v1 >= v2));
+    static assert(!__traits(compiles, v1 <> v2));
+    static assert(!__traits(compiles, v1 !< v2));
+    static assert(!__traits(compiles, v1 !> v2));
+    static assert(!__traits(compiles, v1 !<> v2));
+    static assert(!__traits(compiles, v1 <>= v2));
+    static assert(!__traits(compiles, v1 !<= v2));
+    static assert(!__traits(compiles, v1 !>= v2));
+    static assert(!__traits(compiles, v1 !<>= v2));
+    v1 = v2 << 1;
+    v1 = v2 >> 1;
+    v1 = v2 >>> 1;
+    static assert(!__traits(compiles, v1 && v2));
+    static assert(!__traits(compiles, v1 || v2));
+    v1 = ~v2;
+    v1 = -v2;
+    v1 = +v2;
+    static assert(!__traits(compiles, !v1));
+
+    v1 += v2;
+    v1 -= v2;
+    v1 *= v2;
+    v1 /= v2;
+    v1 %= v2;
+    v1 &= v2;
+    v1 |= v2;
+    v1 ^= v2;
+    static assert(!__traits(compiles, v1 ~= v2));
+    static assert(!__traits(compiles, v1 ^^= v2));
+    v1 <<= 1;
+    v1 >>= 1;
+    v1 >>>= 1;
+
+    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.
+    static assert(!__traits(compiles, cast(byte)v1));       // 1byte
+    static assert(!__traits(compiles, cast(short)v1));      // 2byte
+    static assert(!__traits(compiles, cast(int)v1));        // 4byte
+    static assert(!__traits(compiles, cast(long)v1));       // 8byte
+    static assert(!__traits(compiles, cast(float)v1));      // 4byte
+    static assert(!__traits(compiles, cast(double)v1));     // 8byte
+    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray
+    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK
+    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK
+}
+
+/*****************************************/
+
+void test2f()
+{
+    uint4 v1, v2 = 1, v3 = 1;
+    v1 = v2;
+    v1 = v2 + v3;
+    v1 = v2 - v3;
+    v1 = v2 * v3;
+    v1 = v2 / v3;
+    v1 = v2 % v3;
+    v1 = v2 & v3;
+    v1 = v2 | v3;
+    v1 = v2 ^ v3;
+    static assert(!__traits(compiles, v1 ~ v2));
+    static assert(!__traits(compiles, v1 ^^ v2));
+    static assert(!__traits(compiles, v1 is v2));
+    static assert(!__traits(compiles, v1 !is v2));
+    static assert(!__traits(compiles, v1 == v2));
+    static assert(!__traits(compiles, v1 != v2));
+    static assert(!__traits(compiles, v1 < v2));
+    static assert(!__traits(compiles, v1 > v2));
+    static assert(!__traits(compiles, v1 <= v2));
+    static assert(!__traits(compiles, v1 >= v2));
+    static assert(!__traits(compiles, v1 <> v2));
+    static assert(!__traits(compiles, v1 !< v2));
+    static assert(!__traits(compiles, v1 !> v2));
+    static assert(!__traits(compiles, v1 !<> v2));
+    static assert(!__traits(compiles, v1 <>= v2));
+    static assert(!__traits(compiles, v1 !<= v2));
+    static assert(!__traits(compiles, v1 !>= v2));
+    static assert(!__traits(compiles, v1 !<>= v2));
+    v1 = v2 << 1;
+    v1 = v2 >> 1;
+    v1 = v2 >>> 1;
+    static assert(!__traits(compiles, v1 && v2));
+    static assert(!__traits(compiles, v1 || v2));
+    v1 = ~v2;
+    v1 = -v2;
+    v1 = +v2;
+    static assert(!__traits(compiles, !v1));
+
+    v1 += v2;
+    v1 -= v2;
+    v1 *= v2;
+    v1 /= v2;
+    v1 %= v2;
+    v1 &= v2;
+    v1 |= v2;
+    v1 ^= v2;
+    static assert(!__traits(compiles, v1 ~= v2));
+    static assert(!__traits(compiles, v1 ^^= v2));
+    v1 <<= 1;
+    v1 >>= 1;
+    v1 >>>= 1;
+
+    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.
+    static assert(!__traits(compiles, cast(byte)v1));       // 1byte
+    static assert(!__traits(compiles, cast(short)v1));      // 2byte
+    static assert(!__traits(compiles, cast(int)v1));        // 4byte
+    static assert(!__traits(compiles, cast(long)v1));       // 8byte
+    static assert(!__traits(compiles, cast(float)v1));      // 4byte
+    static assert(!__traits(compiles, cast(double)v1));     // 8byte
+    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray
+    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK
+    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK
+}
+
+/*****************************************/
+
+void test2g()
+{
+    long2 v1, v2 = 1, v3 = 1;
+    v1 = v2;
+    v1 = v2 + v3;
+    v1 = v2 - v3;
+    v1 = v2 * v3;
+    v1 = v2 / v3;
+    v1 = v2 % v3;
+    v1 = v2 & v3;
+    v1 = v2 | v3;
+    v1 = v2 ^ v3;
+    static assert(!__traits(compiles, v1 ~ v2));
+    static assert(!__traits(compiles, v1 ^^ v2));
+    static assert(!__traits(compiles, v1 is v2));
+    static assert(!__traits(compiles, v1 !is v2));
+    static assert(!__traits(compiles, v1 == v2));
+    static assert(!__traits(compiles, v1 != v2));
+    static assert(!__traits(compiles, v1 < v2));
+    static assert(!__traits(compiles, v1 > v2));
+    static assert(!__traits(compiles, v1 <= v2));
+    static assert(!__traits(compiles, v1 >= v2));
+    static assert(!__traits(compiles, v1 <> v2));
+    static assert(!__traits(compiles, v1 !< v2));
+    static assert(!__traits(compiles, v1 !> v2));
+    static assert(!__traits(compiles, v1 !<> v2));
+    static assert(!__traits(compiles, v1 <>= v2));
+    static assert(!__traits(compiles, v1 !<= v2));
+    static assert(!__traits(compiles, v1 !>= v2));
+    static assert(!__traits(compiles, v1 !<>= v2));
+    v1 = v2 << 1;
+    v1 = v2 >> 1;
+    v1 = v2 >>> 1;
+    static assert(!__traits(compiles, v1 && v2));
+    static assert(!__traits(compiles, v1 || v2));
+    v1 = ~v2;
+    v1 = -v2;
+    v1 = +v2;
+    static assert(!__traits(compiles, !v1));
+
+    v1 += v2;
+    v1 -= v2;
+    v1 *= v2;
+    v1 /= v2;
+    v1 %= v2;
+    v1 &= v2;
+    v1 |= v2;
+    v1 ^= v2;
+    static assert(!__traits(compiles, v1 ~= v2));
+    static assert(!__traits(compiles, v1 ^^= v2));
+    v1 <<= 1;
+    v1 >>= 1;
+    v1 >>>= 1;
+
+    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.
+    static assert(!__traits(compiles, cast(byte)v1));       // 1byte
+    static assert(!__traits(compiles, cast(short)v1));      // 2byte
+    static assert(!__traits(compiles, cast(int)v1));        // 4byte
+    static assert(!__traits(compiles, cast(long)v1));       // 8byte
+    static assert(!__traits(compiles, cast(float)v1));      // 4byte
+    static assert(!__traits(compiles, cast(double)v1));     // 8byte
+    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray
+    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK
+    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK
+}
+
+/*****************************************/
+
+void test2h()
+{
+    ulong2 v1, v2 = 1, v3 = 1;
+    v1 = v2;
+    v1 = v2 + v3;
+    v1 = v2 - v3;
+    v1 = v2 * v3;
+    v1 = v2 / v3;
+    v1 = v2 % v3;
+    v1 = v2 & v3;
+    v1 = v2 | v3;
+    v1 = v2 ^ v3;
+    static assert(!__traits(compiles, v1 ~ v2));
+    static assert(!__traits(compiles, v1 ^^ v2));
+    static assert(!__traits(compiles, v1 is v2));
+    static assert(!__traits(compiles, v1 !is v2));
+    static assert(!__traits(compiles, v1 == v2));
+    static assert(!__traits(compiles, v1 != v2));
+    static assert(!__traits(compiles, v1 < v2));
+    static assert(!__traits(compiles, v1 > v2));
+    static assert(!__traits(compiles, v1 <= v2));
+    static assert(!__traits(compiles, v1 >= v2));
+    static assert(!__traits(compiles, v1 <> v2));
+    static assert(!__traits(compiles, v1 !< v2));
+    static assert(!__traits(compiles, v1 !> v2));
+    static assert(!__traits(compiles, v1 !<> v2));
+    static assert(!__traits(compiles, v1 <>= v2));
+    static assert(!__traits(compiles, v1 !<= v2));
+    static assert(!__traits(compiles, v1 !>= v2));
+    static assert(!__traits(compiles, v1 !<>= v2));
+    v1 = v2 << 1;
+    v1 = v2 >> 1;
+    v1 = v2 >>> 1;
+    static assert(!__traits(compiles, v1 && v2));
+    static assert(!__traits(compiles, v1 || v2));
+    v1 = ~v2;
+    v1 = -v2;
+    v1 = +v2;
+    static assert(!__traits(compiles, !v1));
+
+    v1 += v2;
+    v1 -= v2;
+    v1 *= v2;
+    v1 /= v2;
+    v1 %= v2;
+    v1 &= v2;
+    v1 |= v2;
+    v1 ^= v2;
+    static assert(!__traits(compiles, v1 ~= v2));
+    static assert(!__traits(compiles, v1 ^^= v2));
+    v1 <<= 1;
+    v1 >>= 1;
+    v1 >>>= 1;
+
+    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.
+    static assert(!__traits(compiles, cast(byte)v1));       // 1byte
+    static assert(!__traits(compiles, cast(short)v1));      // 2byte
+    static assert(!__traits(compiles, cast(int)v1));        // 4byte
+    static assert(!__traits(compiles, cast(long)v1));       // 8byte
+    static assert(!__traits(compiles, cast(float)v1));      // 4byte
+    static assert(!__traits(compiles, cast(double)v1));     // 8byte
+    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray
+    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK
+    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK
+}
+
+/*****************************************/
+
+void test2i()
+{
+    float4 v1, v2 = 1, v3 = 1;
+    v1 = v2;
+    v1 = v2 + v3;
+    v1 = v2 - v3;
+    v1 = v2 * v3;
+    v1 = v2 / v3;
+    static assert(!__traits(compiles, v1 % v2));
+    static assert(!__traits(compiles, v1 & v2));
+    static assert(!__traits(compiles, v1 | v2));
+    static assert(!__traits(compiles, v1 ^ v2));
+    static assert(!__traits(compiles, v1 ~ v2));
+    static assert(!__traits(compiles, v1 ^^ v2));
+    static assert(!__traits(compiles, v1 is v2));
+    static assert(!__traits(compiles, v1 !is v2));
+    static assert(!__traits(compiles, v1 == v2));
+    static assert(!__traits(compiles, v1 != v2));
+    static assert(!__traits(compiles, v1 < v2));
+    static assert(!__traits(compiles, v1 > v2));
+    static assert(!__traits(compiles, v1 <= v2));
+    static assert(!__traits(compiles, v1 >= v2));
+    static assert(!__traits(compiles, v1 <> v2));
+    static assert(!__traits(compiles, v1 !< v2));
+    static assert(!__traits(compiles, v1 !> v2));
+    static assert(!__traits(compiles, v1 !<> v2));
+    static assert(!__traits(compiles, v1 <>= v2));
+    static assert(!__traits(compiles, v1 !<= v2));
+    static assert(!__traits(compiles, v1 !>= v2));
+    static assert(!__traits(compiles, v1 !<>= v2));
+    static assert(!__traits(compiles, v1 << 1));
+    static assert(!__traits(compiles, v1 >> 1));
+    static assert(!__traits(compiles, v1 >>> 1));
+    static assert(!__traits(compiles, v1 && v2));
+    static assert(!__traits(compiles, v1 || v2));
+    static assert(!__traits(compiles, ~v1));
+    v1 = -v2;
+    v1 = +v2;
+    static assert(!__traits(compiles, !v1));
+
+    v1 += v2;
+    v1 -= v2;
+    v1 *= v2;
+    v1 /= v2;
+    static assert(!__traits(compiles, v1 %= v2));
+    static assert(!__traits(compiles, v1 &= v2));
+    static assert(!__traits(compiles, v1 |= v2));
+    static assert(!__traits(compiles, v1 ^= v2));
+    static assert(!__traits(compiles, v1 ~= v2));
+    static assert(!__traits(compiles, v1 ^^= v2));
+    static assert(!__traits(compiles, v1 <<= 1));
+    static assert(!__traits(compiles, v1 >>= 1));
+    static assert(!__traits(compiles, v1 >>>= 1));
+
+    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.
+    static assert(!__traits(compiles, cast(byte)v1));       // 1byte
+    static assert(!__traits(compiles, cast(short)v1));      // 2byte
+    static assert(!__traits(compiles, cast(int)v1));        // 4byte
+    static assert(!__traits(compiles, cast(long)v1));       // 8byte
+    static assert(!__traits(compiles, cast(float)v1));      // 4byte
+    static assert(!__traits(compiles, cast(double)v1));     // 8byte
+    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray
+    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK
+    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK
+}
+
+/*****************************************/
+
+void test2j()
+{
+    double2 v1, v2 = 1, v3 = 1;
+    v1 = v2;
+    v1 = v2 + v3;
+    v1 = v2 - v3;
+    v1 = v2 * v3;
+    v1 = v2 / v3;
+    static assert(!__traits(compiles, v1 % v2));
+    static assert(!__traits(compiles, v1 & v2));
+    static assert(!__traits(compiles, v1 | v2));
+    static assert(!__traits(compiles, v1 ^ v2));
+    static assert(!__traits(compiles, v1 ~ v2));
+    static assert(!__traits(compiles, v1 ^^ v2));
+    static assert(!__traits(compiles, v1 is v2));
+    static assert(!__traits(compiles, v1 !is v2));
+    static assert(!__traits(compiles, v1 == v2));
+    static assert(!__traits(compiles, v1 != v2));
+    static assert(!__traits(compiles, v1 < v2));
+    static assert(!__traits(compiles, v1 > v2));
+    static assert(!__traits(compiles, v1 <= v2));
+    static assert(!__traits(compiles, v1 >= v2));
+    static assert(!__traits(compiles, v1 <> v2));
+    static assert(!__traits(compiles, v1 !< v2));
+    static assert(!__traits(compiles, v1 !> v2));
+    static assert(!__traits(compiles, v1 !<> v2));
+    static assert(!__traits(compiles, v1 <>= v2));
+    static assert(!__traits(compiles, v1 !<= v2));
+    static assert(!__traits(compiles, v1 !>= v2));
+    static assert(!__traits(compiles, v1 !<>= v2));
+    static assert(!__traits(compiles, v1 << 1));
+    static assert(!__traits(compiles, v1 >> 1));
+    static assert(!__traits(compiles, v1 >>> 1));
+    static assert(!__traits(compiles, v1 && v2));
+    static assert(!__traits(compiles, v1 || v2));
+    static assert(!__traits(compiles, ~v1));
+    v1 = -v2;
+    v1 = +v2;
+    static assert(!__traits(compiles, !v1));
+
+    v1 += v2;
+    v1 -= v2;
+    v1 *= v2;
+    v1 /= v2;
+    static assert(!__traits(compiles, v1 %= v2));
+    static assert(!__traits(compiles, v1 &= v2));
+    static assert(!__traits(compiles, v1 |= v2));
+    static assert(!__traits(compiles, v1 ^= v2));
+    static assert(!__traits(compiles, v1 ~= v2));
+    static assert(!__traits(compiles, v1 ^^= v2));
+    static assert(!__traits(compiles, v1 <<= 1));
+    static assert(!__traits(compiles, v1 >>= 1));
+    static assert(!__traits(compiles, v1 >>>= 1));
+
+    //  A cast from vector to non-vector is allowed only when the target is same size Tsarray.
+    static assert(!__traits(compiles, cast(byte)v1));       // 1byte
+    static assert(!__traits(compiles, cast(short)v1));      // 2byte
+    static assert(!__traits(compiles, cast(int)v1));        // 4byte
+    static assert(!__traits(compiles, cast(long)v1));       // 8byte
+    static assert(!__traits(compiles, cast(float)v1));      // 4byte
+    static assert(!__traits(compiles, cast(double)v1));     // 8byte
+    static assert(!__traits(compiles, cast(int[2])v1));     // 8byte Tsarray
+    static assert( __traits(compiles, cast(int[4])v1));     // 16byte Tsarray, OK
+    static assert( __traits(compiles, cast(long[2])v1));    // 16byte Tsarray, OK
+}
+
+/*****************************************/
+
+void test4()
+{
+    int4 c = 7;
+    (cast(int[4])c)[3] = 4;
+    (cast(int*)&c)[2] = 4;
+    c.array[1] = 4;
+    c.ptr[3] = 4;
+    assert(c.length == 4);
+}
+
+/*****************************************/
+
+void BaseTypeOfVector(T : __vector(T[N]), size_t N)(int i)
+{
+    assert(is(T == int));
+    assert(N == 4);
+}
+
+
+void test7411()
+{
+    BaseTypeOfVector!(__vector(int[4]))(3);
+}
+
+/*****************************************/
+// 7951
+
+float[4] test7951()
+{
+    float4 v1;
+    float4 v2;
+
+    return cast(float[4])(v1+v2);
+}
+
+/*****************************************/
+
+void test7951_2()
+{
+    float[4] v1 = [1,2,3,4];
+    float[4] v2 = [1,2,3,4];
+    float4 f1, f2, f3;
+    f1.array = v1;
+    f2.array = v2;
+    f3 = f1 + f2;
+}
+
+/*****************************************/
+
+immutable ulong2 gulong2 = 0x8000_0000_0000_0000;
+immutable uint4 guint4 = 0x8000_0000;
+immutable ushort8 gushort8 = 0x8000;
+immutable ubyte16 gubyte16 = 0x80;
+
+immutable long2 glong2 = 0x7000_0000_0000_0000;
+immutable int4 gint4 = 0x7000_0000;
+immutable short8 gshort8 = 0x7000;
+immutable byte16 gbyte16 = 0x70;
+
+immutable float4 gfloat4 = 4.0;
+immutable double2 gdouble2 = 8.0;
+
+void test7414()
+{
+    immutable ulong2 lulong2 = 0x8000_0000_0000_0000;
+    assert(memcmp(&lulong2, &gulong2, gulong2.sizeof) == 0);
+
+    immutable uint4 luint4 = 0x8000_0000;
+    assert(memcmp(&luint4, &guint4, guint4.sizeof) == 0);
+
+    immutable ushort8 lushort8 = 0x8000;
+    assert(memcmp(&lushort8, &gushort8, gushort8.sizeof) == 0);
+
+    immutable ubyte16 lubyte16 = 0x80;
+    assert(memcmp(&lubyte16, &gubyte16, gubyte16.sizeof) == 0);
+
+
+    immutable long2 llong2 = 0x7000_0000_0000_0000;
+    assert(memcmp(&llong2, &glong2, glong2.sizeof) == 0);
+
+    immutable int4 lint4 = 0x7000_0000;
+    assert(memcmp(&lint4, &gint4, gint4.sizeof) == 0);
+
+    immutable short8 lshort8 = 0x7000;
+    assert(memcmp(&lshort8, &gshort8, gshort8.sizeof) == 0);
+
+    immutable byte16 lbyte16 = 0x70;
+    assert(memcmp(&lbyte16, &gbyte16, gbyte16.sizeof) == 0);
+
+
+    immutable float4 lfloat4 = 4.0;
+    assert(memcmp(&lfloat4, &gfloat4, gfloat4.sizeof) == 0);
+
+    immutable double2 ldouble2 = 8.0;
+    assert(memcmp(&ldouble2, &gdouble2, gdouble2.sizeof) == 0);
+}
+
+/*****************************************/
+
+void test7413()
+{
+    byte16 b = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
+    assert(b.array[0] == 1);
+    assert(b.array[1] == 2);
+    assert(b.array[2] == 3);
+    assert(b.array[3] == 4);
+    assert(b.array[4] == 5);
+    assert(b.array[5] == 6);
+    assert(b.array[6] == 7);
+    assert(b.array[7] == 8);
+    assert(b.array[8] == 9);
+    assert(b.array[9] == 10);
+    assert(b.array[10] == 11);
+    assert(b.array[11] == 12);
+    assert(b.array[12] == 13);
+    assert(b.array[13] == 14);
+    assert(b.array[14] == 15);
+    assert(b.array[15] == 16);
+
+    ubyte16 ub = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
+    assert(ub.array[0] == 1);
+    assert(ub.array[1] == 2);
+    assert(ub.array[2] == 3);
+    assert(ub.array[3] == 4);
+    assert(ub.array[4] == 5);
+    assert(ub.array[5] == 6);
+    assert(ub.array[6] == 7);
+    assert(ub.array[7] == 8);
+    assert(ub.array[8] == 9);
+    assert(ub.array[9] == 10);
+    assert(ub.array[10] == 11);
+    assert(ub.array[11] == 12);
+    assert(ub.array[12] == 13);
+    assert(ub.array[13] == 14);
+    assert(ub.array[14] == 15);
+    assert(ub.array[15] == 16);
+
+    short8 s = [1,2,3,4,5,6,7,8];
+    assert(s.array[0] == 1);
+    assert(s.array[1] == 2);
+    assert(s.array[2] == 3);
+    assert(s.array[3] == 4);
+    assert(s.array[4] == 5);
+    assert(s.array[5] == 6);
+    assert(s.array[6] == 7);
+    assert(s.array[7] == 8);
+
+    ushort8 us = [1,2,3,4,5,6,7,8];
+    assert(us.array[0] == 1);
+    assert(us.array[1] == 2);
+    assert(us.array[2] == 3);
+    assert(us.array[3] == 4);
+    assert(us.array[4] == 5);
+    assert(us.array[5] == 6);
+    assert(us.array[6] == 7);
+    assert(us.array[7] == 8);
+
+    int4 i = [1,2,3,4];
+    assert(i.array[0] == 1);
+    assert(i.array[1] == 2);
+    assert(i.array[2] == 3);
+    assert(i.array[3] == 4);
+
+    uint4 ui = [1,2,3,4];
+    assert(ui.array[0] == 1);
+    assert(ui.array[1] == 2);
+    assert(ui.array[2] == 3);
+    assert(ui.array[3] == 4);
+
+    long2 l = [1,2];
+    assert(l.array[0] == 1);
+    assert(l.array[1] == 2);
+
+    ulong2 ul = [1,2];
+    assert(ul.array[0] == 1);
+    assert(ul.array[1] == 2);
+
+    float4 f = [1,2,3,4];
+    assert(f.array[0] == 1);
+    assert(f.array[1] == 2);
+    assert(f.array[2] == 3);
+    assert(f.array[3] == 4);
+
+    double2 d = [1,2];
+    assert(d.array[0] == 1);
+    assert(d.array[1] == 2);
+}
+
+/*****************************************/
+
+byte16 b = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
+ubyte16 ub = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
+short8 s = [1,2,3,4,5,6,7,8];
+ushort8 us = [1,2,3,4,5,6,7,8];
+int4 i = [1,2,3,4];
+uint4 ui = [1,2,3,4];
+long2 l = [1,2];
+ulong2 ul = [1,2];
+float4 f = [1,2,3,4];
+double2 d = [1,2];
+
+void test7413_2()
+{
+    assert(b.array[0] == 1);
+    assert(b.array[1] == 2);
+    assert(b.array[2] == 3);
+    assert(b.array[3] == 4);
+    assert(b.array[4] == 5);
+    assert(b.array[5] == 6);
+    assert(b.array[6] == 7);
+    assert(b.array[7] == 8);
+    assert(b.array[8] == 9);
+    assert(b.array[9] == 10);
+    assert(b.array[10] == 11);
+    assert(b.array[11] == 12);
+    assert(b.array[12] == 13);
+    assert(b.array[13] == 14);
+    assert(b.array[14] == 15);
+    assert(b.array[15] == 16);
+
+    assert(ub.array[0] == 1);
+    assert(ub.array[1] == 2);
+    assert(ub.array[2] == 3);
+    assert(ub.array[3] == 4);
+    assert(ub.array[4] == 5);
+    assert(ub.array[5] == 6);
+    assert(ub.array[6] == 7);
+    assert(ub.array[7] == 8);
+    assert(ub.array[8] == 9);
+    assert(ub.array[9] == 10);
+    assert(ub.array[10] == 11);
+    assert(ub.array[11] == 12);
+    assert(ub.array[12] == 13);
+    assert(ub.array[13] == 14);
+    assert(ub.array[14] == 15);
+    assert(ub.array[15] == 16);
+
+    assert(s.array[0] == 1);
+    assert(s.array[1] == 2);
+    assert(s.array[2] == 3);
+    assert(s.array[3] == 4);
+    assert(s.array[4] == 5);
+    assert(s.array[5] == 6);
+    assert(s.array[6] == 7);
+    assert(s.array[7] == 8);
+
+    assert(us.array[0] == 1);
+    assert(us.array[1] == 2);
+    assert(us.array[2] == 3);
+    assert(us.array[3] == 4);
+    assert(us.array[4] == 5);
+    assert(us.array[5] == 6);
+    assert(us.array[6] == 7);
+    assert(us.array[7] == 8);
+
+    assert(i.array[0] == 1);
+    assert(i.array[1] == 2);
+    assert(i.array[2] == 3);
+    assert(i.array[3] == 4);
+
+    assert(ui.array[0] == 1);
+    assert(ui.array[1] == 2);
+    assert(ui.array[2] == 3);
+    assert(ui.array[3] == 4);
+
+    assert(l.array[0] == 1);
+    assert(l.array[1] == 2);
+
+    assert(ul.array[0] == 1);
+    assert(ul.array[1] == 2);
+
+    assert(f.array[0] == 1);
+    assert(f.array[1] == 2);
+    assert(f.array[2] == 3);
+    assert(f.array[3] == 4);
+
+    assert(d.array[0] == 1);
+    assert(d.array[1] == 2);
+}
+
+/*****************************************/
+
+float bug8060(float x) {
+    int i = *cast(int*)&x;
+    ++i;
+    return *cast(float*)&i;
+}
+
+/*****************************************/
+/+
+// 9200
+
+void bar9200(double[2] a)
+{
+    assert(a[0] == 1);
+    assert(a[1] == 2);
+}
+
+double2 * v9200(double2* a)
+{
+    return a;
+}
+
+void test9200()
+{
+    double2 a = [1, 2];
+
+    *v9200(&a) = a;
+
+    bar9200(a.array);
+}
++/
+
+/*****************************************/
+
+// 9304 and 9322
+
+float4 foo9304(float4 a)
+{
+    return -a;
+}
+
+
+void test9304()
+{
+    auto a = foo9304([0, 1, 2, 3]);
+    //writeln(a.array);
+    assert(a.array == [0,-1,-2,-3]);
+}
+
+/*****************************************/
+
+void test9910()
+{
+    float4 f = [1, 1, 1, 1];
+    auto works = f + 3;
+    auto bug = 3 + f;
+
+    assert (works.array == [4,4,4,4]);
+    assert (bug.array == [4,4,4,4]);    // no property 'array' for type 'int'
+}
+
+/*****************************************/
+
+bool normalize(double[] range, double sum = 1)
+{
+    double s = 0;
+    const length = range.length;
+    foreach (e; range)
+    {
+        s += e;
+    }
+    if (s == 0)
+    {
+        return false;
+    }
+    return true;
+}
+
+void test12852()
+{
+    double[3] range = [0.0, 0.0, 0.0];
+    assert(normalize(range[]) == false);
+    range[1] = 3.0;
+    assert(normalize(range[]) == true);
+}
+
+/*****************************************/
+
+void test9449()
+{
+    ubyte16[1] table;
+}
+
+/*****************************************/
+
+void test9449_2()
+{
+    float[4][2] m = [[2.0, 1, 3, 4], [5.0, 6, 7, 8]];   // segfault
+
+    assert(m[0][0] == 2.0);
+    assert(m[0][1] == 1);
+    assert(m[0][2] == 3);
+    assert(m[0][3] == 4);
+
+    assert(m[1][0] == 5.0);
+    assert(m[1][1] == 6);
+    assert(m[1][2] == 7);
+    assert(m[1][3] == 8);
+}
+
+/*****************************************/
+// 13841
+
+void test13841()
+{
+    alias Vector16s = TypeTuple!(
+        void16,  byte16,  short8,  int4,  long2,
+                ubyte16, ushort8, uint4, ulong2, float4, double2);
+    foreach (V1; Vector16s)
+    {
+        foreach (V2; Vector16s)
+        {
+            V1 v1 = void;
+            V2 v2 = void;
+            static if (is(V1 == V2))
+            {
+                static assert( is(typeof(true ? v1 : v2) == V1));
+            }
+            else
+            {
+                static assert(!is(typeof(true ? v1 : v2)));
+            }
+        }
+    }
+}
+
+/*****************************************/
+// 12776
+
+void test12776()
+{
+    alias Vector16s = TypeTuple!(
+        void16,  byte16,  short8,  int4,  long2,
+                ubyte16, ushort8, uint4, ulong2, float4, double2);
+    foreach (V; Vector16s)
+    {
+        static assert(is(typeof(                   V .init) ==                    V ));
+        static assert(is(typeof(             const(V).init) ==              const(V)));
+        static assert(is(typeof(       inout(      V).init) ==        inout(      V)));
+        static assert(is(typeof(       inout(const V).init) ==        inout(const V)));
+        static assert(is(typeof(shared(            V).init) == shared(            V)));
+        static assert(is(typeof(shared(      const V).init) == shared(      const V)));
+        static assert(is(typeof(shared(inout       V).init) == shared(inout       V)));
+        static assert(is(typeof(shared(inout const V).init) == shared(inout const V)));
+        static assert(is(typeof(         immutable(V).init) ==          immutable(V)));
+    }
+}
+
+/*****************************************/
+
+void foo13988(double[] arr)
+{
+    static ulong repr(double d) { return *cast(ulong*)&d; }
+    foreach (x; arr)
+        assert(repr(arr[0]) == *cast(ulong*)&(arr[0]));
+}
+
+
+void test13988()
+{
+    double[] arr = [3.0];
+    foo13988(arr);
+}
+
+/*****************************************/
+// 15123
+
+void test15123()
+{
+    alias Vector16s = TypeTuple!(
+        void16,  byte16,  short8,  int4,  long2,
+                ubyte16, ushort8, uint4, ulong2, float4, double2);
+    foreach (V; Vector16s)
+    {
+        auto x = V.init;
+    }
+}
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=15144
+
+void test15144()
+{
+        enum      ubyte16 csXMM1 = ['a','b','c',0,0,0,0,0];
+        __gshared ubyte16 csXMM2 = ['a','b','c',0,0,0,0,0];
+        immutable ubyte16 csXMM3 = ['a','b','c',0,0,0,0,0];
+}
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=13927
+
+void test13927(ulong2 a)
+{
+    ulong2 b = [long.min, long.min];
+    auto tmp = a - b;
+}
+
+/*****************************************/
+
+// https://issues.dlang.org/show_bug.cgi?id=16488
+
+void foo_byte16(byte t, byte s)
+{
+    byte16 f = s;
+    auto p = cast(byte*)&f;
+    foreach (i; 0 .. 16)
+        assert(p[i] == s);
+}
+
+void foo_ubyte16(ubyte t, ubyte s)
+{
+    ubyte16 f = s;
+    auto p = cast(ubyte*)&f;
+    foreach (i; 0 .. 16)
+        assert(p[i] == s);
+}
+
+
+void foo_short8(short t, short s)
+{
+    short8 f = s;
+    auto p = cast(short*)&f;
+    foreach (i; 0 .. 8)
+        assert(p[i] == s);
+}
+
+void foo_ushort8(ushort t, ushort s)
+{
+    ushort8 f = s;
+    auto p = cast(ushort*)&f;
+    foreach (i; 0 .. 8)
+        assert(p[i] == s);
+}
+
+
+void foo_int4(int t, int s)
+{
+    int4 f = s;
+    auto p = cast(int*)&f;
+    foreach (i; 0 .. 4)
+        assert(p[i] == s);
+}
+
+void foo_uint4(uint t, uint s, uint u)
+{
+    uint4 f = s;
+    auto p = cast(uint*)&f;
+    foreach (i; 0 .. 4)
+        assert(p[i] == s);
+}
+
+
+void foo_long2(long t, long s, long u)
+{
+    long2 f = s;
+    auto p = cast(long*)&f;
+    foreach (i; 0 .. 2)
+        assert(p[i] == s);
+}
+
+void foo_ulong2(ulong t, ulong s)
+{
+    ulong2 f = s;
+    auto p = cast(ulong*)&f;
+    foreach (i; 0 .. 2)
+        assert(p[i] == s);
+}
+
+void foo_float4(float t, float s)
+{
+    float4 f = s;
+    auto p = cast(float*)&f;
+    foreach (i; 0 .. 4)
+        assert(p[i] == s);
+}
+
+void foo_double2(double t, double s, double u)
+{
+    double2 f = s;
+    auto p = cast(double*)&f;
+    foreach (i; 0 .. 2)
+        assert(p[i] == s);
+}
+
+
+void test16448()
+{
+    foo_byte16(5, -10);
+    foo_ubyte16(5, 11);
+
+    foo_short8(5, -6);
+    foo_short8(5, 7);
+
+    foo_int4(5, -6);
+    foo_uint4(5, 0x12345678, 22);
+
+    foo_long2(5, -6, 1);
+    foo_ulong2(5, 0x12345678_87654321L);
+
+    foo_float4(5, -6);
+    foo_double2(5, -6, 2);
+}
+
+/*****************************************/
+
+void foo_byte32(byte t, byte s)
+{
+    byte32 f = s;
+    auto p = cast(byte*)&f;
+    foreach (i; 0 .. 32)
+        assert(p[i] == s);
+}
+
+void foo_ubyte32(ubyte t, ubyte s)
+{
+    ubyte32 f = s;
+    auto p = cast(ubyte*)&f;
+    foreach (i; 0 .. 32)
+        assert(p[i] == s);
+}
+
+void foo_short16(short t, short s)
+{
+    short16 f = s;
+    auto p = cast(short*)&f;
+    foreach (i; 0 .. 16)
+        assert(p[i] == s);
+}
+
+void foo_ushort16(ushort t, ushort s)
+{
+    ushort16 f = s;
+    auto p = cast(ushort*)&f;
+    foreach (i; 0 .. 16)
+        assert(p[i] == s);
+}
+
+void foo_int8(int t, int s)
+{
+    int8 f = s;
+    auto p = cast(int*)&f;
+    foreach (i; 0 .. 8)
+        assert(p[i] == s);
+}
+
+void foo_uint8(uint t, uint s, uint u)
+{
+    uint8 f = s;
+    auto p = cast(uint*)&f;
+    foreach (i; 0 .. 8)
+        assert(p[i] == s);
+}
+
+void foo_long4(long t, long s, long u)
+{
+    long4 f = s;
+    auto p = cast(long*)&f;
+    foreach (i; 0 .. 4)
+        assert(p[i] == s);
+}
+
+void foo_ulong4(ulong t, ulong s)
+{
+    ulong4 f = s;
+    auto p = cast(ulong*)&f;
+    foreach (i; 0 .. 4)
+        assert(p[i] == s);
+}
+
+void foo_float8(float t, float s)
+{
+    float8 f = s;
+    auto p = cast(float*)&f;
+    foreach (i; 0 .. 8)
+        assert(p[i] == s);
+}
+
+void foo_double4(double t, double s, double u)
+{
+    double4 f = s;
+    auto p = cast(double*)&f;
+    foreach (i; 0 .. 4)
+        assert(p[i] == s);
+}
+
+void test16448_32()
+{
+    import core.cpuid;
+    if (!core.cpuid.avx)
+        return;
+
+    foo_byte32(5, -10);
+    foo_ubyte32(5, 11);
+
+    foo_short16(5, -6);
+    foo_short16(5, 7);
+
+    foo_int8(5, -6);
+    foo_uint8(5, 0x12345678, 22);
+
+    foo_long4(5, -6, 1);
+    foo_ulong4(5, 0x12345678_87654321L);
+
+    foo_float8(5, -6);
+    foo_double4(5, -6, 2);
+}
+
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=16703
+
+float index(float4 f4, size_t i)
+{
+    return f4[i];
+    //return (*cast(float[4]*)&f4)[2];
+}
+
+float[4] slice(float4 f4)
+{
+    return f4[];
+}
+
+float slice2(float4 f4, size_t lwr, size_t upr, size_t i)
+{
+    float[] fa = f4[lwr .. upr];
+    return fa[i];
+}
+
+void test16703()
+{
+    float4 f4 = [1,2,3,4];
+    assert(index(f4, 0) == 1);
+    assert(index(f4, 1) == 2);
+    assert(index(f4, 2) == 3);
+    assert(index(f4, 3) == 4);
+
+    float[4] fsa = slice(f4);
+    assert(fsa == [1.0f,2,3,4]);
+
+    assert(slice2(f4, 1, 3, 0) == 2);
+    assert(slice2(f4, 1, 3, 1) == 3);
+}
+
+/*****************************************/
+
+struct Sunsto
+{
+  align (1): // make sure f4 is misaligned
+    byte b;
+    union
+    {
+        float4 f4;
+        ubyte[16] a;
+    }
+}
+
+ubyte[16] foounsto()
+{
+    float4 vf = 6;
+    Sunsto s;
+    s.f4 = vf * 2;
+    vf = s.f4;
+
+    return s.a;
+}
+
+void testOPvecunsto()
+{
+    auto a = foounsto();
+    assert(a == [0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65]);
+}
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=10447
+
+void test10447()
+{
+    immutable __vector(double[2]) a = [1.0, 2.0];
+    __vector(double[2]) r;
+    r += a;
+    r = r * a;
+}
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=17237
+
+struct S17237
+{
+    bool a;
+    struct
+    {
+        bool b;
+        int8 c;
+    }
+}
+
+static assert(S17237.a.offsetof == 0);
+static assert(S17237.b.offsetof == 32);
+static assert(S17237.c.offsetof == 64);
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=16697
+
+static assert(!is(float == __vector));
+static assert(!is(float[1] == __vector));
+static assert(!is(float[4] == __vector));
+static assert( is(__vector(float[4]) == __vector));
+static assert(!is(__vector(float[3]) == __vector));
+static assert(!is(__vector(float[5]) == __vector));
+static assert( is(__vector(float[4]) X == __vector) && is(X == float[4]));
+static assert( is(__vector(byte[16]) X == __vector) && is(X == byte[16]));
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=17720
+
+void test17720()
+{
+    alias Vector16s = TypeTuple!(
+        void16,  byte16,  short8,  int4,  long2,
+                ubyte16, ushort8, uint4, ulong2, float4, double2);
+    alias Vector32s = TypeTuple!(
+        void32,  byte32,  short16,  int8,  long4,
+                ubyte32, ushort16, uint8, ulong4, float8, double4);
+
+    // OK: __vector(T) -> __vector(void[]) of same size.
+    // NG: __vector(T) -> __vector(void[]) of different size.
+    // NG: explicit cast __vector(T) -> __vector(void[]) of different size.
+    foreach (V; Vector16s)
+    {
+        static assert( __traits(compiles, { void16 v = V.init; }));
+        static assert(!__traits(compiles, { void32 v = V.init; }));
+        static assert(!__traits(compiles, { void32 v = cast(void32)V.init; }));
+    }
+    foreach (V; Vector32s)
+    {
+        static assert( __traits(compiles, { void32 v = V.init; }));
+        static assert(!__traits(compiles, { void16 v = V.init; }));
+        static assert(!__traits(compiles, { void16 v = cast(void16)V.init; }));
+    }
+
+    // NG: __vector(T) -> __vector(T) of same size.
+    // OK: explicit cast __vector(T) -> __vector(T) of same size.
+    // NG: __vector(T) -> __vector(T) of different size.
+    // NG: explicit cast __vector(T) -> __vector(T) of different size.
+    foreach (V; Vector16s)
+    {
+        static if (is(V == double2))
+        {
+            static assert(!__traits(compiles, { long2 v = V.init; }));
+            static assert( __traits(compiles, { long2 v = cast(long2)V.init; }));
+        }
+        else
+        {
+            static assert(!__traits(compiles, { double2 v = V.init; }));
+            static assert( __traits(compiles, { double2 v = cast(double2)V.init; }));
+        }
+        static assert(!__traits(compiles, { double4 v = V.init; }));
+        static assert(!__traits(compiles, { double4 v = cast(double4)V.init; }));
+    }
+    foreach (V; Vector32s)
+    {
+        static if (is(V == double4))
+        {
+            static assert(!__traits(compiles, { long4 v = V.init; }));
+            static assert( __traits(compiles, { long4 v = cast(long4)V.init; }));
+        }
+        else
+        {
+            static assert(!__traits(compiles, { double4 v = V.init; }));
+            static assert( __traits(compiles, { double4 v = cast(double4)V.init; }));
+        }
+        static assert(!__traits(compiles, { double2 v = V.init; }));
+        static assert(!__traits(compiles, { double2 v = cast(double2)V.init; }));
+    }
+}
+
+/*****************************************/
+
+// https://issues.dlang.org/show_bug.cgi?id=17695
+
+void test17695(__vector(ubyte[16]) a)
+{
+    auto b = -a;
+}
+
+/*****************************************/
+
+int main()
+{
+    test1();
+    test2();
+    test2b();
+    test2c();
+    test2d();
+    test2e();
+    test2f();
+    test2g();
+    test2h();
+    test2i();
+    test2j();
+
+    test4();
+    test7411();
+
+    test7951();
+    test7951_2();
+    test7414();
+    test7413();
+    test7413_2();
+//    test9200();
+    test9304();
+    test9910();
+    test12852();
+    test9449();
+    test9449_2();
+    test13988();
+    test16448();
+    test16448_32();
+    test16703();
+    testOPvecunsto();
+    test10447();
+
+    return 0;
+}

Reply via email to