[arm] PR target/85026: Fix ldrsh length estimate in Thumb state
commit5d79b75ef3a7b4516146fd417de7482369f62369
authorktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Mar 2018 16:43:43 +0000 (23 16:43 +0000)
committerktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Mar 2018 16:43:43 +0000 (23 16:43 +0000)
treea60f13219c7d8bb048d9338aa4dbb01fb98eb1e3
parent61cdc200306c523c653206824bba367af096c8a6
[arm] PR target/85026: Fix ldrsh length estimate in Thumb state

This bug has been reported against GCC 7.3.0 but it is latent in all release branches and on trunk.
We underestimate the length of the LRSH instruction in Thumb state.
Unlike other load instructions LDRSH can be encoded in 16 bits only when using a register offset.
In the testcase we have "ldrsh   r2, [r4]" being assigned a length of 2, which is wrong.
So we don't calculate branch ranges properly and cause the assembler error.

The fix is to make the unaligned_loadhis insn similar to the *arm_extendqihi_insn insn that outputs an LDRSB.
Just remove the wrong 2-byte alternative. I don't think this is worth inventing a new "register-offset-only" constraint.
This also makes the patch safer for backporting.

Bootstrapped and tested on arm-none-linux-gnueabihf.

PR target/85026
* config/arm/arm.md (unaligned_loadhis): Remove first alternative.
Clean up attributes.

* g++.dg/pr85026.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@258818 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/ChangeLog
gcc/config/arm/arm.md
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/pr85026.C [new file with mode: 0644]