RFC: [Patch, PR Bug 60818] - ICE in validate_condition_mode on powerpc*-linux-gnu* ]

Rohit Arul Raj D rohit.arul.raj.d@nxp.com
Thu Feb 18 05:49:00 GMT 2016


> -----Original Message-----
> From: Alan Modra [mailto:amodra@gmail.com]
> On Wed, Feb 17, 2016 at 06:31:45AM -0600, Segher Boessenkool wrote:
> > > (gdb) p debug_rtx (other_insn)
> > > (insn 11 10 16 2 (set (reg:SI 165 [ D.2339+-3 ])
> > >         (if_then_else:SI (ne (reg:CC 166)
> > >                 (const_int 0 [0]))
> > >             (reg:SI 168)
> > >             (reg:SI 167))) test.c:7 317 {isel_unsigned_si}
> > >      (expr_list:REG_DEAD (reg:SI 168)
> > >         (expr_list:REG_DEAD (reg:SI 167)
> > >             (expr_list:REG_DEAD (reg:CC 166)
> > >                 (expr_list:REG_EQUAL (gtu:SI (reg:CC 166)
> > >                         (const_int 0 [0]))
> > >                     (nil))))))
> >
> > The REG_EQUAL there is bad already.  Where does that come from?
> 
> Rohit explain that quite well already, I thought.  It's there due to 
> transforming a GTU to NE in another insn, which means the reg mode
> combine changes to CCmode via rs6000.h:SELECT_CC_MODE.

Yes, when the reg mode (reg:166) changes while transforming a GTU to NE,
it affects the reg mode of all reg:166 in the corresponding REG_NOTE's too.
This is the actual code which changes the mode:

File: combine.c [function: simplify_set (Line No 6604)]

#ifndef HAVE_cc0
      ....
if (compare_mode != GET_MODE (dest))
	{
	  if (can_change_dest_mode (dest, 0, compare_mode))
	    {
	.....
	      if (regno < FIRST_PSEUDO_REGISTER)
		new_dest = gen_rtx_REG (compare_mode, regno);
	      else
		{
		  SUBST_MODE (regno_reg_rtx[regno], compare_mode);---->(A)
		  new_dest = regno_reg_rtx[regno];
		}
	....
	}
#endif  /* cc0 */
#endif  /* SELECT_CC_MODE */

      /* If the code changed, we have to build a new comparison in
	 undobuf.other_insn.  */
      if (new_code != old_code)
	{
	  int other_changed_previously = other_changed;
	  unsigned HOST_WIDE_INT mask;
	  rtx old_cc_use = *cc_use;

	  SUBST (*cc_use, gen_rtx_fmt_ee (new_code, GET_MODE (*cc_use), 
					  dest, const0_rtx));                  ---------->(B)
	  other_changed = 1;

....

Content of 'other_insn' before executing (A)

(gdb) p debug_rtx (other_insn)
(insn 11 10 16 2 (set (reg:SI 165 [ D.2339+-3 ])
        (if_then_else:SI (gtu (reg:CCUNS 166)
                (const_int 0 [0]))
            (reg:SI 168)
            (reg:SI 167))) test.c:7 317 {isel_unsigned_si}
     (expr_list:REG_DEAD (reg:SI 168)
        (expr_list:REG_DEAD (reg:SI 167)
            (expr_list:REG_DEAD (reg:CCUNS 166)
                (expr_list:REG_EQUAL (gtu:SI (reg:CCUNS 166)
                        (const_int 0 [0]))
                    (nil))))))
$26 = void

Content of 'other_insn' after executing (A)

(gdb) p debug_rtx (other_insn)
(insn 11 10 16 2 (set (reg:SI 165 [ D.2339+-3 ])
        (if_then_else:SI (gtu (reg:CC 166)
                (const_int 0 [0]))
            (reg:SI 168)
            (reg:SI 167))) test.c:7 317 {isel_unsigned_si}
     (expr_list:REG_DEAD (reg:SI 168)
        (expr_list:REG_DEAD (reg:SI 167)
            (expr_list:REG_DEAD (reg:CC 166)
                (expr_list:REG_EQUAL (gtu:SI (reg:CC 166)
                        (const_int 0 [0]))
                    (nil))))))

Content of 'other_insn' after executing (B)

gdb) p debug_rtx (other_insn)
(insn 11 10 16 2 (set (reg:SI 165 [ D.2339+-3 ])
        (if_then_else:SI (ne (reg:CC 166)
                (const_int 0 [0]))
            (reg:SI 168)
            (reg:SI 167))) test.c:7 317 {isel_unsigned_si}
     (expr_list:REG_DEAD (reg:SI 168)
        (expr_list:REG_DEAD (reg:SI 167)
            (expr_list:REG_DEAD (reg:CC 166)
                (expr_list:REG_EQUAL (gtu:SI (reg:CC 166)
                        (const_int 0 [0]))
                    (nil))))))

Regards,
Rohit



More information about the Gcc-patches mailing list