aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/arm/arm.c4
-rw-r--r--gcc/config/arm/neon.md35
3 files changed, 21 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 85bf69c..aaed5d5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2018-08-16 Tamar Christina <tamar.christina@arm.com>
+ PR target/84711
+ * config/arm/arm.c (arm_can_change_mode_class): Disallow subreg.
+ * config/arm/neon.md (movv4hf, movv8hf): Refactored to..
+ (mov<mov>): ..this and enable unconditionally.
+
+2018-08-16 Tamar Christina <tamar.christina@arm.com>
+
* config/arm/neon.md (*neon_mov<mode>): Remove reg-to-reg alternative.
2018-08-16 Sam Tebbs <sam.tebbs@arm.com>
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index f5eece4..1d97db5 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -31509,8 +31509,8 @@ arm_can_change_mode_class (machine_mode from, machine_mode to,
{
if (TARGET_BIG_END
&& !(GET_MODE_SIZE (from) == 16 && GET_MODE_SIZE (to) == 8)
- && (GET_MODE_UNIT_SIZE (from) > UNITS_PER_WORD
- || GET_MODE_UNIT_SIZE (to) > UNITS_PER_WORD)
+ && (GET_MODE_SIZE (from) > UNITS_PER_WORD
+ || GET_MODE_SIZE (to) > UNITS_PER_WORD)
&& reg_classes_intersect_p (VFP_REGS, rclass))
return false;
return true;
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 97d88e6..5aeee4b 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -113,6 +113,13 @@
(set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*")
(set_attr "neg_pool_range" "*,*,*,996,*,*,*,996,*")])
+/* We define these mov expanders to match the standard mov$a optab to prevent
+ the mid-end from trying to do a subreg for these modes which is the most
+ inefficient way to expand the move. Also big-endian subreg's aren't
+ allowed for a subset of modes, See TARGET_CAN_CHANGE_MODE_CLASS.
+ Without these RTL generation patterns the mid-end would attempt to take a
+ sub-reg and may ICE if it can't. */
+
(define_expand "movti"
[(set (match_operand:TI 0 "nonimmediate_operand" "")
(match_operand:TI 1 "general_operand" ""))]
@@ -137,33 +144,15 @@
}
})
-(define_expand "movv4hf"
- [(set (match_operand:V4HF 0 "s_register_operand")
- (match_operand:V4HF 1 "s_register_operand"))]
- "TARGET_NEON && TARGET_FP16"
+(define_expand "mov<mode>"
+ [(set (match_operand:VH 0 "s_register_operand")
+ (match_operand:VH 1 "s_register_operand"))]
+ "TARGET_NEON"
{
- /* We need to use force_reg to avoid TARGET_CAN_CHANGE_MODE_CLASS
- causing an ICE on big-endian because it cannot extract subregs in
- this case. */
- if (can_create_pseudo_p ())
- {
- if (!REG_P (operands[0]))
- operands[1] = force_reg (V4HFmode, operands[1]);
- }
-})
-
-(define_expand "movv8hf"
- [(set (match_operand:V8HF 0 "")
- (match_operand:V8HF 1 ""))]
- "TARGET_NEON && TARGET_FP16"
-{
- /* We need to use force_reg to avoid TARGET_CAN_CHANGE_MODE_CLASS
- causing an ICE on big-endian because it cannot extract subregs in
- this case. */
if (can_create_pseudo_p ())
{
if (!REG_P (operands[0]))
- operands[1] = force_reg (V8HFmode, operands[1]);
+ operands[1] = force_reg (<MODE>mode, operands[1]);
}
})