Created attachment 28483 [details] Test case If the following conditions are true, a constant pool is placed too far from an LDR instruction accessing it: - Compiling to Thumb2. - There is no unconditional branch within 4k of the LDR instruction. - At least one of: * The LDR instruction is not at a 4-byte aligned address. * There is an instruction boundary 4094 bytes from the value of PC at the LDR. The problem here is twofold: 1. The base address of a PC-relative LDR in Thumb2 is the address of the instruction plus 4, rounded down to a multiple of 4. The calculation for the valid range fails to take this rounding into account. 2. The constant pool is (rightly) 4-byte aligned. When scanning the instructions for a suitable location, the possible need for padding is not considered. The problem can be seen by compiling the attached preprocessed source using flags "-mthumb -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard -O0 -fPIC".
Created attachment 28484 [details] Hack patch This hack patch validates the analysis. A proper fix probably looks different.
works with 4.7, fails with trunk
Also works with gcc-4.6.
The test case started failing with r189790: http://gcc.gnu.org/ml/gcc-cvs/2012-07/msg00695.html That patch merely enabled insn splitting at -O0, so I suspect it exposed a latent problem in the back-end, consistent with Måns' analysis.
this patch is now on the 4.7 branch too.
http://gcc.gnu.org/ml/gcc-patches/2012-11/msg01825.html Patch posted here.
Author: mgretton Date: Thu Nov 29 10:02:16 2012 New Revision: 193930 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=193930 Log: PR target/54974 * config/arm/arm.md (thumb2_pool_range, pool_range): Add comment on Thumb pool ranges. (thumb1_extendhisi2): Reduce Thumb pool range. (arm_movdi): Likewise. (thumb1_movdi_insn): Likewise. (thumb1_movsi_insn): Likewise. (pic_load_addr_unified): Likewise. (pic_load_addr_32bit): Likewise. (pic_load_addr_thumb1): Likewise. (thumb1_movhf): Likewise. (arm_movsf_soft_insn): Likewise. (thumb1_movsf_soft_insn): Likewise. (movdf_soft_insn): Likewise. (thumb1_movdf_soft_insn): Likewise. * config/arm/neon.md (*neon_mov<mode>): Likewise. (*neon_mov<mode>): Likwise. * config/arm/thumb2.md: (*thumb2_movsi_insn): Likewise. (*thumb2_movhi_insn): Likewise. (*thumb2_extendqisi_v6): Likewise. (*thumb2_zero_extendqisi_v6): Likewise. (*thumb2_zero_extendqisi2_v6): Likewise. * config/arm/vfp.md: (*thumb2_movsi_vfp): Likewise. (*movdi_vfp): Likewise. (*movdi_vfp_cortexa8): Likewise. (*thumb2_movsf_vfp): Likewise. (*thumb2_movdf_vfp): Likewise. Modified: trunk/gcc/ChangeLog trunk/gcc/config/arm/arm.md trunk/gcc/config/arm/neon.md trunk/gcc/config/arm/thumb2.md trunk/gcc/config/arm/vfp.md
Fixed on the trunk I suppose.
Matt, Are you planning on backporting this to 4.7 ? regards Ramana
GCC 4.7.3 is being released, adjusting target milestone.
Fixed for 4.8.0.