diff options
author | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-05-30 11:07:05 +0000 |
---|---|---|
committer | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-05-30 11:07:05 +0000 |
commit | 5bea3269f082640f7314ed8db23137a982d97177 (patch) | |
tree | e04afbe88c9a495644dda56fb1c9e33e6253b249 /gcc | |
parent | 72cf5e1121bea5f6f52ce30fe20a885562128f61 (diff) | |
download | gcc-5bea3269f082640f7314ed8db23137a982d97177.tar.gz |
PR rtl-optimization/57439
* postreload.c (move2add_valid_value_p): Check that we have
a zero subreg_regno_offset when accessing the register in
the requested mode.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199449 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/postreload.c | 21 |
2 files changed, 26 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8b27ecc44c7..f08cd613cfc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-05-30 Joern Rennecke <joern.rennecke@embecosm.com> + + PR rtl-optimization/57439 + * postreload.c (move2add_valid_value_p): Check that we have + a zero subreg_regno_offset when accessing the register in + the requested mode. + 2013-05-30 Yuri Rumyantsev <yuri.s.rumyantsev@intel.com> Igor Zamyatin <igor.zamyatin@intel.com> diff --git a/gcc/postreload.c b/gcc/postreload.c index 558ab8b867e..f340503f69c 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -1726,10 +1726,27 @@ move2add_record_sym_value (rtx reg, rtx sym, rtx off) static bool move2add_valid_value_p (int regno, enum machine_mode mode) { - if (reg_set_luid[regno] <= move2add_last_label_luid - || !MODES_OK_FOR_MOVE2ADD (mode, reg_mode[regno])) + if (reg_set_luid[regno] <= move2add_last_label_luid) return false; + if (mode != reg_mode[regno]) + { + if (!MODES_OK_FOR_MOVE2ADD (mode, reg_mode[regno])) + return false; + /* The value loaded into regno in reg_mode[regno] is also valid in + mode after truncation only if (REG:mode regno) is the lowpart of + (REG:reg_mode[regno] regno). Now, for big endian, the starting + regno of the lowpart might be different. */ + int s_off = subreg_lowpart_offset (mode, reg_mode[regno]); + s_off = subreg_regno_offset (regno, reg_mode[regno], s_off, mode); + if (s_off != 0) + /* We could in principle adjust regno, check reg_mode[regno] to be + BLKmode, and return s_off to the caller (vs. -1 for failure), + but we currently have no callers that could make use of this + information. */ + return false; + } + for (int i = hard_regno_nregs[regno][mode] - 1; i > 0; i--) if (reg_mode[regno + i] != BLKmode) return false; |