Bug 50193 - ARM: ICE on a | (b << negative-constant)
Summary: ARM: ICE on a | (b << negative-constant)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Andrew Stubbs
URL:
Keywords:
: 50947 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-08-25 22:48 UTC by Michael Hope
Modified: 2011-12-03 15:58 UTC (History)
3 users (show)

See Also:
Host:
Target: arm
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-09-01 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Hope 2011-08-25 22:48:03 UTC
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.
Comment 1 Michael Hope 2011-08-28 21:40:01 UTC
Also occurs when building LLVM trunk.  See:
 http://builds.linaro.org/toolchain/llvm-3.0~svn138625/logs/armv7l-natty-cbuild172-ursa1-cortexa9r1/llvm-build.txt

/scratch/cbuild/slave/slaves/ursa1/llvm-3.0~svn138625/llvm/llvm-3.0~/tools/clang/unittests/AST/APValueTest.cpp: In member function 'virtual void {anonymous}::APValue_Diagnostics_Test::TestBody()':
/scratch/cbuild/slave/slaves/ursa1/llvm-3.0~svn138625/llvm/llvm-3.0~/tools/clang/unittests/AST/APValueTest.cpp:77:1: error: insn does not satisfy its constraints:
(insn 1267 1266 1269 72 (set (subreg:SI (reg:DI 1327) 0)
        (ior:SI (ashift:SI (reg:SI 1330)
                (const_int -16 [0xfffffffffffffff0]))
            (subreg:SI (reg:DI 1327) 0))) /scratch/cbuild/slave/slaves/ursa1/llvm-3.0~svn138625/llvm/llvm-3.0~/include/llvm/ADT/APInt.h:140 257 {*arith_shiftsi}
     (nil))
/scratch/cbuild/slave/slaves/ursa1/llvm-3.0~svn138625/llvm/llvm-3.0~/tools/clang/unittests/AST/APValueTest.cpp:77:1: internal compiler error: in extract_constrain_insn_cached, at recog.c:2028
Comment 2 Andrew Stubbs 2011-09-01 10:19:03 UTC
The problem appears to be that the predicate accepts any constant, without checking the range.

I'll post a patch shortly.
Comment 3 Andrew Stubbs 2011-10-10 11:39:22 UTC
This has now been fixed. The patch was posted here:

http://gcc.gnu.org/ml/gcc-patches/2011-10/msg00594.html
Comment 4 Matthias Klose 2011-12-03 15:58:45 UTC
*** Bug 50947 has been marked as a duplicate of this bug. ***