This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/53376] Unrecognizable compare insn generated by movsicc in arm backend.
- From: "rearnsha at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 16 May 2012 23:18:34 +0000
- Subject: [Bug target/53376] Unrecognizable compare insn generated by movsicc in arm backend.
- Auto-submitted: auto-generated
- References: <bug-53376-4@http.gcc.gnu.org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53376
--- Comment #2 from Richard Earnshaw <rearnsha at gcc dot gnu.org> 2012-05-16 23:18:34 UTC ---
(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.