[PR,d/88957] Committed fix for ICE in tree_could_trap_p with -fsanitize=undefined

Message ID CABOHX+cCd5mfxapPWiZ=bnVFnJtBShe_1zuvK=H6Awjkc_Sr9w@mail.gmail.com
State New
Headers show
Series
  • [PR,d/88957] Committed fix for ICE in tree_could_trap_p with -fsanitize=undefined
Related show

Commit Message

Iain Buclaw March 12, 2019, 11:11 p.m.
Hi,

This patch merges the D front-end implementation with dmd upstream 19b1454b5.

Backports fixes for many ICEs that occurred when using the vector
.array property in both CTFE and code generation passes.

Bootstrapped and regression tested on x86_64-linux-gnu.

Committed to trunk as r269627.

-- 
Iain
---
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.
---

Patch

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index f58b620d844..5e4abe6f33f 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -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.
diff --git a/gcc/d/dmd/ctfeexpr.c b/gcc/d/dmd/ctfeexpr.c
index 1050e93699e..1b382232dab 100644
--- a/gcc/d/dmd/ctfeexpr.c
+++ b/gcc/d/dmd/ctfeexpr.c
@@ -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;
diff --git a/gcc/d/dmd/dinterpret.c b/gcc/d/dmd/dinterpret.c
index 140abfdd7e9..777f89cf186 100644
--- a/gcc/d/dmd/dinterpret.c
+++ b/gcc/d/dmd/dinterpret.c
@@ -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;
 }
 
diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c
index df373925e09..af762eb3c66 100644
--- a/gcc/d/dmd/expression.c
+++ b/gcc/d/dmd/expression.c
@@ -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)
 {
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 2dd0b249458..b460e8caa01 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -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()
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index bcc1ac9ed2f..a88ff8822ac 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -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)
diff --git a/gcc/d/dmd/hdrgen.c b/gcc/d/dmd/hdrgen.c
index e6380970a8d..4eaa1ae1050 100644
--- a/gcc/d/dmd/hdrgen.c
+++ b/gcc/d/dmd/hdrgen.c
@@ -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]);
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index 900f172cccb..d0e73967d45 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -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)
diff --git a/gcc/d/dmd/parse.c b/gcc/d/dmd/parse.c
index 701c3141031..e0ee299eb6d 100644
--- a/gcc/d/dmd/parse.c
+++ b/gcc/d/dmd/parse.c
@@ -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;
diff --git a/gcc/d/dmd/tokens.c b/gcc/d/dmd/tokens.c
index 89feffac7e9..c9c7ab45878 100644
--- a/gcc/d/dmd/tokens.c
+++ b/gcc/d/dmd/tokens.c
@@ -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";
 }
diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h
index 453683f34e1..567e802b611 100644
--- a/gcc/d/dmd/tokens.h
+++ b/gcc/d/dmd/tokens.h
@@ -179,6 +179,8 @@  enum TOK
         TOKvoidexp,
         TOKcantexp,
 
+        TOKvectorarray,
+
         TOKMAX
 };
 
diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h
index 25ebba84253..4c9267044e2 100644
--- a/gcc/d/dmd/visitor.h
+++ b/gcc/d/dmd/visitor.h
@@ -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); }
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 4bfdde5a29a..acf81a6cca0 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -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)
diff --git a/gcc/testsuite/gdc.dg/pr88957.d b/gcc/testsuite/gdc.dg/pr88957.d
new file mode 100644
index 00000000000..d9bac58f0b3
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr88957.d
@@ -0,0 +1,18 @@ 
+// { dg-do compile }
+// { dg-additional-options "-fsanitize=undefined" }
+
+// Code generation tests
+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);
+}
diff --git a/gcc/testsuite/gdc.dg/simd.d b/gcc/testsuite/gdc.dg/simd.d
index e4361a69881..812b36649aa 100644
--- a/gcc/testsuite/gdc.dg/simd.d
+++ b/gcc/testsuite/gdc.dg/simd.d
@@ -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;
 }