aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-08-15 12:44:23 +0000
committerRichard Biener <rguenther@suse.de>2019-08-15 12:44:23 +0000
commit615b1b6e36865791b97d25399198a143712800d4 (patch)
tree93c0fdf0d4b56377da4ad28cda0ad15a62c51c9e
parent3c61a7fd00831ab131f17b7cddcf3b7181ea4aec (diff)
2019-08-15 Richard Biener <rguenther@suse.de>
PR target/91454 * config/i386/i386-features.c (gen_gpr_to_xmm_move_src): New helper. (general_scalar_chain::make_vector_copies): Use it. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@274535 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/i386-features.c37
2 files changed, 30 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2aa7a8cba19..458caa5a89e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2019-08-15 Richard Biener <rguenther@suse.de>
+
+ PR target/91454
+ * config/i386/i386-features.c (gen_gpr_to_xmm_move_src): New
+ helper.
+ (general_scalar_chain::make_vector_copies): Use it.
+
2019-08-15 Bernd Edlinger <bernd.edlinger@hotmail.de>
* function.c (assign_parm_setup_reg): Handle misaligned stack arguments.
diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c
index f622ac79ab9..cead2077e48 100644
--- a/gcc/config/i386/i386-features.c
+++ b/gcc/config/i386/i386-features.c
@@ -658,6 +658,25 @@ scalar_chain::emit_conversion_insns (rtx insns, rtx_insn *after)
emit_insn_after (insns, BB_HEAD (new_bb));
}
+/* Generate the canonical SET_SRC to move GPR to a VMODE vector register,
+ zeroing the upper parts. */
+
+static rtx
+gen_gpr_to_xmm_move_src (enum machine_mode vmode, rtx gpr)
+{
+ switch (GET_MODE_NUNITS (vmode))
+ {
+ case 1:
+ return gen_rtx_SUBREG (vmode, gpr, 0);
+ case 2:
+ return gen_rtx_VEC_CONCAT (vmode, gpr,
+ CONST0_RTX (GET_MODE_INNER (vmode)));
+ default:
+ return gen_rtx_VEC_MERGE (vmode, gen_rtx_VEC_DUPLICATE (vmode, gpr),
+ CONST0_RTX (vmode), GEN_INT (HOST_WIDE_INT_1U));
+ }
+}
+
/* Make vector copies for all register REGNO definitions
and replace its uses in a chain. */
@@ -684,13 +703,8 @@ general_scalar_chain::make_vector_copies (unsigned regno)
}
else
emit_move_insn (tmp, reg);
- emit_insn (gen_rtx_SET
- (gen_rtx_SUBREG (vmode, vreg, 0),
- gen_rtx_VEC_MERGE (vmode,
- gen_rtx_VEC_DUPLICATE (vmode,
- tmp),
- CONST0_RTX (vmode),
- GEN_INT (HOST_WIDE_INT_1U))));
+ emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
+ gen_gpr_to_xmm_move_src (vmode, tmp)));
}
else if (!TARGET_64BIT && smode == DImode)
{
@@ -720,13 +734,8 @@ general_scalar_chain::make_vector_copies (unsigned regno)
}
}
else
- emit_insn (gen_rtx_SET
- (gen_rtx_SUBREG (vmode, vreg, 0),
- gen_rtx_VEC_MERGE (vmode,
- gen_rtx_VEC_DUPLICATE (vmode,
- reg),
- CONST0_RTX (vmode),
- GEN_INT (HOST_WIDE_INT_1U))));
+ emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
+ gen_gpr_to_xmm_move_src (vmode, reg)));
rtx_insn *seq = get_insns ();
end_sequence ();
rtx_insn *insn = DF_REF_INSN (ref);