+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
-7423993c996ed9f73d6ba6d58f625ad3c778ca1d
+19b1454b5ca7b1036ea5fde197d91d4a7d05c0a5
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
uinteger_t resolveArrayLength(Expression *e)
{
if (e->op == TOKvector)
- e = ((VectorExp *)e)->e1;
+ return ((VectorExp *)e)->dim;
if (e->op == TOKnull)
return 0;
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();
Expression *aggregate;
dinteger_t firstIndex;
- if (e1->op == TOKvector)
- e1 = ((VectorExp *)e1)->e1;
if (e1->op == TOKslice)
{
// ------------------------------
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);
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());
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;
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)
{
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;
}
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;
}
assert(t->ty == Tvector);
to = (TypeVector *)t;
dim = ~0;
+ ownedByCtfe = OWNEDcode;
}
VectorExp *VectorExp::create(Loc loc, Expression *e, Type *t)
/************************************************************/
+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)
{
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);
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:
char addrexp [sizeof(AddrExp)];
char indexexp [sizeof(IndexExp)];
char sliceexp [sizeof(SliceExp)];
+ char vectorexp [sizeof(VectorExp)];
} u;
#if defined(__DMC__)
#pragma pack()
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)
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]);
{
//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)
precedence[TOKdefault] = PREC_primary;
precedence[TOKoverloadset] = PREC_primary;
precedence[TOKvoid] = PREC_primary;
+ precedence[TOKvectorarray] = PREC_primary;
// post
precedence[TOKdotti] = PREC_primary;
Token::tochars[TOKon_scope_success] = "scope(success)";
Token::tochars[TOKon_scope_failure] = "scope(failure)";
Token::tochars[TOKdelegateptr] = "delegateptr";
+ Token::tochars[TOKvectorarray] = "vectorarray";
}
TOKvoidexp,
TOKcantexp,
+ TOKvectorarray,
+
TOKMAX
};
class DeleteExp;
class CastExp;
class VectorExp;
+class VectorArrayExp;
class SliceExp;
class ArrayLengthExp;
class IntervalExp;
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); }
}
}
+ /* 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)
+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
--- /dev/null
+// 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);
+}
}
/*****************************************/
-/+
// https://issues.dlang.org/show_bug.cgi?id=9200
void bar9200(double[2] a)
bar9200(a.array);
}
-+/
/*****************************************/
// https://issues.dlang.org/show_bug.cgi?id=9304
}
/*****************************************/
-
// https://issues.dlang.org/show_bug.cgi?id=17695
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()
test7414();
test7413();
test7413_2();
-// test9200();
+ test9200();
test9304();
test9910();
test12852();
testOPvecunsto();
test10447();
+ test19223();
+ test19607();
+
return 0;
}