Bug 50022

Summary: [4.7 regression] "incorrect condition in IT block" when building mozilla code base for ARM
Product: gcc Reporter: Mike Hommey <mh+gcc>
Component: targetAssignee: Ramana Radhakrishnan <ramana>
Status: RESOLVED FIXED    
Severity: normal CC: Greta.Yorsh, michael.hope, ramana
Priority: P3 Keywords: wrong-code
Version: 4.7.0   
Target Milestone: 4.7.0   
Host: Target: arm
Build: Known to work:
Known to fail: Last reconfirmed: 2011-08-09 16:45:43
Attachments: nsCookieService.i.xz
WIP Patch.

Description Mike Hommey 2011-08-08 10:25:14 UTC
Taking the attached preprocessed file, the following fails with latest gcc snapshot (4.7-20110806):
$ g++ -std=gnu++0x -o test.o -c nsCookieService.i -mthumb -O3 -march=armv7-a -mfloat-abi=softfp
/tmp/ccxA5O8X.s: Assembler messages:
/tmp/ccxA5O8X.s:2694: Error: incorrect condition in IT block -- `ldrdlt r2,[r3]'
/tmp/ccxA5O8X.s:2695: Error: thumb conditional instruction should be in IT block -- `smullge r2,r3,r3,r2'

The error is slightly different when adding -fomit-frame-pointer:
/tmp/ccSzGgKB.s: Assembler messages:
/tmp/ccSzGgKB.s:2702: Error: thumb conditional instruction should be in IT block -- `ldrdlt r2,[r3]'
Comment 1 Mike Hommey 2011-08-08 10:44:27 UTC
Created attachment 24949 [details]
nsCookieService.i.xz
Comment 2 Greta Yorsh 2011-08-09 15:55:46 UTC
Here is a small test case:

long long glob;
void bar(int val)
{
  glob = (val >= 0 && val <= 2147483647 ? val : 2147483647) * 1000000L; 
}

I reproduced the bug with the flags
arm-none-eabi-gcc -c  -O1 -mcpu=cortex-a8  -mthumb t1.c
but not with -O0  and not with -mcpu=cortex-a9.
By the way, changing the large numbers to smaller or removing conditions makes the error message go away. 

The error seems to be generating K+1 instructions instead of K in the IT block.


bar:
	cmp	r0, #0
	itttt	ge
	movwge	r3, #16960
	movtge	r3, 15
	mulge	r0, r3, r0
	movge	r2, r0

	ite	ge
	asrge	r3, r2, #31
	adrlt	r3, .L4
	ldrdlt	r2, [r3]

	movw	r1, #:lower16:glob
	movt	r1, #:upper16:glob
	strd	r2, [r1]
	bx	lr


-- Greta
Comment 3 Ramana Radhakrishnan 2011-08-09 16:45:43 UTC
I believe this is the same case as a breakage with building ada. I have a patch that I'm testing but I couldn't submit it as I was in the middle of other stuff last week and early this week. 

I'll try to fix this soonish.

Ramana
Comment 4 Ramana Radhakrishnan 2011-08-10 12:15:43 UTC
Created attachment 24968 [details]
WIP Patch.

A patch I'm testing but I don't very much like this given it makes this rather complex. The simple solution is to split the pattern into 2 for ARM and Thumb state and mark the Thumb state one non-predicable. I don't want to split the pattern into 2 if I can avoid it  and would rather get it working correctly if I can but anyway here goes. 

Can you check and see if this helps in your case and if any other problems show up  ?

cheers
Ramana
Comment 5 Ramana Radhakrishnan 2011-08-15 11:57:38 UTC
Author: ramana
Date: Mon Aug 15 11:57:33 2011
New Revision: 177759

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=177759
Log:


2011-08-15  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>

	PR target/50022
	* config/arm/arm.c (output_move_double): Add 2 parameters
	to count the number of insns emitted and whether to emit or not.
	Use the flag to decide when to emit and count number of instructions
	that will be emitted.
	Handle case where output_move_double might be called for calculating
	lengths with an invalid constant.
	(arm_count_output_move_double_insns): Define.
	* config/arm/arm-protos.h (arm_count_output_move_double_insns): Declare.
	(output_move_double): Adjust prototype.
	* config/arm/vfp.md ("*movdi_vfp"): Adjust call to
	output_move_double.
	("*movdi_vfp_cortexa8"): Likewise and add attribute
	for ce_count.
	* config/arm/arm.md ("*arm_movdi"): Adjust call to output_move_double.
	("*movdf_soft_insn"): Likewise.
	* config/arm/cirrus.md ("*cirrus_arm_movdi"): Likewise.
	("*cirrus_thumb2_movdi"): Likewise.
	("*thumb2_cirrus_movdf_hard_insn"): Likewise.
	("*cirrus_movdf_hard_insn"): Likewise.
	* config/arm/neon.md (*neon_mov<mode> VD): Likewise.
	* config/arm/iwmmxt.md ("*iwmmxt_arm_movdi"): Likewise.
	("mov<mode>_internal VMMX"): Likewise.
	* config/arm/fpa.md (*movdf_fpa, *thumb2_movdf_fpa): Likewise.



Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/arm/arm-protos.h
    trunk/gcc/config/arm/arm.c
    trunk/gcc/config/arm/arm.md
    trunk/gcc/config/arm/cirrus.md
    trunk/gcc/config/arm/fpa.md
    trunk/gcc/config/arm/iwmmxt.md
    trunk/gcc/config/arm/neon.md
    trunk/gcc/config/arm/vfp.md
Comment 6 Michael Hope 2011-09-07 02:21:02 UTC
For reference, I ran this against the different builds I have lying about.  The fault occurs in r177688, is gone in r178025, and does not exist in 4.5.3, 4.6.1, or gcc-linaro-4.6-2011.08.

The 4.6 and earlier compilers generate a branch instead of the itt block.
Comment 7 Ramana Radhakrishnan 2011-09-08 07:48:53 UTC
Fixed now.
Comment 8 jye2 2011-09-19 08:35:45 UTC
Author: jye2
Date: Mon Sep 19 08:35:37 2011
New Revision: 178960

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=178960
Log:
2011-09-19  Jiangning Liu  <jiangning.liu@arm.com>

	Backport r177759 from mainline
	2011-08-15  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>

	PR target/50022
	* config/arm/arm.c (output_move_double): Add 2 parameters
	to count the number of insns emitted and whether to emit or not.
	Use the flag to decide when to emit and count number of instructions
	that will be emitted.
	Handle case where output_move_double might be called for calculating
	lengths with an invalid constant.
	(arm_count_output_move_double_insns): Define.
	* config/arm/arm-protos.h (arm_count_output_move_double_insns): Declare.
	(output_move_double): Adjust prototype.
	* config/arm/vfp.md ("*movdi_vfp"): Adjust call to
	output_move_double.
	("*movdi_vfp_cortexa8"): Likewise and add attribute
	for ce_count.
	* config/arm/arm.md ("*arm_movdi"): Adjust call to output_move_double.
	("*movdf_soft_insn"): Likewise.
	* config/arm/cirrus.md ("*cirrus_arm_movdi"): Likewise.
	("*cirrus_thumb2_movdi"): Likewise.
	("*thumb2_cirrus_movdf_hard_insn"): Likewise.
	("*cirrus_movdf_hard_insn"): Likewise.
	* config/arm/neon.md (*neon_mov<mode> VD): Likewise.
	* config/arm/iwmmxt.md ("*iwmmxt_arm_movdi"): Likewise.
	("mov<mode>_internal VMMX"): Likewise.
	* config/arm/fpa.md (*movdf_fpa, *thumb2_movdf_fpa): Likewise.

2011-09-19  Jiangning Liu  <jiangning.liu@arm.com>

	Backport r176867 from mainline
	2011-07-28  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>

	* config/arm/vfp.md ("*movdf_vfp"): Handle the VFP constraints
	before the core constraints. Adjust attributes.
	(*thumb2_movdf_vfp"): Likewise.

2011-09-19  Jiangning Liu  <jiangning.liu@arm.com>

	Backport r175588 from mainline
	2011-06-28  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>

	* config/arm/vfp.md ("*divsf3_vfp"): Replace '+' constraint modifier
	with '=' constraint modifier.
	(*divdf3_vfp): Likewise.
	("*mulsf3_vfp"): Likewise.
	("*muldf3_vfp"): Likewise.
	("*mulsf3negsf_vfp"): Likewise.
	("*muldf3negdf_vfp"): Likewise.

2011-09-19  Jiangning Liu  <jiangning.liu@arm.com>

	Backport r174894 from mainline
	2011-06-10  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>
	    Richard Earnshaw  <rearnsha@arm.com>

	* config/arm/arm.c (const_ok_for_op): Check to see
	if mvn can be used.
	* config/arm/vfp.md (*arm_movdi_vfp): Delete.
	(*thumb2_movdi_vfp): Delete.
	(*arm_movdi_vfp_cortexa8): Delete.
	(*movdi_vfp): Consolidate from *arm_movdi_vfp and *thumb2_movdi_vfp.
	(*movdi_vfp_cortexa8): Likewise.

2011-09-19  Jiangning Liu  <jiangning.liu@arm.com>

	Backport r172777 from mainline
	2011-04-20  Andrew Stubbs  <ams@codesourcery.com>

	* config/arm/arm.c (arm_gen_constant): Move movw support ....
	(const_ok_for_op): ... to here.

2011-09-19  Jiangning Liu  <jiangning.liu@arm.com>

	Partially backport r171449 from mainline
	2011-03-25  Bernd Schmidt  <bernds@codesourcery.com>
 	    Andrew Stubbs  <ams@codesourcery.com>

	* config/arm/vfp.md (arm_movdi_vfp): Enable only when not tuning
	for Cortex-A8.
	(arm_movdi_vfp_cortexa8): New pattern.
	* config/arm/arm.md: Move include arm-tune.md up a bit.
	(define_attr "arch"): Add "onlya8" and "nota8" values.
	(define_attr "arch_enabled"): Handle "onlya8" and "nota8".


Modified:
    branches/ARM/embedded-4_6-branch/gcc/ChangeLog.arm
    branches/ARM/embedded-4_6-branch/gcc/config/arm/arm-protos.h
    branches/ARM/embedded-4_6-branch/gcc/config/arm/arm.c
    branches/ARM/embedded-4_6-branch/gcc/config/arm/arm.md
    branches/ARM/embedded-4_6-branch/gcc/config/arm/cirrus.md
    branches/ARM/embedded-4_6-branch/gcc/config/arm/fpa.md
    branches/ARM/embedded-4_6-branch/gcc/config/arm/iwmmxt.md
    branches/ARM/embedded-4_6-branch/gcc/config/arm/neon.md
    branches/ARM/embedded-4_6-branch/gcc/config/arm/vfp.md