Bug 30552

Summary: loop_analysis.h:193: bool loop_variable::is_loop_constant() const: Assertion `!this->var->read_only || (this->var->read_only && is_const)' failed.
Product: Mesa Reporter: Vinson Lee <vlee>
Component: Mesa coreAssignee: Ian Romanick <idr>
Status: CLOSED FIXED QA Contact:
Severity: critical    
Priority: medium CC: brianp
Version: git   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Bug Depends on:    
Bug Blocks: 30124    

Description Vinson Lee 2010-10-01 18:31:30 UTC
mesa: 64a9fc3fc15603a8e25d0e1146fe5da5a5bde55b (master)

I've seen this crash several times with VMware Workstation running a Windows guest. I'm going to try to narrow this down and provide reproducible steps.


loop_analysis.h:193: bool loop_variable::is_loop_constant() const: Assertion `!this->var->read_only || (this->var->read_only && is_const)' failed.

(gdb) bt full
#0  0x00120422 in __kernel_vsyscall ()
No symbol table info available.
#1  0x005c6651 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
        resultvar = <value optimized out>
        pid = 7282676
        selftid = 17151
#2  0x005c9a82 in *__GI_abort () at abort.c:92
        act = {__sigaction_handler = {sa_handler = 0x3014ce0, sa_sigaction = 0x3014ce0}, sa_mask = warning: can't find linker symbol for virtual table for `(null)' value
{__val = {6344605, 312, 168, 50417104, 50416892, 312, 168, 160, 234274736, 
              7282676, 160, 159, 50417064, 6275458, 234274744, 160, 50417104, 246372032, 0, 4222451712, 234274744, 234274845, 234274744, 234274744, 234274903, 234275044, 
              234274744, 234275044, 0, 0, 0, 0}}, sa_flags = 0, sa_restorer = 0x2}
        sigs = {__val = {32, 0 <repeats 31 times>}}
#3  0x005bf718 in *__GI___assert_fail (assertion=0x29399d8 "!this->var->read_only || (this->var->read_only && is_const)", file=0x2939980 "loop_analysis.h", line=193, 
    function=0x2939b40 "bool loop_variable::is_loop_constant() const") at assert.c:81
        buf = 0xdf6bfb8 "vmware-vmx: loop_analysis.h:193: bool loop_variable::is_loop_constant() const: Assertion `!this->var->read_only || (this->var->read_only && is_const)' failed.\n"
#4  0x02740ff0 in loop_variable::is_loop_constant (this=0xdf6f168) at loop_analysis.h:193
        is_const = false
        __PRETTY_FUNCTION__ = "bool loop_variable::is_loop_constant() const"
#5  0x0274077a in loop_analysis::visit_leave (this=0x3015024, ir=0xe6b7808) at loop_analysis.cpp:230
        lv = 0xdf6f168
        node = 0xdf6f168
        __next = 0xdf6b1d8
        ls = 0xeaf4b38
        progress = 14
        __PRETTY_FUNCTION__ = "virtual ir_visitor_status loop_analysis::visit_leave(ir_loop*)"
#6  0x0272c997 in ir_loop::accept (this=0xe6b7808, v=0x3015024) at ir_hv_accept.cpp:98
        s = visit_continue
#7  0x0272c7e1 in visit_list_elements (v=0x3015024, l=0xf0cf830) at ir_hv_accept.cpp:48
        ir = 0xe6b7808
        s = visit_continue
        n = 0xe6b780c
        __next = 0xeb0fc9c
        prev_base_ir = 0xf0cf808
#8  0x0272ca3e in ir_function_signature::accept (this=0xf0cf808, v=0x3015024) at ir_hv_accept.cpp:120
        s = visit_continue
#9  0x0272c7e1 in visit_list_elements (v=0x3015024, l=0xf0cf7c8) at ir_hv_accept.cpp:48
        ir = 0xf0cf808
        s = visit_continue
        n = 0xf0cf80c
        __next = 0xf0cf7cc
        prev_base_ir = 0xf0cf7b0
#10 0x0272cac7 in ir_function::accept (this=0xf0cf7b0, v=0x3015024) at ir_hv_accept.cpp:132
        s = visit_continue
#11 0x0272c7e1 in visit_list_elements (v=0x3015024, l=0xe714d50) at ir_hv_accept.cpp:48
        ir = 0xf0cf7b0
        s = visit_continue
        n = 0xf0cf7b4
        __next = 0xe714d54
        prev_base_ir = 0x0
#12 0x0272c73a in ir_hierarchical_visitor::run (this=0x3015024, instructions=0xe714d50) at ir_hierarchical_visitor.cpp:282
No locals.
#13 0x02740e14 in analyze_loop_variables (instructions=0xe714d50) at loop_analysis.cpp:494
        v = {<ir_hierarchical_visitor> = {_vptr.ir_hierarchical_visitor = 0x296f028, base_ir = 0xe6b7808, callback = 0, data = 0x0, in_assignee = false}, loops = 0xdcf8e70, 
          if_statement_depth = 0, current_assignment = 0x0, state = {head = 0x3015048, tail = 0x0, tail_pred = 0x3015044}}
#14 0x027171a9 in do_common_optimization (ir=0xe714d50, linked=true, max_unroll_iterations=32) at glsl_parser_extras.cpp:726
        progress = 1 '\001'
        ls = 0x1
#15 0x0273f617 in link_shaders (ctx=0xdf2a600, prog=0xe19e778) at linker.cpp:1475
        i = 0
        vert_shader_list = 0xdf61300
        num_frag_shaders = 0
        min_version = 110
        max_version = 110
        __PRETTY_FUNCTION__ = "void link_shaders(GLcontext*, gl_shader_program*)"
        num_vert_shaders = 1
        frag_shader_list = 0xdf61304
#16 0x026f840b in _mesa_glsl_link_shader (ctx=0xdf2a600, prog=0xe19e778) at program/ir_to_mesa.cpp:2624
        i = 1
#17 0x02689b2b in link_program (ctx=0xdf2a600, program=287) at main/shaderapi.c:833
        shProg = 0xe19e778
        obj = 0xd325a08
        __FUNCTION__ = "link_program"
#18 0x0268ac4b in _mesa_LinkProgramARB (programObj=287) at main/shaderapi.c:1346
        ctx = 0xdf2a600

(gdb) frame 4
#4  0x02740ff0 in loop_variable::is_loop_constant (this=0xdf6f168) at loop_analysis.h:193
193	      assert(!this->var->read_only || (this->var->read_only && is_const));
(gdb) print this->var->read_only
$1 = 1
(gdb) print is_const
$2 = false
(gdb) print *this
$9 = {<exec_node> = {next = 0xdf6b1d8, prev = 0xeaf6740}, var = 0xeb0bde0, read_before_write = false, rhs_clean = false, conditional_assignment = false, 
  first_assignment = 0xeb0c018, num_assignments = 1, iv_scale = 0x0, biv = 0x0, increment = 0x0}
(gdb) print *this->var
$10 = {<ir_instruction> = {<exec_node> = {next = 0xeb0c01c, prev = 0xeb0bd84}, _vptr.ir_instruction = 0x296d7e8, ir_type = ir_type_variable, type = 0x297999c}, 
  name = 0xf0cbef8 "v", max_array_access = 0, read_only = 1, centroid = 0, invariant = 0, mode = 0, interpolation = 0, array_lvalue = 0, origin_upper_left = 0, 
  pixel_center_integer = 0, location = -1, warn_extension = 0x0, constant_value = 0x0}


src/glsl/loop_analysis.h
   177     inline bool is_loop_constant() const
   178     {
   179        const bool is_const = (this->num_assignments == 0)
   180           || ((this->num_assignments == 1)
   181               && !this->conditional_assignment
   182               && !this->read_before_write
   183               && this->rhs_clean);
   184  
   185        /* If the RHS of *the* assignment is clean, then there must be exactly
   186         * one assignment of the variable.
   187         */
   188        assert((this->rhs_clean && (this->num_assignments == 1))
   189               || !this->rhs_clean);
   190  
   191        /* Variables that are marked read-only *MUST* be loop constant.
   192         */
   193        assert(!this->var->read_only || (this->var->read_only && is_const));
   194  
   195        return is_const;
   196     }
   197  };
Comment 1 Vinson Lee 2010-10-04 12:24:45 UTC
I've created a new piglit test, glsl-link-bug30552, which reproduces the crash.
Comment 2 Vinson Lee 2010-10-04 12:32:58 UTC
mesa: 2cdfda8851e919f26d0a4c77f6141895e4b86e38 (7.9) - same assert
mesa: 3af43c0b4c29f7cb82df72d0b65bcd190053f57c (7.8) - pass
Comment 3 Vinson Lee 2010-10-04 13:26:23 UTC
8df2dbf91ddfd0c1590e33015e85470b67e69319 is the first bad commit
commit 8df2dbf91ddfd0c1590e33015e85470b67e69319
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Thu Aug 26 16:45:22 2010 -0700

    glsl2: Perform initial bits of loop analysis during compilation

:040000 040000 3f88d7f238957cb115d99b03cf45f952c44a1f6e 3f7875e7e46b568dda8ce43a28314d40cfaedb36 M	src
bisect run success
Comment 4 Ian Romanick 2010-10-04 18:34:26 UTC
It seems to break because the function parameter is marked 'const'.  Removing 'const' from the function prototype makes the test pass.  The constness of the variable gets inlined with the rest of the function, but there's also an assignment to the variable (inside the loop).  LOLs ensue.

My guess is that removing the const decoration from inlined function parameters will fix this issue.
Comment 5 Brian Paul 2010-10-06 09:08:32 UTC
Ian, can this be fixed in the glsl compiler?  The shader is legal as-is.
Comment 6 Ian Romanick 2010-10-06 10:21:25 UTC
(In reply to comment #5)
> Ian, can this be fixed in the glsl compiler?  The shader is legal as-is.

Yes.  I just haven't gotten to it yet.  What I meant by 

> My guess is that removing the const decoration from inlined function parameters
> will fix this issue.

is that the function inliner in the compiler should remove the const decoration when it inlines the function.  I didn't mean that the shader itself should be changed.
Comment 7 Ian Romanick 2010-10-08 14:39:04 UTC
commit 0ea8b993324365769ed0aa2f7bab2dd9281b4924
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Fri Oct 8 14:29:11 2010 -0700

    glsl: Remove const decoration from inlined function parameters
    
    The constness of the function parameter gets inlined with the rest of
    the function.  However, there is also an assignment to the parameter.
    If this occurs inside a loop the loop analysis code will get confused
    by the assignment to a read-only variable.
    
    Fixes bugzilla #30552.
    
    NOTE: this is a candidate for the 7.9 branch.
Comment 8 Vinson Lee 2011-01-13 16:24:51 UTC
mesa: 31b10516636043b8d92ce518acf6afb27d82a2d1 (master)

Verified fixed.

This crash no longer appears with VMware Workstation.

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.