X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fsimplify-rtx.c;h=e3e29991af8f9b11d396da6139a7593f1ce1b721;hp=d7e9da6062f2a2b60380fa10ce2560ae5dfc22b8;hb=44312acb2e89644c4d60ae6e700d2018f4c478ae;hpb=1a16849bba6b77dafea0f3fbce53a10f48435178 diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index d7e9da6062f..e3e29991af8 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -16,8 +16,8 @@ for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #include "config.h" @@ -145,6 +145,7 @@ avoid_constant_pool_reference (rtx x) { rtx c, tmp, addr; enum machine_mode cmode; + HOST_WIDE_INT offset = 0; switch (GET_CODE (x)) { @@ -173,26 +174,40 @@ avoid_constant_pool_reference (rtx x) /* Call target hook to avoid the effects of -fpic etc.... */ addr = targetm.delegitimize_address (addr); + /* Split the address into a base and integer offset. */ + if (GET_CODE (addr) == CONST + && GET_CODE (XEXP (addr, 0)) == PLUS + && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT) + { + offset = INTVAL (XEXP (XEXP (addr, 0), 1)); + addr = XEXP (XEXP (addr, 0), 0); + } + if (GET_CODE (addr) == LO_SUM) addr = XEXP (addr, 1); - if (GET_CODE (addr) != SYMBOL_REF - || ! CONSTANT_POOL_ADDRESS_P (addr)) - return x; - - c = get_pool_constant (addr); - cmode = get_pool_mode (addr); - - /* If we're accessing the constant in a different mode than it was - originally stored, attempt to fix that up via subreg simplifications. - If that fails we have no choice but to return the original memory. */ - if (cmode != GET_MODE (x)) + /* If this is a constant pool reference, we can turn it into its + constant and hope that simplifications happen. */ + if (GET_CODE (addr) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (addr)) { - c = simplify_subreg (GET_MODE (x), c, cmode, 0); - return c ? c : x; + c = get_pool_constant (addr); + cmode = get_pool_mode (addr); + + /* If we're accessing the constant in a different mode than it was + originally stored, attempt to fix that up via subreg simplifications. + If that fails we have no choice but to return the original memory. */ + if (offset != 0 || cmode != GET_MODE (x)) + { + rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset); + if (tem && CONSTANT_P (tem)) + return tem; + } + else + return c; } - return c; + return x; } /* Make a unary operation by first seeing if it folds and otherwise making @@ -3221,7 +3236,9 @@ simplify_const_relational_operation (enum rtx_code code, case LT: /* Optimize abs(x) < 0.0. */ - if (trueop1 == CONST0_RTX (mode) && !HONOR_SNANS (mode)) + if (trueop1 == CONST0_RTX (mode) + && !HONOR_SNANS (mode) + && !(flag_wrapv && INTEGRAL_MODE_P (mode))) { tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0) : trueop0; @@ -3232,7 +3249,9 @@ simplify_const_relational_operation (enum rtx_code code, case GE: /* Optimize abs(x) >= 0.0. */ - if (trueop1 == CONST0_RTX (mode) && !HONOR_NANS (mode)) + if (trueop1 == CONST0_RTX (mode) + && !HONOR_NANS (mode) + && !(flag_wrapv && INTEGRAL_MODE_P (mode))) { tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0) : trueop0;