Skip to content

Commit

Permalink
fix Issue 20041 - CTFE incorrect result with __vector
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright authored and PetarKirov committed Dec 28, 2020
1 parent 11a722b commit 716b3e0
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
19 changes: 18 additions & 1 deletion src/dmd/dinterpret.d
Expand Up @@ -38,6 +38,7 @@ import dmd.identifier;
import dmd.init;
import dmd.initsem;
import dmd.mtype;
import dmd.printast;
import dmd.root.rmem;
import dmd.root.array;
import dmd.root.region;
Expand Down Expand Up @@ -308,6 +309,7 @@ public:

extern (C++) Expression getValue(VarDeclaration v)
{
//printf("getValue() %s\n", v.toChars());
if ((v.isDataseg() || v.storage_class & STC.manifest) && !v.isCTFE())
{
assert(v.ctfeAdrOnStack < globalValues.dim);
Expand All @@ -319,13 +321,15 @@ public:

extern (C++) void setValue(VarDeclaration v, Expression e)
{
//printf("setValue() %s : %s\n", v.toChars(), e.toChars());
assert(!v.isDataseg() || v.isCTFE());
assert(v.ctfeAdrOnStack < stackPointer());
values[v.ctfeAdrOnStack] = e;
}

extern (C++) void push(VarDeclaration v)
{
//printf("push() %s\n", v.toChars());
assert(!v.isDataseg() || v.isCTFE());
if (v.ctfeAdrOnStack != VarDeclaration.AdrOnStackNone && v.ctfeAdrOnStack >= framepointer)
{
Expand Down Expand Up @@ -3694,6 +3698,7 @@ public:

private Expression assignToLvalue(BinExp e, Expression e1, Expression newval)
{
//printf("assignToLvalue() e: %s e1: %s newval: %s\n", e.toChars(), e1.toChars(), newval.toChars());
VarDeclaration vd = null;
Expression* payload = null; // dead-store to prevent spurious warning
Expression oldval;
Expand Down Expand Up @@ -3786,6 +3791,17 @@ public:
Type t1b = e1.type.toBasetype();
bool wantCopy = t1b.baseElemOf().ty == Tstruct;

if (auto ve = newval.isVectorExp())
{
// Ensure ve is an array literal, and not a broadcast
if (ve.e1.op == TOK.int64 || ve.e1.op == TOK.float64) // if broadcast
{
UnionExp ue = void;
Expression ex = interpretVectorToArray(&ue, ve);
ve.e1 = (ex == ue.exp()) ? ue.copy() : ex;
}
}

if (newval.op == TOK.structLiteral && oldval)
{
assert(oldval.op == TOK.structLiteral || oldval.op == TOK.arrayLiteral || oldval.op == TOK.string_);
Expand Down Expand Up @@ -4984,7 +5000,7 @@ public:
static Expression interpretVectorToArray(UnionExp* pue, VectorExp e)
{
if (auto ale = e.e1.isArrayLiteralExp())
return ale;
return ale; // it's already an array literal
if (e.e1.op == TOK.int64 || e.e1.op == TOK.float64)
{
// Convert literal __vector(int) -> __vector([array])
Expand Down Expand Up @@ -7348,6 +7364,7 @@ private void setValueWithoutChecking(VarDeclaration vd, Expression newval)

private void setValue(VarDeclaration vd, Expression newval)
{
//printf("setValue() vd: %s newval: %s\n", vd.toChars(), newval.toChars());
version (none)
{
if (!((vd.storage_class & (STC.out_ | STC.ref_)) ? isCtfeReferenceValid(newval) : isCtfeValueValid(newval)))
Expand Down
2 changes: 1 addition & 1 deletion test/fail_compilation/ice20042.d
Expand Up @@ -2,7 +2,7 @@
DISABLED: freebsd32 linux32 osx32 win32
TEST_OUTPUT:
---
fail_compilation/ice20042.d(18): Error: slice operation `cast(__vector(float[4]))nanF = [1.0F, 2.0F, 3.0F, 4.0F][0..4]` cannot be evaluated at compile time
fail_compilation/ice20042.d(18): Error: slice operation `cast(__vector(float[4]))[nanF, nanF, nanF, nanF] = [1.0F, 2.0F, 3.0F, 4.0F][0..4]` cannot be evaluated at compile time
fail_compilation/ice20042.d(25): called from here: `Vec4(cast(__vector(float[4]))[nanF, nanF, nanF, nanF]).this([1.0F, 2.0F, 3.0F, 4.0F])`
---
*/
Expand Down
25 changes: 25 additions & 0 deletions test/runnable/testxmm.d
Expand Up @@ -2146,6 +2146,30 @@ int4 foo21469(short a)
return cast(int4)(short8(a));
}

/*****************************************/
// https://issues.dlang.org/show_bug.cgi?id=20041

immutable(float4) foo20041()
{
float4 raw = 2.0f;
raw.array[0] = 1;
return cast(immutable)raw;
}

void test20041()
{
static immutable float4 v = foo20041();

assert(v.array[0] == 1);
assert(v.array[1] == 2);
assert(v.array[2] == 2);
assert(v.array[3] == 2);

// foreach(d; 0 .. 4)
// printf("%g ", v[d]);
// printf("\n");
}

/*****************************************/
// https://issues.dlang.org/show_bug.cgi?id=21364

Expand Down Expand Up @@ -2225,6 +2249,7 @@ int main()
test6();
test7();
test20981();
test20041();
test21364();
test19788();

Expand Down

0 comments on commit 716b3e0

Please sign in to comment.