diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2016-06-19 12:47:45 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2016-06-20 16:49:43 -0700 |
commit | 13dd60ab323090f75f7d014d271aea71f4e5c26d (patch) | |
tree | a5c9f388c28d227d8c03a735aa30e9a09c192027 /gcc/config/i386/i386.c | |
parent | 0b4b12fd4a13c8d5292151f1e832cc71e28fa39d (diff) | |
download | gcc-13dd60ab323090f75f7d014d271aea71f4e5c26d.tar.gz |
Convert V1TImode register to TImode in debug insnhjl/pr71549
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 (timode_scalar_chain::fix_debug_reg_uses):
New member function to convert V1TImode register to SUBREG
TImode in debug insn.
(timode_scalar_chain::convert_insn): Call fix_debug_reg_uses
after changing register mode to V1TImode.
gcc/testsuite/
PR target/71549
* gcc.target/i386/pr71549.c: New test.
Diffstat (limited to 'gcc/config/i386/i386.c')
-rw-r--r-- | gcc/config/i386/i386.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 56a5b9c3296..0dd09ce23a9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -3139,6 +3139,7 @@ class timode_scalar_chain : public scalar_chain private: void mark_dual_mode_def (df_ref def); + void fix_debug_reg_uses (rtx reg); void convert_insn (rtx_insn *insn); /* We don't convert registers to difference size. */ void convert_registers () {} @@ -3790,6 +3791,39 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn) df_insn_rescan (insn); } +/* Fix uses of converted REG in debug insns. */ + +void +timode_scalar_chain::fix_debug_reg_uses (rtx reg) +{ + if (!flag_var_tracking) + return; + + df_ref ref; + for (ref = DF_REG_USE_CHAIN (REGNO (reg)); + ref; + ref = DF_REF_NEXT_REG (ref)) + { + rtx_insn *insn = DF_REF_INSN (ref); + if (DEBUG_INSN_P (insn)) + { + /* It may be a debug insn with a TImode variable in + register. */ + rtx val = PATTERN (insn); + if (GET_MODE (val) != TImode) + continue; + gcc_assert (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); + } + } +} + /* Convert INSN from TImode to V1T1mode. */ void @@ -3806,8 +3840,10 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) rtx tmp = find_reg_equal_equiv_note (insn); if (tmp) PUT_MODE (XEXP (tmp, 0), V1TImode); + PUT_MODE (dst, V1TImode); + fix_debug_reg_uses (dst); } - /* FALLTHRU */ + break; case MEM: PUT_MODE (dst, V1TImode); break; |