d/dmd: Merge upstream dmd 19b1454b5
authorIain Buclaw <ibuclaw@gdcproject.org>
Tue, 12 Mar 2019 23:10:49 +0000 (23:10 +0000)
committerIain Buclaw <ibuclaw@gcc.gnu.org>
Tue, 12 Mar 2019 23:10:49 +0000 (23:10 +0000)
Backports fixes for many ICEs that occurred when using the vector .array
property in both CTFE and code generation passes.

Fixes https://gcc.gnu.org/PR88957

Reviewed-on: https://github.com/dlang/dmd/pull/9438

gcc/d/ChangeLog:

2019-03-13  Iain Buclaw  <ibuclaw@gdcproject.org>

PR d/88957
* expr.cc (ExprVisitor::visit(VectorArrayExp)): New override.

gcc/testsuite/ChangeLog:

2019-03-13  Iain Buclaw  <ibuclaw@gdcproject.org>

PR d/88957
* gdc.dg/pr88957.d: New test.
* gdc.dg/simd.d: Add new vector tests.

From-SVN: r269627

17 files changed:
gcc/d/ChangeLog
gcc/d/dmd/MERGE
gcc/d/dmd/ctfeexpr.c
gcc/d/dmd/dinterpret.c
gcc/d/dmd/expression.c
gcc/d/dmd/expression.h
gcc/d/dmd/expressionsem.c
gcc/d/dmd/hdrgen.c
gcc/d/dmd/mtype.c
gcc/d/dmd/parse.c
gcc/d/dmd/tokens.c
gcc/d/dmd/tokens.h
gcc/d/dmd/visitor.h
gcc/d/expr.cc
gcc/testsuite/ChangeLog
gcc/testsuite/gdc.dg/pr88957.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/simd.d

index 6c96ec4bf5b66e9682806262fb2523f3ab9aa6f2..8e45c7ffff73d4f25e829eb585fe3c8d2b3b865d 100644 (file)
@@ -1,3 +1,8 @@
+2019-03-13  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+       PR d/88957
+       * expr.cc (ExprVisitor::visit(VectorArrayExp)): New override.
+
 2019-03-12  Iain Buclaw  <ibuclaw@gdcproject.org>
 
        PR d/87866
index f58b620d84492390cb912b3854412a83ef93ef90..5e4abe6f33fa093462021876f6661f3176718669 100644 (file)
@@ -1,4 +1,4 @@
-7423993c996ed9f73d6ba6d58f625ad3c778ca1d
+19b1454b5ca7b1036ea5fde197d91d4a7d05c0a5
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
index 1050e93699ea70ec2a9c6d544a3210af5177d2b9..1b382232dabd804ce2effe3dbbfb750e2dd0114a 100644 (file)
@@ -517,7 +517,7 @@ Expression *resolveSlice(Expression *e, UnionExp *pue)
 uinteger_t resolveArrayLength(Expression *e)
 {
     if (e->op == TOKvector)
-        e = ((VectorExp *)e)->e1;
+        return ((VectorExp *)e)->dim;
 
     if (e->op == TOKnull)
         return 0;
index 140abfdd7e97fd2be1e546702ce238f312389360..777f89cf186adcf41ae7ed656cbc59b6b8986c4c 100644 (file)
@@ -2920,7 +2920,6 @@ public:
             case TOKneg:    *pue = Neg(e->type, e1);  break;
             case TOKtilde:  *pue = Com(e->type, e1);  break;
             case TOKnot:    *pue = Not(e->type, e1);  break;
-            case TOKvector: result = e;             return; // do nothing
             default:        assert(0);
         }
         result = (*pue).exp();
@@ -3839,8 +3838,6 @@ public:
         Expression *aggregate;
         dinteger_t firstIndex;
 
-        if (e1->op == TOKvector)
-            e1 = ((VectorExp *)e1)->e1;
         if (e1->op == TOKslice)
         {
             // ------------------------------
@@ -4893,6 +4890,87 @@ public:
         result = pue->exp();
     }
 
+    /**
+     * Interpret the vector expression as an array literal.
+     * Params:
+     *    pue = non-null pointer to temporary storage that can be used to store the return value
+     *    e = Expression to interpret
+     * Returns:
+     *    resulting array literal or 'e' if unable to interpret
+     */
+    static Expression *interpretVectorToArray(UnionExp *pue, VectorExp *e)
+    {
+        if (e->e1->op == TOKarrayliteral)
+            return (ArrayLiteralExp *)e->e1;
+        if (e->e1->op == TOKint64 || e->e1->op == TOKfloat64)
+        {
+            // Convert literal __vector(int) -> __vector([array])
+            Expressions *elements = new Expressions();
+            elements->setDim(e->dim);
+            for (size_t i = 0; i < elements->dim; i++)
+                (*elements)[i] = copyLiteral(e->e1).copy();
+            TypeSArray *type = NULL;
+            if (e->type->ty == Tvector)
+            {
+                TypeVector *tv = (TypeVector *)e->type;
+                if (tv->basetype->ty == Tsarray)
+                    type = (TypeSArray *)tv->basetype;
+            }
+            else if (e->type->ty == Tsarray)
+                type = (TypeSArray *)e->type;
+            assert(type);
+            new(pue) ArrayLiteralExp(e->loc, type, elements);
+            ArrayLiteralExp *ale = (ArrayLiteralExp *)pue->exp();
+            ale->ownedByCtfe = OWNEDctfe;
+            return ale;
+        }
+        return e;
+    }
+
+    void visit(VectorExp *e)
+    {
+        if (e->ownedByCtfe >= OWNEDctfe) // We've already interpreted all the elements
+        {
+            result = e;
+            return;
+        }
+        Expression *e1 = interpret(pue, e->e1, istate);
+        assert(e1);
+        if (exceptionOrCant(e1))
+            return;
+        if (e1->op != TOKarrayliteral && e1->op != TOKint64 && e1->op != TOKfloat64)
+        {
+            e->error("`%s` cannot be evaluated at compile time", e->toChars());
+            result = CTFEExp::cantexp;
+            return;
+        }
+        if (e1 == pue->exp())
+            e1 = pue->copy();
+        new(pue) VectorExp(e->loc, e1, e->to);
+        VectorExp *ve = (VectorExp *)pue->exp();
+        ve->type = e->type;
+        ve->dim = e->dim;
+        ve->ownedByCtfe = OWNEDctfe;
+        result = ve;
+    }
+
+    void visit(VectorArrayExp *e)
+    {
+        Expression *e1 = interpret(pue, e->e1, istate);
+        assert(e1);
+        if (exceptionOrCant(e1))
+            return;
+        if (e1->op == TOKvector)
+        {
+            VectorExp *ve = (VectorExp *)e1;
+            result = interpretVectorToArray(pue, ve);
+            if (result->op != TOKvector)
+                return;
+        }
+        e->error("`%s` cannot be evaluated at compile time", e->toChars());
+        result = CTFEExp::cantexp;
+    }
+
     void visit(DelegatePtrExp *e)
     {
         Expression *e1 = interpret(pue, e->e1, istate);
@@ -4984,12 +5062,17 @@ public:
             return false;
         }
         if (e1->op == TOKvector)
-            e1 = ((VectorExp *)e1)->e1;
+        {
+            UnionExp ue;
+            e1 = interpretVectorToArray(&ue, (VectorExp *)e1);
+            e1 = (e1 == ue.exp()) ? ue.copy() : e1;
+        }
 
         // Set the $ variable, and find the array literal to modify
         if (e1->op != TOKarrayliteral &&
             e1->op != TOKstring &&
-            e1->op != TOKslice)
+            e1->op != TOKslice &&
+            e1->op != TOKvector)
         {
             e->error("cannot determine length of %s at compile time",
                 e->e1->toChars());
@@ -5239,9 +5322,15 @@ public:
             return;
         }
 
+        if (e1->op == TOKvector)
+        {
+            e1 = interpretVectorToArray(pue, (VectorExp *)e1);
+            e1 = (e1 == pue->exp()) ? pue->copy() : e1;
+        }
+
         /* Set the $ variable
          */
-        if (e1->op != TOKarrayliteral && e1->op != TOKstring && e1->op != TOKnull && e1->op != TOKslice)
+        if (e1->op != TOKarrayliteral && e1->op != TOKstring && e1->op != TOKnull && e1->op != TOKslice && e1->op != TOKvector)
         {
             e->error("cannot determine length of %s at compile time", e1->toChars());
             result = CTFEExp::cantexp;
@@ -5715,7 +5804,7 @@ public:
             if (exceptionOrCant(e1))
                 return;
             assert(e1->op == TOKvector);
-            e1 = ((VectorExp *)e1)->e1;
+            e1 = interpretVectorToArray(pue, (VectorExp *)e1);
         }
         if (e->to->ty == Tarray && e1->op == TOKslice)
         {
@@ -6165,6 +6254,18 @@ Expression *scrubReturnValue(Loc loc, Expression *e)
             return ex;
         aae->type = toBuiltinAAType(aae->type);
     }
+    else if (e->op == TOKvector)
+    {
+        VectorExp *ve = (VectorExp *)e;
+        ve->ownedByCtfe = OWNEDcode;
+        if (ve->e1->op == TOKarrayliteral)
+        {
+            ArrayLiteralExp *ale = (ArrayLiteralExp *)ve->e1;
+            ale->ownedByCtfe = OWNEDcode;
+            if (Expression *ex = scrubArray(loc, ale->elements))
+                return ex;
+        }
+    }
     return e;
 }
 
@@ -6282,6 +6383,18 @@ Expression *scrubCacheValue(Expression *e)
         if (Expression *ex = scrubArrayCache(aae->values))
             return ex;
     }
+    else if (e->op == TOKvector)
+    {
+        VectorExp *ve = (VectorExp *)e;
+        ve->ownedByCtfe = OWNEDcache;
+        if (ve->e1->op == TOKarrayliteral)
+        {
+            ArrayLiteralExp *ale = (ArrayLiteralExp *)ve->e1;
+            ale->ownedByCtfe = OWNEDcache;
+            if (Expression *ex = scrubArrayCache(ale->elements))
+                return ex;
+        }
+    }
     return e;
 }
 
index df373925e09079398888fa828cac42cfe60c3fba..af762eb3c66f36f9eb0c65a06ffa0d293476e4b6 100644 (file)
@@ -5744,6 +5744,7 @@ VectorExp::VectorExp(Loc loc, Expression *e, Type *t)
     assert(t->ty == Tvector);
     to = (TypeVector *)t;
     dim = ~0;
+    ownedByCtfe = OWNEDcode;
 }
 
 VectorExp *VectorExp::create(Loc loc, Expression *e, Type *t)
@@ -5758,6 +5759,24 @@ Expression *VectorExp::syntaxCopy()
 
 /************************************************************/
 
+VectorArrayExp::VectorArrayExp(Loc loc, Expression *e1)
+        : UnaExp(loc, TOKvectorarray, sizeof(VectorExp), e1)
+{
+}
+
+bool VectorArrayExp::isLvalue()
+{
+    return e1->isLvalue();
+}
+
+Expression *VectorArrayExp::toLvalue(Scope *sc, Expression *e)
+{
+    e1 = e1->toLvalue(sc, e);
+    return this;
+}
+
+/************************************************************/
+
 SliceExp::SliceExp(Loc loc, Expression *e1, IntervalExp *ie)
         : UnaExp(loc, TOKslice, sizeof(SliceExp), e1)
 {
index 2dd0b249458e8d373f0b407da4916a951d03ba17..b460e8caa0103882cbf8c39e69b65eb77dc745d1 100644 (file)
@@ -959,6 +959,7 @@ class VectorExp : public UnaExp
 public:
     TypeVector *to;             // the target vector type before semantic()
     unsigned dim;               // number of elements in the vector
+    OwnedBy ownedByCtfe;
 
     VectorExp(Loc loc, Expression *e, Type *t);
     static VectorExp *create(Loc loc, Expression *e, Type *t);
@@ -966,6 +967,15 @@ public:
     void accept(Visitor *v) { v->visit(this); }
 };
 
+class VectorArrayExp : public UnaExp
+{
+public:
+    VectorArrayExp(Loc loc, Expression *e1);
+    bool isLvalue();
+    Expression *toLvalue(Scope *sc, Expression *e);
+    void accept(Visitor *v) { v->visit(this); }
+};
+
 class SliceExp : public UnaExp
 {
 public:
@@ -1515,6 +1525,7 @@ private:
         char addrexp   [sizeof(AddrExp)];
         char indexexp  [sizeof(IndexExp)];
         char sliceexp  [sizeof(SliceExp)];
+        char vectorexp [sizeof(VectorExp)];
     } u;
 #if defined(__DMC__)
     #pragma pack()
index bcc1ac9ed2f979ec08ded064d873e1f70be33942..a88ff8822acd25ed08dc8d2ee40ab2a52283bcd6 100644 (file)
@@ -4299,6 +4299,25 @@ public:
         result = e;
     }
 
+    void visit(VectorArrayExp *e)
+    {
+        if (!e->type)
+        {
+            unaSemantic(e, sc);
+            e->e1 = resolveProperties(sc, e->e1);
+
+            if (e->e1->op == TOKerror)
+            {
+                result = e->e1;
+                return;
+            }
+            assert(e->e1->type->ty == Tvector);
+            TypeVector *tv = (TypeVector *)e->e1->type;
+            e->type = tv->basetype;
+        }
+        result = e;
+    }
+
     void visit(SliceExp *exp)
     {
         if (exp->type)
index e6380970a8de77488df141a1631d4c9fd1a75528..4eaa1ae10501494ff6ca35a5ee17c01cab2ff379 100644 (file)
@@ -2833,6 +2833,12 @@ public:
         expToBuffer(e->e1, precedence[e->op]);
     }
 
+    void visit(VectorArrayExp *e)
+    {
+        expToBuffer(e->e1, PREC_primary);
+        buf->writestring(".array");
+    }
+
     void visit(SliceExp *e)
     {
         expToBuffer(e->e1, precedence[e->op]);
index 900f172cccb7a69172405d8bd19d2da6d05ebb00..d0e73967d45f1c70bb5d6f4547df506e15ec0d86 100644 (file)
@@ -3766,8 +3766,8 @@ Expression *TypeVector::dotExp(Scope *sc, Expression *e, Identifier *ident, int
     {
         //e = e->castTo(sc, basetype);
         // Keep lvalue-ness
-        e = e->copy();
-        e->type = basetype;
+        e = new VectorArrayExp(e->loc, e);
+        e = ::semantic(e, sc);
         return e;
     }
     if (ident == Id::_init || ident == Id::offsetof || ident == Id::stringof || ident == Id::__xalignof)
index 701c3141031a6a6339b5300cf5c8350095047dfd..e0ee299eb6d3739742826e047228b3a28e6677e7 100644 (file)
@@ -7929,6 +7929,7 @@ PrecedenceInitializer::PrecedenceInitializer()
     precedence[TOKdefault] = PREC_primary;
     precedence[TOKoverloadset] = PREC_primary;
     precedence[TOKvoid] = PREC_primary;
+    precedence[TOKvectorarray] = PREC_primary;
 
     // post
     precedence[TOKdotti] = PREC_primary;
index 89feffac7e9332397b36a32d628f1c956bd39992..c9c7ab45878ee1e77da67123eeb7ee86c27c1d4d 100644 (file)
@@ -472,4 +472,5 @@ TokenInitializer::TokenInitializer()
     Token::tochars[TOKon_scope_success] = "scope(success)";
     Token::tochars[TOKon_scope_failure] = "scope(failure)";
     Token::tochars[TOKdelegateptr]      = "delegateptr";
+    Token::tochars[TOKvectorarray]      = "vectorarray";
 }
index 453683f34e185a9f2efcce3b46c540a700393787..567e802b611d56ba03097afa290f701e81d62f95 100644 (file)
@@ -179,6 +179,8 @@ enum TOK
         TOKvoidexp,
         TOKcantexp,
 
+        TOKvectorarray,
+
         TOKMAX
 };
 
index 25ebba842537f133a2d1cce6e1c4560194b0b2d7..4c9267044e2f87d8cfeb12f3572750511ed7567a 100644 (file)
@@ -226,6 +226,7 @@ class NotExp;
 class DeleteExp;
 class CastExp;
 class VectorExp;
+class VectorArrayExp;
 class SliceExp;
 class ArrayLengthExp;
 class IntervalExp;
@@ -517,6 +518,7 @@ public:
     virtual void visit(DeleteExp *e) { visit((UnaExp *)e); }
     virtual void visit(CastExp *e) { visit((UnaExp *)e); }
     virtual void visit(VectorExp *e) { visit((UnaExp *)e); }
+    virtual void visit(VectorArrayExp *e) { visit((UnaExp *)e); }
     virtual void visit(SliceExp *e) { visit((UnaExp *)e); }
     virtual void visit(ArrayLengthExp *e) { visit((UnaExp *)e); }
     virtual void visit(IntervalExp *e) { visit((Expression *)e); }
index 4bfdde5a29ab22246223c61d7e813529272ea207..acf81a6cca0ae10fe1bf794630755e25dfe3abba 100644 (file)
@@ -2992,6 +2992,14 @@ public:
       }
   }
 
+  /* Build a static array representation of a vector expression.  */
+
+  void visit (VectorArrayExp *e)
+  {
+    this->result_ = convert_expr (build_expr (e->e1, this->constp_),
+                                 e->e1->type, e->type);
+  }
+
   /* Build a static class literal, return its reference.  */
 
   void visit (ClassReferenceExp *e)
index 893953db4065766cb228e6a37b5a7133d573a6a3..94144c93a3d24e7e5f1401382b5be804b4bebec0 100644 (file)
@@ -1,3 +1,9 @@
+2019-03-13  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+       PR d/88957
+       * gdc.dg/pr88957.d: New test.
+       * gdc.dg/simd.d: Add new vector tests.
+
 2019-03-12  Uroš Bizjak  <ubizjak@gmail.com>
 
        PR d/87824
diff --git a/gcc/testsuite/gdc.dg/pr88957.d b/gcc/testsuite/gdc.dg/pr88957.d
new file mode 100644 (file)
index 0000000..e6366d4
--- /dev/null
@@ -0,0 +1,18 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88957
+// { dg-do compile }
+// { dg-additional-options "-fsanitize=undefined" }
+
+alias int4 = __vector(int[4]);
+
+int fn(const int[4] x)
+{
+    int sum = 0;
+    foreach (i; x) sum += i;
+    return sum;
+}
+
+void pr88957()
+{
+    auto x = fn(int4.init.array);
+    auto y = fn(int4(2).array);
+}
index e4361a698819578dd85f1fb07c191396818a9f2a..812b36649aa033e6db99d51dcb658ed9c2e39b47 100644 (file)
@@ -1108,7 +1108,6 @@ float bug8060(float x) {
 }
 
 /*****************************************/
-/+
 // https://issues.dlang.org/show_bug.cgi?id=9200
 
 void bar9200(double[2] a)
@@ -1130,7 +1129,6 @@ void test9200()
 
     bar9200(a.array);
 }
-+/
 
 /*****************************************/
 // https://issues.dlang.org/show_bug.cgi?id=9304
@@ -1686,7 +1684,6 @@ void test17720()
 }
 
 /*****************************************/
-
 // https://issues.dlang.org/show_bug.cgi?id=17695
 
 void test17695(__vector(ubyte[16]) a)
@@ -1694,6 +1691,217 @@ void test17695(__vector(ubyte[16]) a)
     auto b = -a;
 }
 
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=19223
+
+int test19223a(const int[4] x)
+{
+    int sum = 0;
+    foreach (i; x) sum += i;
+    return sum;
+}
+
+void test19223()
+{
+    int4 v1 = int4.init;
+    assert(test19223a(v1.array) == 0);
+    assert(test19223a(int4.init.array) == 0);
+}
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=19224
+
+float test19224(const float[4] val)
+{
+    float sum = 0;
+    foreach (x; val) sum += x;
+    return sum;
+}
+
+enum x19224 = test19224(float4.init.array);
+static assert(x19224 is float.nan);
+
+enum y19224 = test19224(float4(1).array);
+static assert(y19224 == 4);
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=19607
+
+int test19607a(const int[4] x)
+{
+    int sum = 0;
+    foreach (i; x) sum += i;
+    return sum;
+}
+
+void test19607()
+{
+    int4 v1 = 1;
+    assert(test19607a(v1.array) == 4);
+    assert(test19607a(int4(2).array) == 8);
+}
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=19627
+
+enum int[4] fail19627 = cast(int[4])int4(0);
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=19628
+
+enum ice19628a = int4.init[0];
+enum ice19628b = int4.init.array[0];
+enum ice19628c = (cast(int[4])int4.init.array)[0];
+enum ice19628d = (cast(int[4])int4.init)[0];
+
+enum int4 v19628a = int4.init;
+enum idx19628a = v19628a[0];
+static assert(idx19628a == 0);
+
+enum int[4] v19628b = int4.init.array;
+enum idx19628b = v19628b[0];
+static assert(idx19628b == 0);
+
+enum int[4] v19628c = cast(int[4])int4.init.array;
+enum idx19628c = v19628c[0];
+static assert(idx19628c == 0);
+
+enum int[4] v19628d = cast(int[4])int4.init;
+enum idx19628d = v19628d[0];
+static assert(idx19628d == 0);
+
+immutable int4 v19628e = int4.init;
+immutable idx19628e = v19628e[0];
+static assert(idx19628e == 0);
+
+immutable int[4] v19628f = int4.init.array;
+immutable idx19628f = v19628f[0];
+static assert(idx19628f == 0);
+
+immutable int[4] v19628g = cast(int[4])int4.init.array;
+immutable idx19628g = v19628g[0];
+static assert(idx19628g == 0);
+
+immutable idx19628h = v19628h[0];
+immutable int[4] v19628h = cast(int[4])int4.init;
+static assert(idx19628h == 0);
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=19629
+
+enum fail19629a = int4(0)[0];
+enum fail19629b = int4(0).array[0];
+enum fail19629c = (cast(int[4])int4(0).array)[0];
+enum fail19628d = (cast(int[4])int4(0))[0];
+
+enum int4 v19629a = int4(0);
+enum idx19629a = v19629a[0];
+static assert(idx19629a == 0);
+
+enum int[4] v19629b = int4(0).array;
+enum idx19629b = v19629b[0];
+static assert(idx19629b == 0);
+
+enum int[4] v19629c = cast(int[4])int4(0).array;
+enum idx19629c = v19629c[0];
+static assert(idx19629c == 0);
+
+enum int[4] v19629d = cast(int[4])int4(0);
+enum idx19629d = v19629d[0];
+static assert(idx19629d == 0);
+
+immutable int4 v19629e = int4(0);
+immutable idx19629e = v19629e[0];
+static assert(idx19629e == 0);
+
+immutable int[4] v19629f = int4(0).array;
+immutable idx19629f = v19629f[0];
+static assert(idx19629f == 0);
+
+immutable int[4] v19629g = cast(int[4])int4(0).array;
+immutable idx19629g = v19629g[0];
+static assert(idx19629g == 0);
+
+immutable int[4] v19629h = cast(int[4])int4(0);
+immutable idx19629h = v19629h[0];
+static assert(idx19629h == 0);
+
+/*****************************************/
+// https://issues.dlang.org/show_bug.cgi?id=19630
+
+enum fail19630a = int4.init[1..2];
+enum fail19630b = int4.init.array[1..2];
+enum fail19630c = (cast(int[4])int4.init.array)[1..2];
+enum fail19630d = (cast(int[4])int4.init)[1..2];
+enum fail19630e = int4(0)[1..2];
+enum fail19630f = int4(0).array[1..2];
+enum fail19630g = (cast(int[4])int4(0).array)[1..2];
+enum fail19630h = (cast(int[4])int4(0))[1..2];
+
+enum int4 v19630a = int4.init;
+enum slice19630a = v19630a[1..2];
+static assert(slice19630a == [0]);
+
+enum int[4] v19630b = int4.init.array;
+enum slice19630b = v19630b[1..2];
+static assert(slice19630b == [0]);
+
+enum int[4] v19630c = cast(int[4])int4.init.array;
+enum slice19630c = v19630c[1..2];
+static assert(slice19630c == [0]);
+
+enum int[4] v19630d = cast(int[4])int4.init;
+enum slice19630d = v19630d[1..2];
+static assert(slice19630d == [0]);
+
+enum int4 v19630e = int4(0);
+enum slice19630e = v19630e[1..2];
+static assert(slice19630e == [0]);
+
+enum int[4] v19630f = int4(0).array;
+enum slice19630f = v19630f[1..2];
+static assert(slice19630f == [0]);
+
+enum int[4] v19630g = cast(int[4])int4(0).array;
+enum slice19630g = v19630g[1..2];
+static assert(slice19630g == [0]);
+
+enum int[4] v19630h = cast(int[4])int4(0);
+enum slice19630h = v19630h[1..2];
+static assert(slice19630h == [0]);
+
+immutable int4 v19630i = int4.init;
+immutable slice19630i = v19630i[1..2];
+static assert(slice19630i == [0]);
+
+immutable int[4] v19630j = int4.init.array;
+immutable slice19630j = v19630j[1..2];
+static assert(slice19630j == [0]);
+
+immutable int[4] v19630k = cast(int[4])int4.init.array;
+immutable slice19630k = v19630k[1..2];
+static assert(slice19630k == [0]);
+
+immutable int[4] v19630l = cast(int[4])int4.init;
+immutable slice19630l = v19630l[1..2];
+static assert(slice19630l == [0]);
+
+immutable int4 v19630m = int4(0);
+immutable slice19630m = v19630m[1..2];
+static assert(slice19630m == [0]);
+
+immutable int[4] v19630n = int4(0).array;
+immutable slice19630n = v19630n[1..2];
+static assert(slice19630n == [0]);
+
+immutable int[4] v19630o = cast(int[4])int4(0).array;
+immutable slice19630o = v19630o[1..2];
+static assert(slice19630o == [0]);
+
+immutable int[4] v19630p = cast(int[4])int4(0);
+immutable slice19630p = v19630p[1..2];
+static assert(slice19630p == [0]);
+
 /*****************************************/
 
 int main()
@@ -1718,7 +1926,7 @@ int main()
     test7414();
     test7413();
     test7413_2();
-//    test9200();
+    test9200();
     test9304();
     test9910();
     test12852();
@@ -1731,5 +1939,8 @@ int main()
     testOPvecunsto();
     test10447();
 
+    test19223();
+    test19607();
+
     return 0;
 }