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