aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2019-05-03 13:45:59 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2019-05-03 13:45:59 +0000
commit38fa938bbf94dcd06696dfd890d386f004e34604 (patch)
treedcc087f4b6383e7cf3b4e84f30d081c157821c08 /gcc
parent051ef623d6e332a6199bbf4e6c66e53925cac825 (diff)
downloadgcc-38fa938bbf94dcd06696dfd890d386f004e34604.zip
gcc-38fa938bbf94dcd06696dfd890d386f004e34604.tar.gz
gcc-38fa938bbf94dcd06696dfd890d386f004e34604.tar.bz2
[arm] PR target/89400 fix thumb1 unaligned access expansion
Armv6 has support for unaligned accesses to memory. However, the thumb1 code patterns were trying to use the 32-bit code constraints. One failure mode from this was that the patterns are designed to be compatible with conditional execution and this was then causing an assert in the compiler. The unaligned_loadhis pattern is only used for expanding extv, which in turn is only enabled for systems supporting thumb2. Given that there is no simple expansion for a thumb1 sign-extending load (the instruction has no immediate offset form and requires two registers in the address) it seems simpler to just disable this for thumb1. Fixed thusly: PR target/89400 * config/arm/arm.md (unaligned_loadsi): Add variant for thumb1. Restrict 'all' variant to 32-bit configurations. (unaligned_loadhiu): Likewise. (unaligned_storehi): Likewise. (unaligned_storesi): Likewise. (unaligned_loadhis): Disable when compiling for thumb1. From-SVN: r270853
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/arm/arm.md74
2 files changed, 55 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a1f2356..7ab0457 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2019-05-03 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/89400
+ * config/arm/arm.md (unaligned_loadsi): Add variant for thumb1.
+ Restrict 'all' variant to 32-bit configurations.
+ (unaligned_loadhiu): Likewise.
+ (unaligned_storehi): Likewise.
+ (unaligned_storesi): Likewise.
+ (unaligned_loadhis): Disable when compiling for thumb1.
+
2019-05-03 Marc Glisse <marc.glisse@inria.fr>
PR tree-optimization/90269
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 0aecd03..ae58217 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -4483,62 +4483,78 @@
; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
(define_insn "unaligned_loadsi"
- [(set (match_operand:SI 0 "s_register_operand" "=l,r")
- (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
+ [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
+ (unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")]
UNSPEC_UNALIGNED_LOAD))]
"unaligned_access"
- "ldr%?\t%0, %1\t@ unaligned"
- [(set_attr "arch" "t2,any")
- (set_attr "length" "2,4")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "yes,no")
+ "@
+ ldr\t%0, %1\t@ unaligned
+ ldr%?\t%0, %1\t@ unaligned
+ ldr%?\t%0, %1\t@ unaligned"
+ [(set_attr "arch" "t1,t2,32")
+ (set_attr "length" "2,2,4")
+ (set_attr "predicable" "no,yes,yes")
+ (set_attr "predicable_short_it" "no,yes,no")
(set_attr "type" "load_4")])
+;; The 16-bit Thumb1 variant of ldrsh requires two registers in the
+;; address (there's no immediate format). That's tricky to support
+;; here and we don't really need this pattern for that case, so only
+;; enable for 32-bit ISAs.
(define_insn "unaligned_loadhis"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(sign_extend:SI
(unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
UNSPEC_UNALIGNED_LOAD)))]
- "unaligned_access"
+ "unaligned_access && TARGET_32BIT"
"ldrsh%?\t%0, %1\t@ unaligned"
[(set_attr "predicable" "yes")
(set_attr "type" "load_byte")])
(define_insn "unaligned_loadhiu"
- [(set (match_operand:SI 0 "s_register_operand" "=l,r")
+ [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
(zero_extend:SI
- (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
+ (unspec:HI [(match_operand:HI 1 "memory_operand" "m,Uw,m")]
UNSPEC_UNALIGNED_LOAD)))]
"unaligned_access"
- "ldrh%?\t%0, %1\t@ unaligned"
- [(set_attr "arch" "t2,any")
- (set_attr "length" "2,4")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "yes,no")
+ "@
+ ldrh\t%0, %1\t@ unaligned
+ ldrh%?\t%0, %1\t@ unaligned
+ ldrh%?\t%0, %1\t@ unaligned"
+ [(set_attr "arch" "t1,t2,32")
+ (set_attr "length" "2,2,4")
+ (set_attr "predicable" "no,yes,yes")
+ (set_attr "predicable_short_it" "no,yes,no")
(set_attr "type" "load_byte")])
(define_insn "unaligned_storesi"
- [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
- (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
+ [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m")
+ (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")]
UNSPEC_UNALIGNED_STORE))]
"unaligned_access"
- "str%?\t%1, %0\t@ unaligned"
- [(set_attr "arch" "t2,any")
- (set_attr "length" "2,4")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "yes,no")
+ "@
+ str\t%1, %0\t@ unaligned
+ str%?\t%1, %0\t@ unaligned
+ str%?\t%1, %0\t@ unaligned"
+ [(set_attr "arch" "t1,t2,32")
+ (set_attr "length" "2,2,4")
+ (set_attr "predicable" "no,yes,yes")
+ (set_attr "predicable_short_it" "no,yes,no")
(set_attr "type" "store_4")])
(define_insn "unaligned_storehi"
- [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
- (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
+ [(set (match_operand:HI 0 "memory_operand" "=m,Uw,m")
+ (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,l,r")]
UNSPEC_UNALIGNED_STORE))]
"unaligned_access"
- "strh%?\t%1, %0\t@ unaligned"
- [(set_attr "arch" "t2,any")
- (set_attr "length" "2,4")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "yes,no")
+ "@
+ strh\t%1, %0\t@ unaligned
+ strh%?\t%1, %0\t@ unaligned
+ strh%?\t%1, %0\t@ unaligned"
+ [(set_attr "arch" "t1,t2,32")
+ (set_attr "length" "2,2,4")
+ (set_attr "predicable" "no,yes,yes")
+ (set_attr "predicable_short_it" "no,yes,no")
(set_attr "type" "store_4")])