Summary: | [4.7 Regression] [ARM] [thumb] Incorrect placement of constant pools | ||
---|---|---|---|
Product: | gcc | Reporter: | Mans Rullgard <mans> |
Component: | target | Assignee: | mgretton |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | doko, mikpelinux, pinskia, ramana |
Priority: | P2 | Keywords: | wrong-code |
Version: | 4.8.0 | ||
Target Milestone: | 4.8.0 | ||
Host: | Target: | arm-linux-gnueabi | |
Build: | Known to work: | 4.6.3, 4.8.0 | |
Known to fail: | 4.7.4 | Last reconfirmed: | 2012-11-28 00:00:00 |
Attachments: |
Test case
Hack patch |
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. |
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".