For some reason, when I "invented" gen_lowpart_no_emit I defaulted it to returning the original value of X. Since gen_lowpart_no_emit is mostly used to return simplifications, the correct thing to return when conversion fails is NULL. As a follow-up, every use in simplify-rtx.c could be changed to try other simplifications if gen_lowpart_no_emit fails; for now, I'm just avoiding a NULL pointer dereference.
2011-07-25 Paolo Bonzini <bonz...@gnu.org> * rtlhooks.c (gen_lowpart_no_emit_general): Remove. * rtlhooks-def.h (gen_lowpart_no_emit_general): Remove prototype. (RTL_HOOKS_GEN_LOWPART_NO_EMIT): Default to gen_lowpart_if_possible. Index: rtlhooks.c =================================================================== --- rtlhooks.c (revision 169877) +++ rtlhooks.c (working copy) @@ -80,18 +80,6 @@ gen_lowpart_general (enum machine_mode m } } -/* Similar to gen_lowpart, but cannot emit any instruction via - copy_to_reg or force_reg. Mainly used in simplify-rtx.c. */ -rtx -gen_lowpart_no_emit_general (enum machine_mode mode, rtx x) -{ - rtx result = gen_lowpart_if_possible (mode, x); - if (result) - return result; - else - return x; -} - rtx reg_num_sign_bit_copies_general (const_rtx x ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, Index: rtlhooks-def.h =================================================================== --- rtlhooks-def.h (revision 169877) +++ rtlhooks-def.h (working copy) @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. #include "rtl.h" #define RTL_HOOKS_GEN_LOWPART gen_lowpart_general -#define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_no_emit_general +#define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_if_possible #define RTL_HOOKS_REG_NONZERO_REG_BITS reg_nonzero_bits_general #define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES reg_num_sign_bit_copies_general #define RTL_HOOKS_REG_TRUNCATED_TO_MODE reg_truncated_to_mode_general @@ -38,7 +38,6 @@ along with GCC; see the file COPYING3. } extern rtx gen_lowpart_general (enum machine_mode, rtx); -extern rtx gen_lowpart_no_emit_general (enum machine_mode, rtx); extern rtx reg_nonzero_bits_general (const_rtx, enum machine_mode, const_rtx, enum machine_mode, unsigned HOST_WIDE_INT, Index: simplify-rtx.c =================================================================== --- simplify-rtx.c (revision 169877) +++ simplify-rtx.c (working copy) @@ -1039,6 +1039,8 @@ simplify_unary_operation_1 (enum rtx_cod { rtx inner = rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0)); + if (!inner) + return NULL_RTX; return simplify_gen_unary (GET_CODE (op) == ASHIFTRT ? SIGN_EXTEND : ZERO_EXTEND, mode, inner, tmode); @@ -1092,6 +1094,8 @@ simplify_unary_operation_1 (enum rtx_cod { rtx inner = rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0)); + if (!inner) + return NULL_RTX; return simplify_gen_unary (ZERO_EXTEND, mode, inner, tmode); } } @@ -2768,6 +2772,8 @@ simplify_binary_operation_1 (enum rtx_co if (trueop1 == constm1_rtx) { rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0); + if (!x) + return NULL_RTX; return simplify_gen_unary (NEG, mode, x, mode); } }