[pixel shader]
float cond;

float4 main() : sv_target
{
    float4 a = {1, 2, 3, 4};
    float4 b;

    // invalidate a
    if (cond)
        a = float4(-1, -2, -3, -4);

    b = a;
    a.y = 357;
    return b.y;
}

[test]
uniform 0 float 0.0
draw quad
probe (0, 0) f32(2.0, 2.0, 2.0, 2.0)
uniform 0 float 1.0
draw quad
probe (0, 0) f32(-2.0, -2.0, -2.0, -2.0)

[pixel shader]
float cond;

float4 main() : sv_target
{
    float2 r = {1, 2};
    float2 tmp;

    // invalidate r
    if (cond)
        r = float2(10, 20);

    tmp = r;
    r = tmp;
    return r.y;
}

[test]
uniform 0 float 0.0
draw quad
probe (0, 0) f32(2.0, 2.0, 2.0, 2.0)
uniform 0 float 1.0
draw quad
probe (0, 0) f32(20.0, 20.0, 20.0, 20.0)

[pixel shader]
float cond;

float4 main() : sv_target
{
    float2 r = {3, 4};

    // invalidate r
    if (cond)
        r = float2(30, 40);

    r = r;
    r = float2(1, r.y);

    return float4(r, 0, 0);
}

[test]
uniform 0 float 0.0
draw quad
probe (0, 0) f32(1.0, 4.0, 0.0, 0.0)
uniform 0 float 1.0
draw quad
probe (0, 0) f32(1.0, 40.0, 0.0, 0.0)

[pixel shader]
float x[6];
float y[3];
uint4 i;

float4 main() : sv_target
{
    float4 r;
    float z[3][2];

    z[0][0] = x[0];
    z[1][0] = x[1];
    z[2][0] = x[2];
    z[0][1] = x[1];
    z[1][1] = x[3];
    z[2][1] = x[5];

    r.x = z[i.x][0];
    r.y = z[i.y][1];

    z[0][1] = y[2];
    z[1][1] = y[1];
    z[2][1] = y[0];

    r.z = z[i.z][1];

    z[2][0] = x[1];
    z[2][1] = x[5];

    r.w = z[2][i.w];

    return r;
}

[test]
uniform 0  float 1.0
uniform 4  float 2.0
uniform 8  float 3.0
uniform 12 float 4.0
uniform 16 float 5.0
uniform 20 float 6.0
uniform 24 float -1.0
uniform 28 float -2.0
uniform 32 float -3.0
if(sm<4)  uniform 36 float4 0 1 2 0
if(sm>=4) uniform 36 uint4  0 1 2 0
draw quad
probe (0, 0) rgba(1.0, 4.0, -1.0, 2.0)
if(sm<4)  uniform 36 float4 2 0 1 1
if(sm>=4) uniform 36 uint4  2 0 1 1
draw quad
probe (0, 0) rgba(3.0, 2.0, -2.0, 6.0)

[pixel shader]
float x[4];
uint4 i;

float4 main() : sv_target
{
    float y[2][2];

    y[0][0] = x[0 + 2*0];
    y[0][1] = x[0 + 2*1];
    y[1][0] = x[1 + 2*0];
    y[1][1] = x[1 + 2*1];

    return y[i.x][i.y];
}

[test]
uniform 0  float 1.0
uniform 4  float 2.0
uniform 8  float 3.0
uniform 12 float 4.0
if(sm<4)  uniform 16 float4 0 1 0 0
if(sm>=4) uniform 16 uint4  0 1 0 0
draw quad
probe (0, 0) rgba(3.0, 3.0, 3.0, 3.0)
if(sm<4)  uniform 16 float4 1 1 0 0
if(sm>=4) uniform 16 uint4  1 1 0 0
draw quad
probe (0, 0) rgba(4.0, 4.0, 4.0, 4.0)

% Copy-prop is currently unable to propagate the following,
% as structs don't yet support dynamic indexing.
[pixel shader]
struct s
{
    float4 a, b;
};

struct s x;
uint4 i;

float4 main() : sv_target
{
    float4 y[2] = {x.a, x.b};
    return y[i.x];
}

[test]
uniform 0 float4 2.0 2.0 2.0 2.0
uniform 4 float4 3.0 3.0 3.0 3.0
if(sm<4)  uniform 8 float4 0 0 0 0
if(sm>=4) uniform 8 uint4  0 0 0 0
draw quad
probe (0, 0) rgba(2.0, 2.0, 2.0, 2.0)
if(sm<4)  uniform 8 float4 1 0 0 0
if(sm>=4) uniform 8 uint4  1 0 0 0
draw quad
probe (0, 0) rgba(3.0, 3.0, 3.0, 3.0)

% OOB indexes are illegal, but sm < 6 allows them in dead code.
% We need copy-prop to know if the code is dead.
% This means copy-prop needs to be able to handle OOB indexes.
[pixel shader fail(sm>=6)]

float4 main() : sv_target
{
    static float4 arr[4];
    bool x = false;

    if (x)
    {
        arr[100] = 0;
        return arr[100];
    }

    return 0;
}

[pixel shader]
float a;

float4 main() : sv_target
{
    float arr[2][2] = {1, 2, 3, 4};

    if (a > 0)
        arr[1][1] = 5;

    return float4(arr[0][0], arr[0][1], arr[1][0], arr[1][1]);
}

[test]
uniform 0 float 11.0
draw quad
probe (0, 0) f32(1, 2, 3, 5)

[require]
shader model < 5.1
options: backcompat

[pixel shader]
sampler s;
Texture2D t1, t2;

float4 main() : sv_target
{
    Texture2D t = t1;
    t1 = t2;
    t2 = t;
    return t1.Sample(s, float2(0, 0)) + t2.Sample(s, float2(0, 0));
}
