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/postreload.c | |
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/postreload.c')
-rw-r--r-- | gcc/postreload.c | 21 |
1 files changed, 19 insertions, 2 deletions
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; |