diff options
author | Joern Rennecke <joern.rennecke@embecosm.com> | 2013-05-30 11:07:05 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 2013-05-30 12:07:05 +0100 |
commit | ca035367a79fd44f052ad0497c16abd38a720163 (patch) | |
tree | e04afbe88c9a495644dda56fb1c9e33e6253b249 /gcc/postreload.c | |
parent | 582f2176b5abe7512e514d31c1770def11cb8e38 (diff) | |
download | gcc-ca035367a79fd44f052ad0497c16abd38a720163.zip gcc-ca035367a79fd44f052ad0497c16abd38a720163.tar.gz gcc-ca035367a79fd44f052ad0497c16abd38a720163.tar.bz2 |
re PR rtl-optimization/57439 (FAIL: gcc.c-torture/execute/920501-6.c execution, -O1)
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.
From-SVN: r199449
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 558ab8b..f340503 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; |