From 0bb7645daa5ad298b195f8a79410620cdd99eacc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 29 Oct 2015 11:36:39 -0700 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 +++++++ gcc/config/i386/i386.c | 36 +++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1f32c9dfa59..fa3e95651de 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-10-29 Richard Henderson + + 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 * config/rs6000/rs6000.c (rs6000_init_libfuncs): Split libfunc diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 82fd05412ac..8476677f1c1 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; } -- 2.30.2