Bug 109532 - ir_variable has maximum access out of bounds -- but it's not out of bounds
Summary: ir_variable has maximum access out of bounds -- but it's not out of bounds
Status: RESOLVED MOVED
Alias: None
Product: Mesa
Classification: Unclassified
Component: glsl-compiler (show other bugs)
Version: git
Hardware: Other All
: medium normal
Assignee: mesa-dev
QA Contact: Intel 3D Bugs Mailing List
URL:
Whiteboard:
Keywords:
: 109260 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-02-02 09:10 UTC by Ilia Mirkin
Modified: 2019-09-18 19:46 UTC (History)
5 users (show)

See Also:
i915 platform:
i915 features:


Attachments
gdb session + generated shaders (19.32 KB, text/plain)
2019-02-02 09:10 UTC, Ilia Mirkin
Details
this simple program helps me to reproduce this issue. (5.99 KB, application/zip)
2019-02-04 16:38 UTC, asimiklit
Details
one more issue. (5.36 KB, text/plain)
2019-02-11 11:54 UTC, asimiklit
Details
patch to disallow an elimination of the first unused ub/ssbo array elements (5.53 KB, patch)
2019-02-21 15:38 UTC, asimiklit
Details | Splinter Review
attachment-11105-0.html (1.80 KB, text/html)
2019-02-26 17:52 UTC, Dylan Baker
Details
draft of a solution (4.11 KB, patch)
2019-03-05 15:54 UTC, asimiklit
Details | Splinter Review

Description Ilia Mirkin 2019-02-02 09:10:37 UTC
Created attachment 143274 [details]
gdb session + generated shaders

This dEQP test asserts, at least on nouveau, but I don't see what would cause it to be driver-specific.

dEQP-GLES31.functional.ssbo.layout.random.all_per_block_buffers.18

This appears to happen because it doesn't understand the interface array index properly? This message is printed before the abort:

ir_variable has maximum access out of bounds (1 vs 0)

For some reason it thinks that the array length is 1 when it should be 2. I recall interfaces being treated rather differently than most things, so perhaps related.
Comment 1 Timothy Arceri 2019-02-02 20:33:08 UTC
I believe we split (maybe eliminate unused blocks?). Looks like the shader only access blockB[1] and not blockB[0] so I assume this has something to do with it. Probably not updating something correctly when doing so.
Comment 2 Ilia Mirkin 2019-02-03 00:58:03 UTC
Looks like this is happening in link_uniform_blocks. The type gets updated:

      if (b->array != NULL &&
          (b->type->without_array()->interface_packing ==
           GLSL_INTERFACE_PACKING_PACKED)) {
         b->type = resize_block_array(b->type, b->array);
         b->var->type = b->type;
      }

But no change to the corresponding max_data_access. However doing the naive thing here didn't help -- the shader fails. I didn't investigate why. I think create_buffer_blocks also needs to be involved somehow.
Comment 3 Mark Janes 2019-02-03 03:37:56 UTC
This test was broken in the dEQP suite recently for m32 i965 platforms by:

237916d03377a469e30dd36087738b069f83a19a
Author:     xinglong.zhu <xinglong.zhu@spreadtrum.com>
Commit:     Patrick Shi <patrick.shi@unisoc.com>
CommitDate: Sat Jan 5 12:46:03 2019 +0000

gles31:es31fSSBOLayoutTests limit m_maxBlocks and m_maxBlockMembers for low ram device

Memory requirement for cts CtsDeqpTestCases
dEQP-GLES31.functional.ssbo.layout.random.all_shared_buffer#5
reduced from 230MB to 36MB

Issue: 121364689
Test: run cts -m CtsDeqpTestCases -t dEQP-GLES31.functional.ssbo.layout.random.all_shared_buffer#5

Change-Id: I2a66263f041265e8697e4b270132b9889486ce4f


I contacted the author and committer, but they had no way to verify on mesa.

I'll forward to deqp-external-requests@google.com
Comment 4 Ilia Mirkin 2019-02-03 14:26:25 UTC
(In reply to Mark Janes from comment #3)
> This test was broken in the dEQP suite recently for m32 i965 platforms by:

FWIW I don't think this is a test bug. The shaders used appear perfectly reasonable. It seems like the commit in question would have changed the generated shader a bit, which could be triggering the different behavior (seems likely, in fact). But ultimately this is a mesa issue, not a dEQP issue.
Comment 5 asimiklit 2019-02-04 15:30:15 UTC
Hi,

I managed to reproduce this issue using provided shader under KBL with latest mesa from git.
This happens with 'BlockB' field:
ir->data.max_array_access is 1
and
ir->type->length is 1 too

I am going to continue my investigation.

Thanks,
Andrii.
Comment 6 asimiklit 2019-02-04 16:38:39 UTC
Created attachment 143288 [details]
this simple program helps me to reproduce this issue.

just share my simple reproducer)

Run it in this way:

   simple_reproducer shader.comp
Comment 7 asimiklit 2019-02-05 15:19:14 UTC
(In reply to Ilia Mirkin from comment #2)
> Looks like this is happening in link_uniform_blocks. The type gets updated:
> 
>       if (b->array != NULL &&
>           (b->type->without_array()->interface_packing ==
>            GLSL_INTERFACE_PACKING_PACKED)) {
>          b->type = resize_block_array(b->type, b->array);
>          b->var->type = b->type;
>       }
> 
> But no change to the corresponding max_data_access. However doing the naive
> thing here didn't help -- the shader fails. I didn't investigate why. I
> think create_buffer_blocks also needs to be involved somehow.

Thanks a lot your message was very helpful to find the start point of investigation.

Looks like this thing is helped:

---
 src/compiler/glsl/link_uniform_blocks.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/compiler/glsl/link_uniform_blocks.cpp b/src/compiler/glsl/link_uniform_blocks.cpp
index 0b890586298..5197870a6d9 100644
--- a/src/compiler/glsl/link_uniform_blocks.cpp
+++ b/src/compiler/glsl/link_uniform_blocks.cpp
@@ -438,8 +438,15 @@ link_uniform_blocks(void *mem_ctx,
       if (b->array != NULL &&
           (b->type->without_array()->interface_packing ==
            GLSL_INTERFACE_PACKING_PACKED)) {
+         const int new_max_array_access = (int)(b->array->num_array_elements - 1);
          b->type = resize_block_array(b->type, b->array);
          b->var->type = b->type;
+
+         assert(((int)b->array->array_elements[new_max_array_access] ==
+                b->var->data.max_array_access ||
+                b->var->data.max_array_access == -1) && "Is last index is proper");
+
+         b->var->data.max_array_access = new_max_array_access;
       }
 
       block_size.num_active_uniforms = 0;
-- 
2.17.1

Did you mean the same thing saying "naive thing" or this change helps?
Comment 8 Ilia Mirkin 2019-02-05 15:27:02 UTC
(In reply to asimiklit from comment #7)
> (In reply to Ilia Mirkin from comment #2)
> > Looks like this is happening in link_uniform_blocks. The type gets updated:
> > 
> >       if (b->array != NULL &&
> >           (b->type->without_array()->interface_packing ==
> >            GLSL_INTERFACE_PACKING_PACKED)) {
> >          b->type = resize_block_array(b->type, b->array);
> >          b->var->type = b->type;
> >       }
> > 
> > But no change to the corresponding max_data_access. However doing the naive
> > thing here didn't help -- the shader fails. I didn't investigate why. I
> > think create_buffer_blocks also needs to be involved somehow.
> 
> Thanks a lot your message was very helpful to find the start point of
> investigation.
> 
> Looks like this thing is helped:
> 
> ---
>  src/compiler/glsl/link_uniform_blocks.cpp | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/src/compiler/glsl/link_uniform_blocks.cpp
> b/src/compiler/glsl/link_uniform_blocks.cpp
> index 0b890586298..5197870a6d9 100644
> --- a/src/compiler/glsl/link_uniform_blocks.cpp
> +++ b/src/compiler/glsl/link_uniform_blocks.cpp
> @@ -438,8 +438,15 @@ link_uniform_blocks(void *mem_ctx,
>        if (b->array != NULL &&
>            (b->type->without_array()->interface_packing ==
>             GLSL_INTERFACE_PACKING_PACKED)) {
> +         const int new_max_array_access =
> (int)(b->array->num_array_elements - 1);
>           b->type = resize_block_array(b->type, b->array);
>           b->var->type = b->type;
> +
> +         assert(((int)b->array->array_elements[new_max_array_access] ==
> +                b->var->data.max_array_access ||
> +                b->var->data.max_array_access == -1) && "Is last index is
> proper");
> +
> +         b->var->data.max_array_access = new_max_array_access;
>        }
>  
>        block_size.num_active_uniforms = 0;
> -- 
> 2.17.1
> 
> Did you mean the same thing saying "naive thing" or this change helps?

Well, as I recall the thing I tried was just saying max_array_access = 0 or -1 unconditionally. It could also have been due to some secondary issue with nouveau that this failed -- like I said, I didn't investigate. I'll have a closer look tonight.

You're basically setting

b->var->data.max_array_access = b->type->length - 1

right?
Comment 9 asimiklit 2019-02-05 16:02:40 UTC
(In reply to Ilia Mirkin from comment #8)
> (In reply to asimiklit from comment #7)
> > (In reply to Ilia Mirkin from comment #2)
> > > Looks like this is happening in link_uniform_blocks. The type gets updated:
> > > 
> > >       if (b->array != NULL &&
> > >           (b->type->without_array()->interface_packing ==
> > >            GLSL_INTERFACE_PACKING_PACKED)) {
> > >          b->type = resize_block_array(b->type, b->array);
> > >          b->var->type = b->type;
> > >       }
> > > 
> > > But no change to the corresponding max_data_access. However doing the naive
> > > thing here didn't help -- the shader fails. I didn't investigate why. I
> > > think create_buffer_blocks also needs to be involved somehow.
> > 
> > Thanks a lot your message was very helpful to find the start point of
> > investigation.
> > 
> > Looks like this thing is helped:
> > 
> > ---
> >  src/compiler/glsl/link_uniform_blocks.cpp | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/src/compiler/glsl/link_uniform_blocks.cpp
> > b/src/compiler/glsl/link_uniform_blocks.cpp
> > index 0b890586298..5197870a6d9 100644
> > --- a/src/compiler/glsl/link_uniform_blocks.cpp
> > +++ b/src/compiler/glsl/link_uniform_blocks.cpp
> > @@ -438,8 +438,15 @@ link_uniform_blocks(void *mem_ctx,
> >        if (b->array != NULL &&
> >            (b->type->without_array()->interface_packing ==
> >             GLSL_INTERFACE_PACKING_PACKED)) {
> > +         const int new_max_array_access =
> > (int)(b->array->num_array_elements - 1);
> >           b->type = resize_block_array(b->type, b->array);
> >           b->var->type = b->type;
> > +
> > +         assert(((int)b->array->array_elements[new_max_array_access] ==
> > +                b->var->data.max_array_access ||
> > +                b->var->data.max_array_access == -1) && "Is last index is
> > proper");
> > +
> > +         b->var->data.max_array_access = new_max_array_access;
> >        }
> >  
> >        block_size.num_active_uniforms = 0;
> > -- 
> > 2.17.1
> > 
> > Did you mean the same thing saying "naive thing" or this change helps?
> 
> Well, as I recall the thing I tried was just saying max_array_access = 0 or
> -1 unconditionally. It could also have been due to some secondary issue with
> nouveau that this failed -- like I said, I didn't investigate. I'll have a
> closer look tonight.

Got it.

> 
> You're basically setting
> 
> b->var->data.max_array_access = b->type->length - 1
> 
> right?

Yes. I guess that the optimized array size - 1 is a new max_array_access. 


But in case if optimization algorithm has some unexpected behavior and could left some unused elements in array I guess the search will be required:
for (int i = 0; i < b->array->num_array_elements; i++)
{
   if(b->var->data.max_array_access == b->array->array_elements[i])
   {
     b->var->data.max_array_access = i;
     break;
   }
}(In reply to Ilia Mirkin from comment #8)
> (In reply to asimiklit from comment #7)
> > (In reply to Ilia Mirkin from comment #2)
> > > Looks like this is happening in link_uniform_blocks. The type gets updated:
> > > 
> > >       if (b->array != NULL &&
> > >           (b->type->without_array()->interface_packing ==
> > >            GLSL_INTERFACE_PACKING_PACKED)) {
> > >          b->type = resize_block_array(b->type, b->array);
> > >          b->var->type = b->type;
> > >       }
> > > 
> > > But no change to the corresponding max_data_access. However doing the naive
> > > thing here didn't help -- the shader fails. I didn't investigate why. I
> > > think create_buffer_blocks also needs to be involved somehow.
> > 
> > Thanks a lot your message was very helpful to find the start point of
> > investigation.
> > 
> > Looks like this thing is helped:
> > 
> > ---
> >  src/compiler/glsl/link_uniform_blocks.cpp | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/src/compiler/glsl/link_uniform_blocks.cpp
> > b/src/compiler/glsl/link_uniform_blocks.cpp
> > index 0b890586298..5197870a6d9 100644
> > --- a/src/compiler/glsl/link_uniform_blocks.cpp
> > +++ b/src/compiler/glsl/link_uniform_blocks.cpp
> > @@ -438,8 +438,15 @@ link_uniform_blocks(void *mem_ctx,
> >        if (b->array != NULL &&
> >            (b->type->without_array()->interface_packing ==
> >             GLSL_INTERFACE_PACKING_PACKED)) {
> > +         const int new_max_array_access =
> > (int)(b->array->num_array_elements - 1);
> >           b->type = resize_block_array(b->type, b->array);
> >           b->var->type = b->type;
> > +
> > +         assert(((int)b->array->array_elements[new_max_array_access] ==
> > +                b->var->data.max_array_access ||
> > +                b->var->data.max_array_access == -1) && "Is last index is
> > proper");
> > +
> > +         b->var->data.max_array_access = new_max_array_access;
> >        }
> >  
> >        block_size.num_active_uniforms = 0;
> > -- 
> > 2.17.1
> > 
> > Did you mean the same thing saying "naive thing" or this change helps?
> 
> Well, as I recall the thing I tried was just saying max_array_access = 0 or
> -1 unconditionally. It could also have been due to some secondary issue with
> nouveau that this failed -- like I said, I didn't investigate. I'll have a
> closer look tonight.

Got it.

> 
> You're basically setting
> 
> b->var->data.max_array_access = b->type->length - 1
> 
> right?

Yes. I guess that the optimized array size - 1 is a new max_array_access.

But in case if optimization algorithm has some "unexpected behavior" and could left some unused elements at the end of array for some reason I guess the some search may be required:

for (int i = 0; i < b->array->num_array_elements; i++)
{
   if(b->var->data.max_array_access == b->array->array_elements[i])
   {
     b->var->data.max_array_access = i;
     break;
   }
}
Comment 10 Ilia Mirkin 2019-02-05 16:04:38 UTC
Does your patch make the test pass on i965? If so, I'll have to figure out where in st/mesa or nouveau it dies.
Comment 11 asimiklit 2019-02-05 16:26:52 UTC
The i965 tests is in progress and result will be appear here (in an hour I think):

https://mesa-ci.01.org/global_logic/builds/

It will be "Build # 70"

The commit which is under test:
https://gitlab.freedesktop.org/GL/mesa/commit/526a9fee0e40a450bc71092b27a3b89cbbf93fd7
Comment 12 Mark Janes 2019-02-05 17:29:51 UTC
(In reply to asimiklit from comment #11)
> https://mesa-ci.01.org/global_logic/builds/
> 
> It will be "Build # 70"
> 

With this build, i965 reports test failure instead of assertion (the same status as for m32).  Before the dEQP change, this test passed.

Since the status has been different for 32-bit binaries, I'm rebuilding with that configuration (see build # 71)
Comment 13 andrii simiklit 2019-02-05 19:00:04 UTC
(In reply to Mark Janes from comment #12)
> (In reply to asimiklit from comment #11)
> > https://mesa-ci.01.org/global_logic/builds/
> > 
> > It will be "Build # 70"
> > 
> 
> With this build, i965 reports test failure instead of assertion (the same
> status as for m32).  Before the dEQP change, this test passed.
> 
> Since the status has been different for 32-bit binaries, I'm rebuilding with
> that configuration (see build # 71)

Thank you) But unfortunately the tests failed so guess I didn't consider something. I am going to continue my investigation)
Comment 14 Ilia Mirkin 2019-02-05 19:21:59 UTC
(In reply to andrii simiklit from comment #13)
> Thank you) But unfortunately the tests failed so guess I didn't consider
> something. I am going to continue my investigation)

Did the test actually pass for you? Or just not crash? When I made my "naive" change, it fixed the crash, but the test continued to fail.
Comment 15 Mark Janes 2019-02-05 20:15:15 UTC
(In reply to Ilia Mirkin from comment #14)
> Did the test actually pass for you? Or just not crash? When I made my
> "naive" change, it fixed the crash, but the test continued to fail.

On i965, tests did not crash, but they continued to fail.
Comment 16 andrii simiklit 2019-02-06 07:51:15 UTC
(In reply to Ilia Mirkin from comment #14)
> (In reply to andrii simiklit from comment #13)
> > Thank you) But unfortunately the tests failed so guess I didn't consider
> > something. I am going to continue my investigation)
> 
> Did the test actually pass for you? Or just not crash? When I made my
> "naive" change, it fixed the crash, but the test continued to fail.

Sorry for misudestanding (In reply to Ilia Mirkin from comment #14)
> (In reply to andrii simiklit from comment #13)
> > Thank you) But unfortunately the tests failed so guess I didn't consider
> > something. I am going to continue my investigation)
> 
> Did the test actually pass for you? Or just not crash? When I made my
> "naive" change, it fixed the crash, but the test continued to fail.

Oops I thought you ask just about crash. Sorry for confusion.
So I have the same results. I will try to understand why test fails today.
Comment 17 Ian Romanick 2019-02-08 20:55:22 UTC
(In reply to asimiklit from comment #6)
> Created attachment 143288 [details]
> this simple program helps me to reproduce this issue.
> 
> just share my simple reproducer)
> 
> Run it in this way:
> 
>    simple_reproducer shader.comp

It seems like this could be made into a piglit test that could be compiled with glslparsertest.  If you haven't already submitted such a test, please do. :)
Comment 18 Ian Romanick 2019-02-08 21:48:49 UTC
(In reply to asimiklit from comment #7)
> (In reply to Ilia Mirkin from comment #2)
> > Looks like this is happening in link_uniform_blocks. The type gets updated:
> > 
> >       if (b->array != NULL &&
> >           (b->type->without_array()->interface_packing ==
> >            GLSL_INTERFACE_PACKING_PACKED)) {
> >          b->type = resize_block_array(b->type, b->array);
> >          b->var->type = b->type;
> >       }
> > 
> > But no change to the corresponding max_data_access. However doing the naive
> > thing here didn't help -- the shader fails. I didn't investigate why. I
> > think create_buffer_blocks also needs to be involved somehow.
> 
> Thanks a lot your message was very helpful to find the start point of
> investigation.
> 
> Looks like this thing is helped:
> 
> ---
>  src/compiler/glsl/link_uniform_blocks.cpp | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/src/compiler/glsl/link_uniform_blocks.cpp
> b/src/compiler/glsl/link_uniform_blocks.cpp
> index 0b890586298..5197870a6d9 100644
> --- a/src/compiler/glsl/link_uniform_blocks.cpp
> +++ b/src/compiler/glsl/link_uniform_blocks.cpp
> @@ -438,8 +438,15 @@ link_uniform_blocks(void *mem_ctx,
>        if (b->array != NULL &&
>            (b->type->without_array()->interface_packing ==
>             GLSL_INTERFACE_PACKING_PACKED)) {
> +         const int new_max_array_access =
> (int)(b->array->num_array_elements - 1);
>           b->type = resize_block_array(b->type, b->array);
>           b->var->type = b->type;
> +
> +         assert(((int)b->array->array_elements[new_max_array_access] ==
> +                b->var->data.max_array_access ||
> +                b->var->data.max_array_access == -1) && "Is last index is
> proper");
> +
> +         b->var->data.max_array_access = new_max_array_access;
>        }
>  
>        block_size.num_active_uniforms = 0;

I don't think this has any chance of being correct.  max_array_access is set based on actual, known accesses to the array.  Changing that arbitrarily is just lying to the rest of the compiler.  Nothing good can come from that.  Since the type of the array is now wrong, my guess is that the test fails (instead of crashes) because the part of the array that has the data the shader wants is optimized away.

How does the mismatch between max_array_access and the type occur in the first place?  My guess is that this is the source of the bug.  They *must* agree at some point, or an earlier part of the compile would have generated an error (as required by the spec).
Comment 19 andrii simiklit 2019-02-09 20:33:28 UTC
(In reply to Ian Romanick from comment #18)
> (In reply to asimiklit from comment #7)
> > (In reply to Ilia Mirkin from comment #2)
> > > Looks like this is happening in link_uniform_blocks. The type gets updated:
> > > 
> > >       if (b->array != NULL &&
> > >           (b->type->without_array()->interface_packing ==
> > >            GLSL_INTERFACE_PACKING_PACKED)) {
> > >          b->type = resize_block_array(b->type, b->array);
> > >          b->var->type = b->type;
> > >       }
> > > 
> > > But no change to the corresponding max_data_access. However doing the naive
> > > thing here didn't help -- the shader fails. I didn't investigate why. I
> > > think create_buffer_blocks also needs to be involved somehow.
> > 
> > Thanks a lot your message was very helpful to find the start point of
> > investigation.
> > 
> > Looks like this thing is helped:
> > 
> > ---
> >  src/compiler/glsl/link_uniform_blocks.cpp | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/src/compiler/glsl/link_uniform_blocks.cpp
> > b/src/compiler/glsl/link_uniform_blocks.cpp
> > index 0b890586298..5197870a6d9 100644
> > --- a/src/compiler/glsl/link_uniform_blocks.cpp
> > +++ b/src/compiler/glsl/link_uniform_blocks.cpp
> > @@ -438,8 +438,15 @@ link_uniform_blocks(void *mem_ctx,
> >        if (b->array != NULL &&
> >            (b->type->without_array()->interface_packing ==
> >             GLSL_INTERFACE_PACKING_PACKED)) {
> > +         const int new_max_array_access =
> > (int)(b->array->num_array_elements - 1);
> >           b->type = resize_block_array(b->type, b->array);
> >           b->var->type = b->type;
> > +
> > +         assert(((int)b->array->array_elements[new_max_array_access] ==
> > +                b->var->data.max_array_access ||
> > +                b->var->data.max_array_access == -1) && "Is last index is
> > proper");
> > +
> > +         b->var->data.max_array_access = new_max_array_access;
> >        }
> >  
> >        block_size.num_active_uniforms = 0;
> 
> I don't think this has any chance of being correct.  max_array_access is set
> based on actual, known accesses to the array.  Changing that arbitrarily is
> just lying to the rest of the compiler.  Nothing good can come from that. 
> Since the type of the array is now wrong, my guess is that the test fails
> (instead of crashes) because the part of the array that has the data the
> shader wants is optimized away.
This is changed not arbitrarily. All elements of the new optimized array type
are 100% used so index of the last element of this array is a max_array_access, no?

> 
> How does the mismatch between max_array_access and the type occur in the
> first place?  My guess is that this is the source of the bug.  They *must*
> agree at some point, or an earlier part of the compile would have generated
> an error (as required by the spec).
Do you know where the location of the code which should leads them to agreement?
Unfortunately I didn't find this code. 
Shouldn't it be correct to lead them to agreement here?

https://gitlab.freedesktop.org/mesa/mesa/blob/master/src/compiler/glsl/link_uniform_blocks.cpp#L441
Seems like a new optimized array type should contain used/active instances only
so it should be correct to suppose that last element of this array is 100% used
and max_array_access can points to this element. Didn't I consider something here?



About deqp test, it fails in such cases:

layout(local_size_x = 1) in;

layout(packed, binding = 0) buffer BlockB
{
        float b[1];
} blockB[2];

void main (void)
{
    blockB[1].b[0] = 77777.77777;
}

and looks like problem is here:
https://android.googlesource.com/platform/external/deqp/+/master/modules/gles31/functional/es31fSSBOLayoutCase.cpp#2249

deqp test uses binding point 1 for BlockB[1] but when we use 'packed' layout the BlockB[0] instance
is removed due to unuse and there is just one array instance BlockB[1] with assigned binding point 0 instead of 1.

Looks like it should be something like this:
   if (layoutNdx >= 0)
   {
      const BlockLocation& blockLoc = blockLocations[layoutNdx];
      if (blockLoc.size > 0)
         gl.bindBufferRange(GL_SHADER_STORAGE_BUFFER, bindingPoint, buffers[blockLoc.index].buffer, blockLoc.offset, blockLoc.size);
   
      bindingPoint += 1;
   }
   else if((block.getFlags() & LAYOUT_PACKED) == 0)
   {
      bindingPoint += 1;
   }

I read the spec and looks like it is acceptable to remove the instance of array if it isn't active.
I will provide the patch (to test it on Intel CI if possible) and more details on Monday
(because I left everything on work machine).

Thanks,
Andrii.
Comment 20 asimiklit 2019-02-11 11:54:02 UTC
Created attachment 143359 [details]
one more issue.

ERROR: ac_numPassed = 0, expected 1

void main (void)
{
	bool allOk = true;
	allOk = allOk &amp;&amp; compare_mat4(blockB[1].b[0][0], mat4(-8.0, -2.0, -1.0, 3.0, 2.0, 4.0, 1.0, -7.0, 8.0, -7.0, -1.0, 4.0, -2.0, -2.0, -6.0, 1.0));
	allOk = allOk &amp;&amp; compare_mat4(blockB[1].b[0][1], mat4(-6.0, -2.0, 2.0, 7.0, -7.0, 8.0, -2.0, -7.0, 2.0, 0.0, 3.0, 9.0, 8.0, 2.0, -6.0, -2.0));
	allOk = allOk &amp;&amp; compare_int(f, 9);
	allOk = allOk &amp;&amp; compare_ivec4(blockD.g[0], ivec4(8, 4, -3, 0));
	allOk = allOk &amp;&amp; compare_ivec4(blockD.g[1], ivec4(-9, 7, -9, 8));
	if (allOk)
		atomicCounterIncrement(ac_numPassed);

	blockB[1].b[0][0] = mat4(-6.0, -7.0, -9.0, 8.0, 3.0, -8.0, 9.0, -1.0, 5.0, 3.0, -9.0, -4.0, -8.0, -6.0, 9.0, 0.0);
	blockB[1].b[0][1] = mat4(-4.0, 9.0, -2.0, 0.0, 2.0, -3.0, 5.0, 0.0, 1.0, -2.0, -3.0, 2.0, 2.0, -6.0, 2.0, -8.0);
	c = mat4x3(-5.0, -3.0, -3.0, 0.0, 8.0, -9.0, 2.0, -4.0, 1.0, 8.0, 7.0, -4.0);
	blockD.g[0] = ivec4(-4, -3, -8, 8);
	blockD.g[1] = ivec4(-8, 3, -1, 4);
}

Hmm, unfortunately there is some additional issue in the mesa or deqp.
So some variable were copied incorrectly by test or mesa or we lost something...
So I will investigate it too.

(Shared code is in attachment)
Comment 21 asimiklit 2019-02-11 13:49:50 UTC
So the previously mentioned issue was due to issue in my fix. 
I fixed my it and locally I have the following results:

./deqp-gles31 -n dEQP-GLES31.functional.ssbo.*

Test run totals:
  Passed:        2061/2061 (100.0%)
  Failed:        0/2061 (0.0%)
  Not supported: 0/2061 (0.0%)
  Warnings:      0/2061 (0.0%)


It with mesa assertion fix and with deqp fix.
Without the mesa fix it is still crashes even if the deqp fix is applied:
   Test case 'dEQP-GLES31.functional.ssbo.layout.random.all_per_block_buffers.18'..
   ir_variable has maximum access out of bounds (1 vs 0)
   Aborted (core dumped)

deqp: 
   https://github.com/asimiklit/deqp/commit/91cff8150944213f6da533e281ee76d95ca00f21

mesa:
   https://gitlab.freedesktop.org/GL/mesa/commit/526a9fee0e40a450bc71092b27a3b89cbbf93fd7

So I am actually not 100% sure about which binding point should be assigned 
for BlockB[1] instance in the following case:

   layout(local_size_x = 1) in;

   layout(packed, binding = 0) buffer BlockB
   {
           float b[1];
   } blockB[2];

   void main (void)
   {
       blockB[1].b[0] = 77777.77777;
   }

But according to next comment it should be 0 because of the BlockB[0] was optimized
and there is the BlockB[1] only:

   /* The ARB_shading_language_420pack spec says:
    *
    *    If the binding identifier is used with a uniform block instanced as
    *    an array then the first element of the array takes the specified
    *    block binding and each subsequent element takes the next consecutive
    *    uniform block binding point.
    */

https://gitlab.freedesktop.org/mesa/mesa/blob/master/src/compiler/glsl/link_uniform_blocks.cpp#L279-310

Mark is it possible to check both patches under Intel CI?

mesa:
   fork: https://gitlab.freedesktop.org/asimiklit/mesa/
   branch: max_array_access

deqp:
   fork: https://github.com/asimiklit/deqp/
   branch: array_instance_binding_fix
Comment 22 Mark Janes 2019-02-11 16:07:28 UTC
The combination of deqp/mesa patches passed CI.  The only failure was 

  piglit.spec.!opengl 1_1.tex-upside-down-miptree

This test is new and was fixed on mesa master.  The fix is probably not in the tested developer branch.

You should contact deqp-external-requests@google.com to make your case that the deqp test is buggy.
Comment 23 asimiklit 2019-02-11 16:21:37 UTC
(In reply to Mark Janes from comment #22)
> The combination of deqp/mesa patches passed CI.  The only failure was 
> 
>   piglit.spec.!opengl 1_1.tex-upside-down-miptree
> 
> This test is new and was fixed on mesa master.  The fix is probably not in
> the tested developer branch.
> 
> You should contact deqp-external-requests@google.com to make your case that
> the deqp test is buggy.

Cool, thanks a lot.
I will contact them tomorrow)
Comment 24 Ilia Mirkin 2019-02-11 17:18:05 UTC
"""
But according to next comment it should be 0 because of the BlockB[0] was optimized
and there is the BlockB[1] only:

   /* The ARB_shading_language_420pack spec says:
    *
    *    If the binding identifier is used with a uniform block instanced as
    *    an array then the first element of the array takes the specified
    *    block binding and each subsequent element takes the next consecutive
    *    uniform block binding point.
    */
"""

I don't think that's enough justification for the "mesa" way of doing it. Whether a block is eliminated or not is not specified by GLSL spec. Would be good to get some more experienced opinions on this. [Not mine...]
Comment 25 asimiklit 2019-02-12 12:22:19 UTC
(In reply to asimiklit from comment #23)
> (In reply to Mark Janes from comment #22)
> > The combination of deqp/mesa patches passed CI.  The only failure was 
> > 
> >   piglit.spec.!opengl 1_1.tex-upside-down-miptree
> > 
> > This test is new and was fixed on mesa master.  The fix is probably not in
> > the tested developer branch.
> > 
> > You should contact deqp-external-requests@google.com to make your case that
> > the deqp test is buggy.
> 
> Cool, thanks a lot.
> I will contact them tomorrow)

I don't know, is it make sense to contact deqp-external-requests@google.com
with questions about specs they used to write this test, according to the last Ilia comment?
I think I rather won't contact them until we have 100% explanation how it should work.
I have been trying to find some explanation how we should assign binding points for
the ssbo array instances with packed layout case but
unfortunately didn't find any concrete answer yet.

It is possible that the deqp fix will migrate to mesa depends on answer which we will find.
Comment 26 asimiklit 2019-02-12 12:59:36 UTC
(In reply to Ian Romanick from comment #17)
> (In reply to asimiklit from comment #6)
> > Created attachment 143288 [details]
> > this simple program helps me to reproduce this issue.
> > 
> > just share my simple reproducer)
> > 
> > Run it in this way:
> > 
> >    simple_reproducer shader.comp
> 
> It seems like this could be made into a piglit test that could be compiled
> with glslparsertest.  If you haven't already submitted such a test, please
> do. :)

I work on it)
Comment 27 asimiklit 2019-02-15 11:58:30 UTC
(In reply to Ilia Mirkin from comment #24)
> """
> But according to next comment it should be 0 because of the BlockB[0] was
> optimized
> and there is the BlockB[1] only:
> 
>    /* The ARB_shading_language_420pack spec says:
>     *
>     *    If the binding identifier is used with a uniform block instanced as
>     *    an array then the first element of the array takes the specified
>     *    block binding and each subsequent element takes the next consecutive
>     *    uniform block binding point.
>     */
> """
> 
> I don't think that's enough justification for the "mesa" way of doing it.
> Whether a block is eliminated or not is not specified by GLSL spec. Would be
> good to get some more experienced opinions on this. [Not mine...]

I have asked about it here:
https://github.com/KhronosGroup/OpenGL-API/issues/46
Hope that somebody will clarify it)
Comment 28 Mark Janes 2019-02-15 17:25:19 UTC
Chris Forbes at google found a patch that explains at least some of the reason for this test regression:

  https://android-review.googlesource.com/c/platform/external/deqp/+/901894

I just realized that this bug is a dupe the one I opened when the test regressed.  Since the discussion is here, I'll close that one.
Comment 29 Mark Janes 2019-02-15 17:26:46 UTC
*** Bug 109260 has been marked as a duplicate of this bug. ***
Comment 30 Mark Janes 2019-02-15 18:55:49 UTC
(In reply to Mark Janes from comment #28)
>   https://android-review.googlesource.com/c/platform/external/deqp/+/901894

Mesa still asserts with this fix.  I also tested Andrii's mesa patch with the dEQP fix and the test fails.

Since non-mesa drivers have found issues with the original dEQP change, I suspect there are still deeper problems with the test.
Comment 31 andrii simiklit 2019-02-15 20:44:30 UTC
(In reply to Mark Janes from comment #30)
> (In reply to Mark Janes from comment #28)
> >   https://android-review.googlesource.com/c/platform/external/deqp/+/901894
> 
> Mesa still asserts with this fix.  I also tested Andrii's mesa patch with
> the dEQP fix and the test fails.
Do you mean the Chris's dEQP fix here, yes?
But looks like the mentioned Chris's dEQP fix considers some GL limitations and doesn't affect the expectations of binding points.

Also the assertion is a separate issue, I created the piglit test for that:
https://patchwork.freedesktop.org/patch/286287/
But yes, we unable to fix the test fail without assertion because of crash :-)

> 
> Since non-mesa drivers have found issues with the original dEQP change, I
> suspect there are still deeper problems with the test.
Possible they have the same issue with binding points mismatch after optimizations by glsl compiler. 
They could try this fix/hack for deqp which is already helped us:
https://github.com/asimiklit/deqp/commit/91cff8150944213f6da533e281ee76d95ca00f21
If it helps them we will know that it is a common issue and it could expedite this:
https://github.com/KhronosGroup/OpenGL-API/issues/46
Comment 32 andrii simiklit 2019-02-16 10:09:31 UTC
(In reply to andrii simiklit from comment #31)
> (In reply to Mark Janes from comment #30)
> > (In reply to Mark Janes from comment #28)
> > >   https://android-review.googlesource.com/c/platform/external/deqp/+/901894
> > 
> > Mesa still asserts with this fix.  I also tested Andrii's mesa patch with
> > the dEQP fix and the test fails.
> Do you mean the Chris's dEQP fix here, yes?
> But looks like the mentioned Chris's dEQP fix considers some GL limitations
> and doesn't affect the expectations of binding points.
> 
> Also the assertion is a separate issue, I created the piglit test for that:
> https://patchwork.freedesktop.org/patch/286287/
> But yes, we unable to fix the test fail without assertion because of crash
> :-)
> 
> > 
> > Since non-mesa drivers have found issues with the original dEQP change, I
> > suspect there are still deeper problems with the test.
> Possible they have the same issue with binding points mismatch after
> optimizations by glsl compiler. 
> They could try this fix/hack for deqp which is already helped us:
> https://github.com/asimiklit/deqp/commit/
> 91cff8150944213f6da533e281ee76d95ca00f21
> If it helps them we will know that it is a common issue and it could
> expedite this:
> https://github.com/KhronosGroup/OpenGL-API/issues/46

So we have an answer from Piers Daniell:
  "I believe all buffer binding points should be consumed, regardless whether 
   the array elements are used or not. This would be the behavior of least 
   surprise to the developer. I didn't see any language that would indicate 
   that unused elements should not be counted when assigning the element to 
   the buffer binding point."

Looks like according to that current mesa implementation is mistaken and dEQP test is right.
So my dEQP "fix" should migrate to mesa somehow.
Are Ilia and Ian agree it?
Is nobody against if I investigate and try to fix it?

Seems like the the binding point increment is done somewhere here:
https://gitlab.freedesktop.org/mesa/mesa/blob/master/src/compiler/glsl/link_uniform_blocks.cpp#L279-310
Comment 33 Ian Romanick 2019-02-20 19:54:59 UTC
(In reply to andrii simiklit from comment #32)
> (In reply to andrii simiklit from comment #31)
> > (In reply to Mark Janes from comment #30)
> > > (In reply to Mark Janes from comment #28)
> > > >   https://android-review.googlesource.com/c/platform/external/deqp/+/901894
> > > 
> > > Mesa still asserts with this fix.  I also tested Andrii's mesa patch with
> > > the dEQP fix and the test fails.
> > Do you mean the Chris's dEQP fix here, yes?
> > But looks like the mentioned Chris's dEQP fix considers some GL limitations
> > and doesn't affect the expectations of binding points.
> > 
> > Also the assertion is a separate issue, I created the piglit test for that:
> > https://patchwork.freedesktop.org/patch/286287/
> > But yes, we unable to fix the test fail without assertion because of crash
> > :-)
> > 
> > > 
> > > Since non-mesa drivers have found issues with the original dEQP change, I
> > > suspect there are still deeper problems with the test.
> > Possible they have the same issue with binding points mismatch after
> > optimizations by glsl compiler. 
> > They could try this fix/hack for deqp which is already helped us:
> > https://github.com/asimiklit/deqp/commit/
> > 91cff8150944213f6da533e281ee76d95ca00f21
> > If it helps them we will know that it is a common issue and it could
> > expedite this:
> > https://github.com/KhronosGroup/OpenGL-API/issues/46
> 
> So we have an answer from Piers Daniell:
>   "I believe all buffer binding points should be consumed, regardless
> whether 
>    the array elements are used or not. This would be the behavior of least 
>    surprise to the developer. I didn't see any language that would indicate 
>    that unused elements should not be counted when assigning the element to 
>    the buffer binding point."

I think this basically agrees with my earlier sentiment that we shouldn't trim elements from the beginning of the array.  It's generally ok (and in some cases expected) to trim elements from the end.
Comment 34 asimiklit 2019-02-21 12:14:34 UTC
(In reply to asimiklit from comment #26)
> (In reply to Ian Romanick from comment #17)
> > (In reply to asimiklit from comment #6)
> > > Created attachment 143288 [details]
> > > this simple program helps me to reproduce this issue.
> > > 
> > > just share my simple reproducer)
> > > 
> > > Run it in this way:
> > > 
> > >    simple_reproducer shader.comp
> > 
> > It seems like this could be made into a piglit test that could be compiled
> > with glslparsertest.  If you haven't already submitted such a test, please
> > do. :)
> 
> I work on it)
The two piglit tests were suggested:
https://patchwork.freedesktop.org/patch/286287/
Comment 35 asimiklit 2019-02-21 15:38:03 UTC
Created attachment 143430 [details] [review]
patch to disallow an elimination of the first unused ub/ssbo array elements

(In reply to Ian Romanick from comment #33)
> (In reply to andrii simiklit from comment #32)
> > (In reply to andrii simiklit from comment #31)
> > > (In reply to Mark Janes from comment #30)
> > > > (In reply to Mark Janes from comment #28)
> > > > >   https://android-review.googlesource.com/c/platform/external/deqp/+/901894
> > > > 
> > > > Mesa still asserts with this fix.  I also tested Andrii's mesa patch with
> > > > the dEQP fix and the test fails.
> > > Do you mean the Chris's dEQP fix here, yes?
> > > But looks like the mentioned Chris's dEQP fix considers some GL limitations
> > > and doesn't affect the expectations of binding points.
> > > 
> > > Also the assertion is a separate issue, I created the piglit test for that:
> > > https://patchwork.freedesktop.org/patch/286287/
> > > But yes, we unable to fix the test fail without assertion because of crash
> > > :-)
> > > 
> > > > 
> > > > Since non-mesa drivers have found issues with the original dEQP change, I
> > > > suspect there are still deeper problems with the test.
> > > Possible they have the same issue with binding points mismatch after
> > > optimizations by glsl compiler. 
> > > They could try this fix/hack for deqp which is already helped us:
> > > https://github.com/asimiklit/deqp/commit/
> > > 91cff8150944213f6da533e281ee76d95ca00f21
> > > If it helps them we will know that it is a common issue and it could
> > > expedite this:
> > > https://github.com/KhronosGroup/OpenGL-API/issues/46
> > 
> > So we have an answer from Piers Daniell:
> >   "I believe all buffer binding points should be consumed, regardless
> > whether 
> >    the array elements are used or not. This would be the behavior of least 
> >    surprise to the developer. I didn't see any language that would indicate 
> >    that unused elements should not be counted when assigning the element to 
> >    the buffer binding point."
> 
> I think this basically agrees with my earlier sentiment that we shouldn't
> trim elements from the beginning of the array.  It's generally ok (and in
> some cases expected) to trim elements from the end.

Are you talking about something like attached variant?
Comment 36 asimiklit 2019-02-22 10:48:11 UTC
(In reply to Ian Romanick from comment #33)
> (In reply to andrii simiklit from comment #32)
> > (In reply to andrii simiklit from comment #31)
> > > (In reply to Mark Janes from comment #30)
> > > > (In reply to Mark Janes from comment #28)
> > > > >   https://android-review.googlesource.com/c/platform/external/deqp/+/901894
> > > > 
> > > > Mesa still asserts with this fix.  I also tested Andrii's mesa patch with
> > > > the dEQP fix and the test fails.
> > > Do you mean the Chris's dEQP fix here, yes?
> > > But looks like the mentioned Chris's dEQP fix considers some GL limitations
> > > and doesn't affect the expectations of binding points.
> > > 
> > > Also the assertion is a separate issue, I created the piglit test for that:
> > > https://patchwork.freedesktop.org/patch/286287/
> > > But yes, we unable to fix the test fail without assertion because of crash
> > > :-)
> > > 
> > > > 
> > > > Since non-mesa drivers have found issues with the original dEQP change, I
> > > > suspect there are still deeper problems with the test.
> > > Possible they have the same issue with binding points mismatch after
> > > optimizations by glsl compiler. 
> > > They could try this fix/hack for deqp which is already helped us:
> > > https://github.com/asimiklit/deqp/commit/
> > > 91cff8150944213f6da533e281ee76d95ca00f21
> > > If it helps them we will know that it is a common issue and it could
> > > expedite this:
> > > https://github.com/KhronosGroup/OpenGL-API/issues/46
> > 
> > So we have an answer from Piers Daniell:
> >   "I believe all buffer binding points should be consumed, regardless
> > whether 
> >    the array elements are used or not. This would be the behavior of least 
> >    surprise to the developer. I didn't see any language that would indicate 
> >    that unused elements should not be counted when assigning the element to 
> >    the buffer binding point."
> 
> I think this basically agrees with my earlier sentiment that we shouldn't
> trim elements from the beginning of the array.  It's generally ok (and in
> some cases expected) to trim elements from the end.

Ilia could you please share your thoughts about this solution?
Do you agree with Ian suggestion as to disallow the elimination from the beginning of the array?
I am asking about it to understand have we consensus as to a direction of the fix or not.
Comment 37 Rob Clark 2019-02-23 01:52:32 UTC
fwiw, after rebasing deqp, I started hitting the same thing (freedreno/a6xx) with debug mesa builds vs dEQP-GLES31.functional.ssbo.layout.random.all_per_block_buffers.18

So I guess the same issue.. I'll read more thru the rest of this bz tomorrow since already getting late, but just thought I'd mention it (and add myself to cc on this bz)
Comment 38 Ilia Mirkin 2019-02-23 01:57:39 UTC
(In reply to asimiklit from comment #36)
> Ilia could you please share your thoughts about this solution?
> Do you agree with Ian suggestion as to disallow the elimination from the
> beginning of the array?
> I am asking about it to understand have we consensus as to a direction of
> the fix or not.

Sounds good to me... I think you can do something like

layout(binding=n) foo[6]

means that n..n+5 are all taken and assigned to the relevant items.

However if you just have "foo[6]", without the explicit binding, you can (and should) eliminate any pre- and post- elements, i.e. before the first and after the last. However if foo[1] and foo[5] are used, then they should be 4 binding points away from one another.

Hope that makes sense.
Comment 39 Mark Janes 2019-02-25 06:07:09 UTC
I just noticed that this new test passes for 32 bit builds.

Does that surprise anyone else?

http://mesa-ci.01.org/mesa_master_daily/builds/4806/group/e60513df13ade427f01bb7334bd5174e
Comment 40 andrii simiklit 2019-02-25 08:02:44 UTC
(In reply to Mark Janes from comment #39)
> I just noticed that this new test passes for 32 bit builds.
> 
> Does that surprise anyone else?
> 
> http://mesa-ci.01.org/mesa_master_daily/builds/4806/group/
> e60513df13ade427f01bb7334bd5174e

Thanks that pointed that out.
I didn't see any platform specific code there.
I will post an update here as far as I figure out the reason.
Comment 41 asimiklit 2019-02-25 14:02:04 UTC
(In reply to andrii simiklit from comment #40)
> (In reply to Mark Janes from comment #39)
> > I just noticed that this new test passes for 32 bit builds.
> > 
> > Does that surprise anyone else?
> > 
> > http://mesa-ci.01.org/mesa_master_daily/builds/4806/group/
> > e60513df13ade427f01bb7334bd5174e
> 
> Thanks that pointed that out.
> I didn't see any platform specific code there.
> I will post an update here as far as I figure out the reason.

Unfortunately I can't to reproduce this behavior locally.
I built the 32-bit debug mesa + 32-bit debug piglit and have the following results:
   asimiklit@asimiklit-pc:~/projects/piglit32$ bin/glslparsertest
   tests/spec/arb_shader_storage_buffer_object/compiler
   /unused-array-element.comp pass 4.50 
   ir_variable has maximum access out of bounds (1 vs 0)
   Aborted (core dumped)

glslparsertest and mesa 100% have 32-bit architecture:
   asimiklit@asimiklit-pc:~/projects/piglit32$ file bin/glslparsertest
   bin/glslparsertest: ELF 32-bit LSB shared object, Intel 80386, 
   version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, 
   for GNU/Linux 3.2.0, BuildID[sha1]=0243d96a1caf7c54189447516b066e5582ef86aa,
   with debug_info, not stripped

   asimiklit@asimiklit-pc:~/projects/piglit32$ ldd bin/glslparsertest
   ........
   libgbm.so.1 => /home/.../mesa_versions/1802_32_dbg/lib/libgbm.so.1 (0xf7a9d000)
   libGL.so.1 => /home/.../mesa_versions/1802_32_dbg/lib/libGL.so.1 (0xf7a09000)
   libEGL.so.1 => /home/.../mesa_versions/1802_32_dbg/lib/libEGL.so.1 (0xf7554000)
   libglapi.so.0 => /home/.../mesa_versions/1802_32_dbg/lib/libglapi.so.0 (0xf7466000)
   .......

   asimiklit@asimiklit-pc:~/projects/piglit32$ file /home/.../mesa_versions
   /1802_32_dbg/lib/libGL.so.1.2.0 
   /home/.../mesa_versions/1802_32_dbg/lib/libGL.so.1.2.0: ELF 32-bit LSB shared object, 
   Intel 80386, version 1 (SYSV), dynamically linked,    
   BuildID[sha1]=8708ca7f174b267838c5b1ffe71ca68d5307f62d, with debug_info, not stripped

   PS: I know that 1802 in the folder name isn't a correct name
       for the latest mesa folder name but I just forgot to update it in prefix :-)


Mark could you please clarify which mesa configuration is used
with 32-bit piglit, debug or release? Because I see the same behavior
just with a release mesa configuration.
Comment 42 Mark Janes 2019-02-25 15:44:52 UTC
i965 CI runs debug builds by default, but for mesa it uses these meson configurations:

  -Dbuildtype=release -Db_ndebug=true

We must catch assertions in the CI, however debug builds are much slower to execute tests.
Comment 43 Mark Janes 2019-02-25 23:43:41 UTC
On my local system, I can easily reproduce the 32-bit pass, and the 64-bit crash.  This is unusual, however the dEQP bug that started all of this also has a different 32 and 64 bit signature.


---------------------------------------
/tmp/build_root/m32/lib/piglit/bin/glslparsertest /tmp/build_root/m32/lib/piglit/tests/spec/arb_shader_storage_buffer_object/compiler/unused-array-element.comp pass 4.30 
piglit: debug: Requested an OpenGL 4.3 Core Context, and received a matching 4.5 context

Successfully compiled compute shader /tmp/build_root/m32/lib/piglit/tests/spec/arb_shader_storage_buffer_object/compiler/unused-array-element.comp: (no compiler output)
PIGLIT: {"result": "pass" }

---------------------------------------

/tmp/build_root/m64/lib/piglit/bin/glslparsertest /tmp/build_root/m64/lib/piglit/tests/spec/arb_shader_storage_buffer_object/compiler/unused-array-element.comp pass 4.30 
piglit: debug: Requested an OpenGL 4.3 Core Context, and received a matching 4.5 context

ir_variable has maximum access out of bounds (1 vs 0)
Aborted

---------------------------------------
Comment 44 asimiklit 2019-02-26 12:32:57 UTC
(In reply to Mark Janes from comment #42)
> i965 CI runs debug builds by default, but for mesa it uses these meson
> configurations:
> 
>   -Dbuildtype=release -Db_ndebug=true
> 
> We must catch assertions in the CI, however debug builds are much slower to
> execute tests.

My tests depends on DEBUG macro:
https://gitlab.freedesktop.org/mesa/mesa/blob/master/src/compiler/glsl/ir_validate.cpp#L1059-1073

So if DEBUG macro is not defined my tests should not call critical
code which leads mesa to crash and should just pass.

Also from 'meson.build':
https://gitlab.freedesktop.org/mesa/mesa/blob/master/meson.build#L742-745
  "# Define DEBUG for debug builds only (debugoptimized is not included on this one)
   if get_option('buildtype') == 'debug'
     pre_args += '-DDEBUG'
   endif
   "

So as far as I understood DEBUG macro will be defined for '-Dbuildtype=debug' 
configuration only but as you mentioned above the mesa is compiled with '-Dbuildtype=release'
in this case my tests should just pass without crash.

Does CI use the same configurations for x32 and x64 mesa builds or
maybe x64 uses debug mesa config '-Dbuildtype=debug'?
Comment 45 Mark Janes 2019-02-26 17:12:34 UTC
PKG_CONFIG_PATH=/tmp/build_root/m64/lib/pkgconfig:/tmp/build_root/m64/lib64/pkgconfig:/tmp/build_root/m64/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/lib64/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig CC=ccache gcc LD_LIBRARY_PATH=/tmp/build_root/m64/lib:/tmp/build_root/m64/lib64:/tmp/build_root/m64/lib/x86_64-linux-gnu:/usr/lib:/usr/lib64:/usr/lib/x86_64-linux-gnu CPPFLAGS=-DDEBUG CXX=ccache g++ meson /home/jenkins/workspace/Leeroy_2/repos/mesa/build_mesa_m64 --prefix /tmp/build_root/m64 --libdir lib -Ddri-drivers=i965,i915 -Dvulkan-drivers=intel -Dplatforms=x11,drm -Dtools=intel -Dgallium-drivers=iris -Dllvm=false



PKG_CONFIG_PATH=/tmp/build_root/m32/lib/pkgconfig:/tmp/build_root/m32/lib/i386-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib/pkgconfig CC=ccache gcc LD_LIBRARY_PATH=/tmp/build_root/m32/lib:/tmp/build_root/m32/lib/i386-linux-gnu:/usr/lib:/usr/lib/i386-linux-gnu CPPFLAGS=-DDEBUG CXX=ccache g++ meson /home/jenkins/workspace/Leeroy/repos/mesa/build_mesa_m32 --prefix /tmp/build_root/m32 --libdir lib --cross-file /home/jenkins/workspace/Leeroy/mesa/../repos/mesa_ci/build_support/x86-linux-gcc.cross -Ddri-drivers=i965,i915 -Dvulkan-drivers=intel -Dplatforms=x11,drm -Dtools=intel -Dgallium-drivers=iris -Dllvm=false

Both builds pass CPPFLAGS=-DDEBUG, but the cross file also specifies cpp_args, which may conflict.  I'll check with Dylan, who created that automation.
Comment 46 Mark Janes 2019-02-26 17:33:54 UTC
I confirmed that the cross file is overriding our 32 bit flags that we pass through the environment.
Comment 47 Dylan Baker 2019-02-26 17:52:33 UTC
Created attachment 143478 [details]
attachment-11105-0.html

It's not that the cross file is overriding, CFLAGS and friends are for
native (build) targets, not cross (host) targets.

I'm on mobile, please excuse autocorrect fail.

On Tue, Feb 26, 2019, 09:33 <bugzilla-daemon@freedesktop.org> wrote:

> *Comment # 46 <https://bugs.freedesktop.org/show_bug.cgi?id=109532#c46> on
> bug 109532 <https://bugs.freedesktop.org/show_bug.cgi?id=109532> from Mark
> Janes <mark.a.janes@intel.com> *
>
> I confirmed that the cross file is overriding our 32 bit flags that we pass
> through the environment.
>
> ------------------------------
> You are receiving this mail because:
>
>    - You are on the CC list for the bug.
>
>
Comment 48 asimiklit 2019-02-27 11:58:11 UTC
(In reply to Mark Janes from comment #46)
> I confirmed that the cross file is overriding our 32 bit flags that we pass
> through the environment.

(In reply to Dylan Baker from comment #47)
> Created attachment 143478 [details]
> attachment-11105-0.html
> 
> It's not that the cross file is overriding, CFLAGS and friends are for
> native (build) targets, not cross (host) targets.
> 
> I'm on mobile, please excuse autocorrect fail.
> 
> On Tue, Feb 26, 2019, 09:33 <bugzilla-daemon@freedesktop.org> wrote:
> 
> > *Comment # 46 <https://bugs.freedesktop.org/show_bug.cgi?id=109532#c46> on
> > bug 109532 <https://bugs.freedesktop.org/show_bug.cgi?id=109532> from Mark
> > Janes <mark.a.janes@intel.com> *
> >
> > I confirmed that the cross file is overriding our 32 bit flags that we pass
> > through the environment.
> >
> > ------------------------------
> > You are receiving this mail because:
> >
> >    - You are on the CC list for the bug.
> >
> >

To be 100% sure what going on with the DEBUG and NDEBUG macros I suggest to build a following branch:
https://gitlab.freedesktop.org/asimiklit/mesa/tree/check_if_DEBUG_enabled
This branch contains following commit:
     void
    validate_ir_tree(exec_list *instructions)
    {
   +#ifdef DEBUG
   +   hmm_DEBUG_MACRO_is_defined = 1;
   +#else
   +   hmm_DEBUG_MACRO_is_NOT_defined = 1;
   +#endif
   +
   +#ifdef NDEBUG
   +   hmm_NDEBUG_is_defined_so_asserts_are_disabled = 1;
   +#else
   +   hmm_NDEBUG_is_NOT_defined_so_asserts_are_enabled = 1;
   +#endif

It should just produce compiling errors.
But depends on a error message we could understand which macros are defined :-)

Actually I tried to run it here:
https://mesa-ci.01.org/global_logic/builds/89/group/63a9f0ea7bb98050796b649e85481845

But I don't have an ability to see compiler error message because there is displayed just that and just for m64:

stdout:
Command '['make', '-j', '18']' returned non-zero exit status 2

stderr:
NULL
Comment 49 Ian Romanick 2019-02-27 16:37:30 UTC
After discussing https://github.com/KhronosGroup/OpenGL-API/issues/46 in the Khronos call today, I realized that my thinking about this bug may have been slightly incorrect.  I believe that there are two separate issues here.

1. The issue with the array type and the maximum index.

2. The way the bindings are assigned to the elements that are used.

No matter what happens, if the shader says

   layout(packed, binding = 3) buffer Block
   {
           float b[1];
   } block[4];

Then the thing accessed in the shader as block[2].b[0] **must** be at binding point 5 (from the API).  The user as explicitly set that to binding 5 by the declaration in the shader, so we absolutely have to respect that.  Had the application not explicitly set the bindings, I think we would be free to assign whatever values we wanted.  I believe that means the bindings set by the CTS in the problematic test are correct.

I think we also cannot reuse the intermediate bindings.  The app may have expectations that those bindings are for elements of block, and it may blindly bind buffers to those bindings.  If those bindings are used for other things, only problems can result.  I think this means we effectively cannot eliminate array elements from buffer block arrays that have explicit bindings.  85% sure, anyway.
Comment 50 asimiklit 2019-02-28 14:02:10 UTC
(In reply to Ian Romanick from comment #49)
> After discussing https://github.com/KhronosGroup/OpenGL-API/issues/46 in the
> Khronos call today, I realized that my thinking about this bug may have been
> slightly incorrect.  I believe that there are two separate issues here.
> 
> 1. The issue with the array type and the maximum index.
> 
> 2. The way the bindings are assigned to the elements that are used.
> 
> No matter what happens, if the shader says
> 
>    layout(packed, binding = 3) buffer Block
>    {
>            float b[1];
>    } block[4];
> 
> Then the thing accessed in the shader as block[2].b[0] **must** be at
> binding point 5 (from the API).  The user as explicitly set that to binding
> 5 by the declaration in the shader, so we absolutely have to respect that. 
> Had the application not explicitly set the bindings, I think we would be
> free to assign whatever values we wanted.  I believe that means the bindings
> set by the CTS in the problematic test are correct.
> 
> I think we also cannot reuse the intermediate bindings.  The app may have
> expectations that those bindings are for elements of block, and it may
> blindly bind buffers to those bindings.  If those bindings are used for
> other things, only problems can result.  I think this means we effectively
> cannot eliminate array elements from buffer block arrays that have explicit
> bindings.  85% sure, anyway.

Ian could you please confirm if I understood everything correctly
and clarify the **implicit case** too.

1. So everything is clear when user explicitly set binding point, in this case
we should not optimize anything at all.

2. But looks like we are not 100% sure what to do with the **implicit case**.
   Let's consider options:

   layout(packed) buffer Block
   {
       float b[1];
   } block[6];

   (The shader uses block[1] and block[4])

   2.1. As it works now. Eliminate any unused array elements
        and shrink array to reuse binding points. (Note: will not pass deqp test)
      + we spend just 2 binding points for Block[1], Block[4]
      - it very unexpected behavior for user because:
         Block[0] is eliminated
         Block[1] binding point is 0
         Block[2] is eliminated
         Block[3] is eliminated
         Block[4] binding point is 1
         Block[5] is eliminated

   2.2. Find first and last used elements and
        eliminate any before the first and after the last.
        This option was suggested by Ilia, Ian do you agree it?
        (Note: looks like should pass deqp test)
      + we spend 4 of 6 binding points
      - it better than 2.1 but looks like still not very
        expected behavior for user:
         Block[0] is eliminated
         Block[1] binding point is 0
         Block[2] binding point is 1
         Block[3] binding point is 2
         Block[4] binding point is 3
         Block[5] is eliminated

   2.3. Find just last used element and eliminate any after the last.
      + we spend 5 of 6 binding points (Note: but if there is a big array
        with a big unused tail it should helps)
     +- quite expected behavior for user:
         Block[0] binding point is 0
         Block[1] binding point is 1
         Block[2] binding point is 2
         Block[3] binding point is 3
         Block[4] binding point is 4
         Block[5] is eliminated

   2.4. Avoid elimination at all like for explicitly case
       + very expected behavior for user
       - we spend 6 of 6 binding points
         Block[0] binding point is 0
         Block[1] binding point is 1
         Block[2] binding point is 2
         Block[3] binding point is 3
         Block[4] binding point is 4
         Block[5] binding point is 5


I created MR for it:
https://gitlab.freedesktop.org/mesa/mesa/merge_requests/332
It has WIP status because we aren't reached an agreement yet.
But anyway I will be glad to see any advices there.
Comment 51 asimiklit 2019-03-01 14:20:52 UTC
We have one more answer from Piers Daniell:
  "We discussed this in the OpenGL/ES working group meeting and agreed that
   eliminating unused elements from the interface block array is not desirable. 
   There is no statement in the spec that this takes place and it would be highly 
   implementation dependent if it happens. If the application has an "interface" in
   the shader they need to match up with the API it would be quite confusing to have
   the binding point get compacted. So the answer is no, the binding points aren't 
   affected by unused elements in the interface block array."

So looks like according to it we should remove this optimization at all.
Regardless whether explicit or implicit case we should not optimize it.
I guess we can remove this optimization for 'packed' blocks by
removing this exclusive cases and just handle it like 'std140' and 'shared' layouts:

https://gitlab.freedesktop.org/mesa/mesa/blob/master/src/compiler/glsl/link_uniform_block_active_visitor.cpp#L254-261

and

https://gitlab.freedesktop.org/mesa/mesa/blob/master/src/compiler/glsl/link_uniform_block_active_visitor.cpp#L170-171
Comment 52 asimiklit 2019-03-05 15:54:03 UTC
Created attachment 143535 [details] [review]
draft of a solution

Currently I am trying to find another way to fix this issue
to avoid removal of an optimization because this optimization
isn't only for minimization of the binding points usage but
it also helps to minimize usage of some other stuff,
however I'm not sure if this is even possible.

But all Intel CI tests are passed:
https://mesa-ci.01.org/global_logic/builds/101/group/63a9f0ea7bb98050796b649e85481845
Comment 53 asimiklit 2019-03-06 10:07:02 UTC
(In reply to asimiklit from comment #52)
> Created attachment 143535 [details] [review] [review]
> draft of a solution
> 
> Currently I am trying to find another way to fix this issue
> to avoid removal of an optimization because this optimization
> isn't only for minimization of the binding points usage but
> it also helps to minimize usage of some other stuff,
> however I'm not sure if this is even possible.
> 
> But all Intel CI tests are passed:
> https://mesa-ci.01.org/global_logic/builds/101/group/
> 63a9f0ea7bb98050796b649e85481845

I have suggested this solution here:
https://gitlab.freedesktop.org/mesa/mesa/merge_requests/332
Comment 54 GitLab Migration User 2019-09-18 19:46:35 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/mesa/mesa/issues/823.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.