From 4229b304b98dff0190922ddd5270a1389321313b Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sun, 19 Jun 2016 12:47:45 -0700
Subject: [PATCH] Convert V1TImode register to TImode in debug insn
TImode register referenced in debug insn can be converted to V1TImode
by scalar to vector optimization. We need to convert a debug insn if
it references TImode register which will be converted to V1TImode.
gcc/
PR target/71549
* config/i386/i386.c (scalar_chain::analyze_register_chain): In
64-bit mode, add debug insn, which references the register, to
queue.
(timode_scalar_chain::convert_insn): Convert V1TImode register
to SUBREG TImode in debug insn.
gcc/testsuite/
PR target/71549
* gcc.target/i386/pr71549.c: New test.
---
gcc/config/i386/i386.c | 32 +++++++++++++++++++++++++++++++-
gcc/testsuite/gcc.target/i386/pr71549.c | 24 ++++++++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr71549.c
@@ -3229,8 +3229,22 @@ scalar_chain::analyze_register_chain (bitmap candidates, df_ref ref)
for (chain = DF_REF_CHAIN (ref); chain; chain = chain->next)
{
unsigned uid = DF_REF_INSN_UID (chain->ref);
+ rtx_insn *insn = DF_REF_INSN (chain->ref);
- if (!NONDEBUG_INSN_P (DF_REF_INSN (chain->ref)))
+ if (TARGET_64BIT && DEBUG_INSN_P (insn))
+ {
+ /* In 64-bit mode, if a variable is put in a TImode register,
+ which may be converted to V1TImode, we need to convert
+ this debug insn. */
+ rtx val = PATTERN (insn);
+ if (!(GET_MODE (val) == TImode
+ && GET_CODE (val) == VAR_LOCATION
+ && REG_P (PAT_VAR_LOCATION_LOC (val))))
+ gcc_unreachable ();
+ add_to_queue (uid);
+ continue;
+ }
+ else if (!NONDEBUG_INSN_P (insn))
continue;
if (!DF_REF_REG_MEM_P (chain->ref))
@@ -3795,6 +3809,22 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
void
timode_scalar_chain::convert_insn (rtx_insn *insn)
{
+ if (DEBUG_INSN_P (insn))
+ {
+ /* It must be a debug insn with a TImode variable in register. */
+ rtx val = PATTERN (insn);
+ gcc_assert (GET_MODE (val) == TImode
+ && GET_CODE (val) == VAR_LOCATION);
+ rtx loc = PAT_VAR_LOCATION_LOC (val);
+ gcc_assert (REG_P (loc)
+ && GET_MODE (loc) == V1TImode);
+ /* Convert V1TImode register, which has been updated by a SET
+ insn before, to SUBREG TImode. */
+ PAT_VAR_LOCATION_LOC (val) = gen_rtx_SUBREG (TImode, loc, 0);
+ df_insn_rescan (insn);
+ return;
+ }
+
rtx def_set = single_set (insn);
rtx src = SET_SRC (def_set);
rtx dst = SET_DEST (def_set);
new file mode 100644
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+struct S1
+{
+ int f0;
+ int f1;
+ int f2;
+ int:4;
+} a, b;
+
+void
+fn1 (struct S1 p1)
+{
+ a = p1;
+ int c = p1.f0;
+}
+
+int
+main ()
+{
+ fn1 (b);
+ return 0;
+}
--
2.5.5