From ca035367a79fd44f052ad0497c16abd38a720163 Mon Sep 17 00:00:00 2001 From: Joern Rennecke Date: Thu, 30 May 2013 11:07:05 +0000 Subject: 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 --- gcc/postreload.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'gcc/postreload.c') 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; -- cgit v1.1