aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2015-10-29 11:36:39 -0700
committerRichard Henderson <rth@gcc.gnu.org>2015-10-29 11:36:39 -0700
commit0bb7645daa5ad298b195f8a79410620cdd99eacc (patch)
treeeda9bd72e08e5bc22fd13bc8ca3d641a8c7943b4
parentd8cf6ce752078133a63d5ffe49f639bad82ad8e9 (diff)
downloadgcc-0bb7645daa5ad298b195f8a79410620cdd99eacc.zip
gcc-0bb7645daa5ad298b195f8a79410620cdd99eacc.tar.gz
gcc-0bb7645daa5ad298b195f8a79410620cdd99eacc.tar.bz2
Fix target/68124
PR target/68124 PR rtl-opt/67609 * config/i386/i386.c (ix86_cannot_change_mode_class): Tighten sse check to the exact conditions of PR 67609. From-SVN: r229550
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/i386.c36
2 files changed, 28 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1f32c9d..fa3e956 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2015-10-29 Richard Henderson <rth@redhat.com>
+
+ PR target/68124
+ PR rtl-opt/67609
+ * config/i386/i386.c (ix86_cannot_change_mode_class): Tighten
+ sse check to the exact conditions of PR 67609.
+
2015-10-29 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.c (rs6000_init_libfuncs): Split libfunc
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 82fd054..8476677 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -43031,22 +43031,28 @@ ix86_cannot_change_mode_class (machine_mode from, machine_mode to,
if (MAYBE_FLOAT_CLASS_P (regclass))
return true;
- /* Vector registers do not support QI or HImode loads. If we don't
- disallow a change to these modes, reload will assume it's ok to
- drop the subreg from (subreg:SI (reg:HI 100) 0). This affects
- the vec_dupv4hi pattern.
-
- Further, 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. This is indistinguishable
- from a "normal" DImode move, and so we're justified to use movsd,
- which modifies the entire 128-bit register.
-
- Combining these two conditions, disallow all narrowing mode changes. */
if (MAYBE_SSE_CLASS_P (regclass) || MAYBE_MMX_CLASS_P (regclass))
- return GET_MODE_SIZE (to) < GET_MODE_SIZE (from);
+ {
+ int from_size = GET_MODE_SIZE (from);
+ int to_size = GET_MODE_SIZE (to);
+
+ /* Vector registers do not support QI or HImode loads. If we don't
+ disallow a change to these modes, reload will assume it's ok to
+ drop the subreg from (subreg:SI (reg:HI 100) 0). This affects
+ the vec_dupv4hi pattern. */
+ if (from_size < 4)
+ return true;
+
+ /* Further, 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. This is indistinguishable
+ from a "normal" DImode move, and so we're justified to use movsd,
+ which modifies the entire 128-bit register. */
+ if (to_size == UNITS_PER_WORD && from_size > UNITS_PER_WORD)
+ return true;
+ }
return false;
}