[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