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

             Bug #: 50193
           Summary: ARM: ICE on a | (b << negative-constant)
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: michael.h...@linaro.org


trunk r178025, 4.6.1, and 4.5.3 all ICE with unsatisfied constraints on the
following code:

int foo(int a, int b)
{
    return a | (b << -3);
}

shift.c: In function 'foo':
shift.c:3:5: warning: left shift count is negative [enabled by default]
shift.c:4:1: error: insn does not satisfy its constraints:
(insn 14 9 17 2 (set (reg/i:SI 0 r0)
        (ior:SI (ashift:SI (reg:SI 1 r1 [ b ])
                (const_int -3 [0xfffffffffffffffd]))
            (reg:SI 0 r0 [ a ]))) shift.c:4 259 {*arith_shiftsi}
     (expr_list:REG_DEAD (reg:SI 1 r1 [ b ])
        (nil)))
shift.c:4:1: internal compiler error: in extract_constrain_insn_cached, at
recog.c:2030

This happens with -mcpu=cortex-a9 -mthumb.  With -marm, GCC recognises that the
shift is unusual, loads it into a register, then uses this in the
register-shifted-register form of ORR.  This form isn't available in Thumb-2.

The problem was originally seen in libtheora:lib/mathops.c when built with -O3
-funroll-loops when a shift by negative 8 is generated.

Reply via email to