This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/53376] New: Unrecognizable compare insn generated by movsicc in arm backend.
- From: "ramana 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 12:00:24 +0000
- Subject: [Bug target/53376] New: Unrecognizable compare insn generated by movsicc in arm backend.
- Auto-submitted: auto-generated
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