This is the mail archive of the gcc@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]

doloop insn generated incorrectly (wrong mode)


I have a doloop_end pattern in pdp11.md which looks like this:

(define_insn_and_split "doloop_end"
  [(set (pc)
	(if_then_else
	 (ne (match_operand:HI 0 "nonimmediate_operand" "+r,!m")
	     (const_int 1))
	 (label_ref (match_operand 1 "" ""))
	 (pc)))
   (set (match_dup 0)
	(plus:HI (match_dup 0)
		 (const_int -1)))]
  "TARGET_40_PLUS"
  "#"
...

And the loop2 dump file shows this insn sequence:

(insn 1417 1415 1418 282 (set (reg:HI 565)
        (plus:HI (subreg:HI (reg/v:QI 269 [ infcount ]) 0)
            (const_int -1 [0xffffffffffffffff]))) "../../../../../combined/newlib/libc/stdio/vfscanf.c":1474:18 62 {addhi3}
     (nil))
(insn 1418 1417 1419 282 (set (reg/v:QI 292 [ infcount ])
        (subreg:QI (reg:HI 565) 0)) "../../../../../combined/newlib/libc/stdio/vfscanf.c":1474:18 20 {movqi}
     (expr_list:REG_DEAD (reg:HI 565)
        (nil)))
(jump_insn 1419 1418 1423 282 (set (pc)
        (if_then_else (ne (reg/v:QI 269 [ infcount ])
                (const_int 3 [0x3]))
            (label_ref 1430)
            (pc))) "../../../../../combined/newlib/libc/stdio/vfscanf.c":1474:9 12 {cbranchqi4}
     (int_list:REG_BR_PROB 955630228 (nil))
 -> 1430)

which is turned into this (in loop2_doloop):

and ends up like this:

(jump_insn 2158 1447 2111 285 (parallel [
            (set (pc)
                (if_then_else (ne (reg:QI 647)
                        (const_int 1 [0x1]))
                    (label_ref 2111)
                    (pc)))
            (set (reg:QI 647)
                (plus:HI (reg:QI 647)
                    (const_int -1 [0xffffffffffffffff])))
        ]) "../../../../../combined/newlib/libc/stdio/vfscanf.c":1474:9 -1
     (int_list:REG_BR_PROB 955630228 (nil))
 -> 2111)

Note that this isn't permitted by the .md file -- the mode is wrong (QI not HI).  The result is an ICE in cfgrtl.c line 1275:

	  /* If the substitution doesn't succeed, die.  This can happen
	     if the back end emitted unrecognizable instructions or if
	     target is exit block on some arches.  */
	  if (!redirect_jump (as_a <rtx_jump_insn *> (insn),
			      block_label (new_bb), 0))
	    {
	      gcc_assert (new_bb == EXIT_BLOCK_PTR_FOR_FN (cfun));
	      return false;
	    }

It's not obvious to me how that relates to the wrong insn generated by the compiler, but clearly it can't be good to have something that won't match when it's time to generate the output code.  It seems to me that the doloop convertor should be checking the doloop_end pattern to make sure the mode matches, and not apply it unless it does.  

Why is this happening, and how can I fix it (short of removing the doloop_end pattern)?  I see a comment in loop-doloop.c about handling a FAIL of the pattern -- am I going to have to check that the wrong mode is being passed in and FAIL if so?

	paul


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