This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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

             Bug #: 53376
           Summary: Unrecognizable compare insn generated by movsicc in
                    arm backend.
    Classification: Unclassified
           Product: gcc
           Version: 4.8.0
            Status: UNCONFIRMED
          Keywords: ice-on-valid-code
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: ramana@gcc.gnu.org
            Target: arm-linux-gnueabi
             Build: x86*


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]