Bug 101766 - Assertion `!"invalid type"' failed when constant expression involves literal of different type
Summary: Assertion `!"invalid type"' failed when constant expression involves literal ...
Alias: None
Product: Mesa
Classification: Unclassified
Component: glsl-compiler (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: mesa-dev
QA Contact: Intel 3D Bugs Mailing List
Depends on:
Reported: 2017-07-12 15:00 UTC by David R. MacIver
Modified: 2017-08-16 02:22 UTC (History)
0 users

See Also:
i915 platform:
i915 features:

Shader required to reproduce assertion (66 bytes, text/plain)
2017-07-12 15:00 UTC, David R. MacIver

Note You need to log in before you can comment on or make changes to this bug.
Description David R. MacIver 2017-07-12 15:00:08 UTC
Created attachment 132634 [details]
Shader required to reproduce assertion

When the attached file is compiled with glsl_compiler, it triggers the following assertion:

glsl_compiler: glsl/ir_expression_operation_constant.h:228: virtual ir_constant* ir_expression::constant_expression_value(hash_table*): Assertion `!"invalid type"' failed.
Aborted (core dumped)

The command I used to produce this was:

glsl_compiler invalid_type.frag.frag --version=300

I tested this with a version of Mesa that I built on git version f7e78abdf45b26f3991dc336120162ae01b208f1 on Ubuntu 14.04, using LLVM 4.0.0, but I originally encountered it on a different version (also on Ubuntu) using the opengl API directly rather than glsl_compiler, so I expect the problem is not specific to my build.
Comment 1 Ilia Mirkin 2017-07-12 15:10:22 UTC
Reproduced with with glslparsertest_gles2 in piglit.

#4  0x00007ffff18b50f5 in ir_expression::constant_expression_value (this=0xbb6630, variable_context=0x0)
    at glsl/ir_expression_operation_constant.h:228
#5  0x00007ffff17e47db in convert_component (src=0xbb64b0, desired_type=0x7ffff22c2e80 <glsl_type::_float_type>)
    at glsl/ast_function.cpp:942
#6  0x00007ffff17e8757 in ast_function_expression::hir (this=0x7612b0, instructions=0xbb4b50, state=0x75fe20)
    at glsl/ast_function.cpp:2218
#7  0x00007ffff17ebad7 in ast_function_expression::hir_no_rvalue (this=0x7612b0, instructions=0xbb4b50, state=0x75fe20)
    at glsl/ast_to_hir.cpp:1088
#8  0x00007ffff17ef6be in ast_expression_statement::hir (this=0x761470, instructions=0xbb4b50, state=0x75fe20) at glsl/ast_to_hir.cpp:2198
#9  0x00007ffff17ef726 in ast_compound_statement::hir (this=0x7614b0, instructions=0xbb4b50, state=0x75fe20) at glsl/ast_to_hir.cpp:2214
#10 0x00007ffff17f7dd8 in ast_function_definition::hir (this=0x761510, instructions=0x761b50, state=0x75fe20) at glsl/ast_to_hir.cpp:6128
#11 0x00007ffff17e9c6a in _mesa_ast_to_hir (instructions=0x761b50, state=0x75fe20) at glsl/ast_to_hir.cpp:155
#12 0x00007ffff1894cb6 in _mesa_glsl_compile_shader (ctx=0x7ffff7fce040, shader=0x75fc80, dump_ast=false, dump_hir=false, 
    force_recompile=false) at glsl/glsl_parser_extras.cpp:2084
#13 0x00007ffff162938d in _mesa_compile_shader (ctx=0x7ffff7fce040, sh=0x75fc80) at main/shaderapi.c:1069

(gdb) l
223              switch (op[0]->type->base_type) {
224              case GLSL_TYPE_INT:
225                 data.f[c] = (float) op[0]->value.i[c];
226                 break;
227              default:
228                 unreachable("invalid type");
229              }
230           }
231           break;
(gdb) p op[0]->type->base_type
(gdb) p *this
$2 = {<ir_rvalue> = {<ir_instruction> = {<exec_node> = {next = 0x0, prev = 0x0}, 
      _vptr.ir_instruction = 0x7ffff22aa250 <vtable for ir_expression+16>, ir_type = ir_type_expression}, 
    type = 0x7ffff22c2e80 <glsl_type::_float_type>}, operation = ir_unop_i2f, operands = {0xbb64b0, 0x0, 0x0, 0x0}}

So makes sense that i2f wants an int input. Something must be auto-converting the int to a float, but then leaving the i2f in? Odd.
Comment 2 David R. MacIver 2017-07-12 16:58:36 UTC
> So makes sense that i2f wants an int input. Something must be auto-converting the int to a float, but then leaving the i2f in? Odd.

Note that the correct behaviour here is a compile error. If I remove the vec2() call I get an error "0:4(2): error: initializer of type int cannot be assigned to variable of type float"

So the problem is probably less auto-conversion and more bad code putting the compiler in an invalid state as it continues error checking.
Comment 3 Ilia Mirkin 2017-08-15 17:44:54 UTC
Happened to do a bit more looking.

So for the expression

const float x = 1;

the 1 is processed, and since it's part of a const assignment, it tries to assign it to x. That fails (types don't match), and so it sets state->error = true, and then ...

      } else {
         if (var->type->is_numeric()) {
            /* Reduce cascading errors. */
            var->constant_value = type->qualifier.flags.q.constant
               ? ir_constant::zero(state, var->type) : NULL;

where var->type is float (var == "x"). However rhs remains as the "1", and things in the variable are initialized based on that. This causes an inconsistency which triggers the impossible case below. I believe I have a one-line fix.
Comment 4 Ilia Mirkin 2017-08-16 02:22:59 UTC
Should be fixed with the below commit, which should appear in mesa 17.2. Thanks for the report!

commit 978c4c597aa48e65bd6822a85e6b8f82ca9281f1
Author: Ilia Mirkin <imirkin@alum.mit.edu>
Date:   Tue Aug 15 13:47:08 2017 -0400

    glsl/ast: update rhs in addition to the var's constant_value

    We continue in the code to do some more things with the rhs, including
    setting a constant initializer. If the type is wrong, this causes some
    confusion down the line, leading to assertions. This makes sure that the
    rhs processing continues to flow as-if the type was correct to start
    with (even though the state has been marked as an error state).
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101766
    Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
    Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
    Cc: mesa-stable@lists.freedesktop.org

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.