This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH V3 05/11] bpf: new GCC port


jose.marchesi@oracle.com (Jose E. Marchesi) writes:
>         > +(define_expand "zero_extendsidi2"
>         > +  [(set (match_operand:DI 0 "register_operand")
>         > +	(zero_extend:DI (match_operand:SI 1 "reg_or_indirect_memory_operand")))]
>         > +  ""
>         > +{
>         > +  if (register_operand (operands[1], SImode))
>         > +    {
>         > +      operands[1] = gen_lowpart (DImode, operands[1]);
>         > +      emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (32)));
>         > +      emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (32)));
>         > +      DONE;
>         > +    }
>         > +})
>         > +
>         > +(define_insn "*zero_extendsidi2"
>         > +  [(set (match_operand:DI 0 "register_operand" "=r,r")
>         > +	(zero_extend:DI (match_operand:SI 1 "reg_or_indirect_memory_operand" "0,m")))]
>         > +  ""
>         > +  "@
>         > +   lsh\t%0,32\n\trsh\t%0,32
>         > +   ldxw\t%0,%1"
>         > +  [(set_attr "type" "alu,ldx")
>         > +   (set_attr "length" "16,8")])
>         
>         Sorry, should have noticed last time, but: you shouldn't need to handle
>         register operands here given the expander above.  It's OK if you find it
>         improves code quality, but it'd be interesting to know why if so....
>     
>     If I remove the 0,=r alternative from the insn above, and also adjust
>     the predicate to indirect_memory_operand, then I get a segfault in one
>     test, in update_costs_from_allocno (ira-color.c:1382), because:
>     
>     (gdb) print mode
>     $1 = E_SImode
>     (gdb) print default_target_ira_int->x_ira_register_move_cost[mode]
>     $13 = (move_table *) 0x0
>     
>     What I think is going on is:
>     
>     1. The expand above is used, and
>     
>     2. there is no insn in the program matched by a pattern that involves a
>        SI operand, and therefore record_operand_costs is never called on
>        SImode operand, and therefore the lazily-initialized
>        x_ira_register_move_cost is never filled in for E_SImode, and then
>     
>     3. ira() -> ira_color() -> color () -> do_coloring () ->
>        ira_traverse_loop_tree () -> color_pass () -> color_allocnos () ->
>        update_costs_from_prefs () -> update_costs_from_allocno () *CRASH*
>     
>     Is this a bug, or am I expected to somehow trigger the initialization of
>     the SImode entry in the ira register move table in some other way?
>
> This is the backtrace btw:
>
> jemarch@termi:~/gnu/src/gcc-git/build-bpf/gcc$ PATH=.:$PATH ./xgcc -O2 -c /home/jemarch/gnu/src/gcc-git/gcc/testsuite/gcc.c-torture/compile/pr39928-2.c
> during RTL pass: ira
> /home/jemarch/gnu/src/gcc-git/gcc/testsuite/gcc.c-torture/compile/pr39928-2.c: In function ‘vq_nbest’:
> /home/jemarch/gnu/src/gcc-git/gcc/testsuite/gcc.c-torture/compile/pr39928-2.c:8:1: internal compiler error: Segmentation fault
>     8 | }
>       | ^
> 0xfa8cb7 crash_signal
> 	../../gcc/toplev.c:326
> 0x7f278d44e05f ???
> 	/build/glibc-yWQXbR/glibc-2.24/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
> 0xd4ec8b update_costs_from_allocno
> 	../../gcc/ira-color.c:1382
> 0xd4ee09 update_costs_from_prefs
> 	../../gcc/ira-color.c:1422
> 0xd535d9 color_allocnos
> 	../../gcc/ira-color.c:3170
> 0xd53e21 color_pass
> 	../../gcc/ira-color.c:3309
> 0xd39b10 ira_traverse_loop_tree(bool, ira_loop_tree_node*, void (*)(ira_loop_tree_node*), void (*)(ira_loop_tree_node*))
> 	../../gcc/ira-build.c:1781
> 0xd54703 do_coloring
> 	../../gcc/ira-color.c:3460
> 0xd58203 color
> 	../../gcc/ira-color.c:4837
> 0xd58746 ira_color()
> 	../../gcc/ira-color.c:4968
> 0xd34990 ira
> 	../../gcc/ira.c:5365
> 0xd35118 execute
> 	../../gcc/ira.c:5663
> Please submit a full bug report,
> with preprocessed source if appropriate.
> Please include the complete backtrace with any bug report.
> See <https://gcc.gnu.org/bugs/> for instructions.

Yeah, this looks like a bug.  Further up we have:

      mode = ALLOCNO_MODE (allocno);
      ira_init_register_move_cost_if_necessary (mode);

which copes with the lazy initialisation.  But then we have:

	  mode = narrower_subreg_mode (mode, ALLOCNO_MODE (cp->second));
	  
	  cost = (cp->second == allocno
		  ? ira_register_move_cost[mode][rclass][aclass]
		  : ira_register_move_cost[mode][aclass][rclass]);

where we can change the mode without initialising the move cost tables.
Does it work if you change it to:

	  if (paradoxical_subreg_p (mode, ALLOCNO_MODE (cp->second)))
	    {
	      mode = ALLOCNO_MODE (cp->second);
	      ira_init_register_move_cost_if_necessary (mode);
	    }

?  The mode handling seems generally a bit weird though: we never
reset "mode" when processing the next copy, and "cp->second" might
be "allocno" itself, depending on which way round the move is.
But the above seems like an obvious change relative to the status quo.

Richard


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]