[Bug target/53376] Unrecognizable compare insn generated by movsicc in arm backend.

ramana at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed May 16 23:49:00 GMT 2012


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53376

--- Comment #3 from Ramana Radhakrishnan <ramana at gcc dot gnu.org> 2012-05-16 23:23:43 UTC ---
(In reply to comment #2)
> (In reply to comment #0)
> > extern int x;
> > static long long p;
> > static long long *h1 ;
> > static long long *h2 ;
> > 
> > void foo (void)
> > {
> >     int i ;
> >     for( i = 0 ; i < x ; i++ )
> >     {
> >       if( (p >> 3)  > 5000)
> >         p += 5000;
> >     *h2 = *h1 ;
> >     h2++;
> >     }
> > }
> > 
> > 
> > Fails with an ICE 
> > 
> > 
> > > (insn 1166 1165 1167 155 (set (reg:CC 24 cc)
> > >        (compare:CC (reg:SI 2148 [ D.6766 ])
> > >            (const_int 5000 [0x1388]))) iirflt01/bmark.c:501 -1
> > >     (nil))
> > > internal compiler error: in extract_insn, at
> > > recog.c:2131
> > 
> > Compares with 5000 really aren't allowed and we appear to happily generate this
> > in this particular case - The patch below completely untested fixes this by
> > forcing invalid operations of the comparison into a register like what happens
> > in other parts of the compiler that use arm_gen_compare_reg - 
> > 
> > For all cases other than DImode arm_gen_compare_reg expects to get only valid
> > operands to the arms of the compare. There are a number of places where these
> > checks already happen before the call to arm_gen_compare_reg and therefore it
> > seems pointless to check twice. 
> > 
> > diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> > index b1ad3bf..04be822 100644
> > --- a/gcc/config/arm/arm.md
> > +++ b/gcc/config/arm/arm.md
> > @@ -8144,6 +8144,9 @@
> >      if (code == UNEQ || code == LTGT)
> >        FAIL;
> > 
> > +    if (!arm_add_operand (XEXP (operands[1], 1), SImode))
> > +      XEXP (operands[1], 1) = force_reg (SImode, XEXP (operands[1], 1));
> > +
> >      ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
> >                                  XEXP (operands[1], 1), NULL_RTX);
> >      operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
> > 
> > 
> > 
> > regards,
> > Ramana
> 
> FTR this isn't safe.  There's no requirement for the comparison to be SImode;
> it could be an FP mode or some other precision.

Agreed (as I said it was completely untested and something off the cuff) -
Reading the code more I realized that I am probably better off doing the
validation inside arm_gen_compare_reg for various modes. 

Ramana



More information about the Gcc-bugs mailing list