aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/aarch64
diff options
context:
space:
mode:
authorJames Greenhalgh <james.greenhalgh@arm.com>2015-12-09 13:47:19 +0000
committerJames Greenhalgh <james.greenhalgh@arm.com>2015-12-09 13:47:19 +0000
commite8e929f593411ae6e9be5d1cfd70506a20968e14 (patch)
tree9d5c6037c38f9e1aad1f3b3a94c7657a04e32f77 /gcc/config/aarch64
parentdd512280cfb75a1b1d33b5759f26a96755c1862d (diff)
[Patch AArch64] Reinstate CANNOT_CHANGE_MODE_CLASS to fix pr67609
gcc/ PR rtl-optimization/67609 * config/aarch64/aarch64-protos.h (aarch64_cannot_change_mode_class): Bring back. * config/aarch64/aarch64.c (aarch64_cannot_change_mode_class): Likewise. * config/aarch64/aarch64.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/aarch64/aarch64.md (aarch64_movdi_<mode>low): Use zero_extract rather than truncate. (aarch64_movdi_<mode>high): Likewise. gcc/testsuite/ PR rtl-optimization/67609 * gcc.dg/torture/pr67609.c: New. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@231455 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/aarch64')
-rw-r--r--gcc/config/aarch64/aarch64-protos.h3
-rw-r--r--gcc/config/aarch64/aarch64.c18
-rw-r--r--gcc/config/aarch64/aarch64.h3
-rw-r--r--gcc/config/aarch64/aarch64.md8
4 files changed, 28 insertions, 4 deletions
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 1e0fb4e97e8..549a89d1f69 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -269,6 +269,9 @@ int aarch64_get_condition_code (rtx);
bool aarch64_bitmask_imm (HOST_WIDE_INT val, machine_mode);
int aarch64_branch_cost (bool, bool);
enum aarch64_symbol_type aarch64_classify_symbolic_expression (rtx);
+bool aarch64_cannot_change_mode_class (machine_mode,
+ machine_mode,
+ enum reg_class);
bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT);
bool aarch64_constant_address_p (rtx);
bool aarch64_expand_movmem (rtx *);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index ae4cfb336a8..1e1b864d865 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -12712,6 +12712,24 @@ aarch64_vectorize_vec_perm_const_ok (machine_mode vmode,
return ret;
}
+/* Implement target hook CANNOT_CHANGE_MODE_CLASS. */
+bool
+aarch64_cannot_change_mode_class (machine_mode from,
+ machine_mode to,
+ enum reg_class rclass)
+{
+ /* We cannot allow word_mode subregs of full vector modes.
+ Otherwise the middle-end will assume it's ok to store to
+ (subreg:DI (reg:TI 100) 0) in order to modify only the low 64 bits
+ of the 128-bit register. However, after reload the subreg will
+ be dropped leaving a plain DImode store. See PR67609 for a more
+ detailed dicussion. In all other cases, we want to be permissive
+ and return false. */
+ return (reg_classes_intersect_p (FP_REGS, rclass)
+ && GET_MODE_SIZE (to) == UNITS_PER_WORD
+ && GET_MODE_SIZE (from) > UNITS_PER_WORD);
+}
+
rtx
aarch64_reverse_mask (enum machine_mode mode)
{
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 06345f0215e..e2ead511076 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -828,6 +828,9 @@ do { \
extern void __aarch64_sync_cache_range (void *, void *); \
__aarch64_sync_cache_range (beg, end)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ aarch64_cannot_change_mode_class (FROM, TO, CLASS)
+
#define SHIFT_COUNT_TRUNCATED !TARGET_SIMD
/* Choose appropriate mode for caller saves, so we do the minimum
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index d9fe1ae4593..dd93012039d 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4681,7 +4681,8 @@
(define_insn "aarch64_movdi_<mode>low"
[(set (match_operand:DI 0 "register_operand" "=r")
- (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
+ (zero_extract:DI (match_operand:TX 1 "register_operand" "w")
+ (const_int 64) (const_int 0)))]
"TARGET_FLOAT && (reload_completed || reload_in_progress)"
"fmov\\t%x0, %d1"
[(set_attr "type" "f_mrc")
@@ -4690,9 +4691,8 @@
(define_insn "aarch64_movdi_<mode>high"
[(set (match_operand:DI 0 "register_operand" "=r")
- (truncate:DI
- (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
- (const_int 64))))]
+ (zero_extract:DI (match_operand:TX 1 "register_operand" "w")
+ (const_int 64) (const_int 64)))]
"TARGET_FLOAT && (reload_completed || reload_in_progress)"
"fmov\\t%x0, %1.d[1]"
[(set_attr "type" "f_mrc")