diff options
author | Than McIntosh <thanm@google.com> | 2015-10-09 12:03:57 -0400 |
---|---|---|
committer | Than McIntosh <thanm@google.com> | 2015-10-09 12:12:46 -0400 |
commit | 5aff2e0142aca13849b4e51de503e71d5010efa6 (patch) | |
tree | 4ddf3573d2b94a78d31f54a660ccaac10203b601 /gcc-4.9 | |
parent | 08a14db5158fa3c3dd5b7a2828dec06b54b4e916 (diff) | |
download | toolchain_gcc-5aff2e0142aca13849b4e51de503e71d5010efa6.tar.gz toolchain_gcc-5aff2e0142aca13849b4e51de503e71d5010efa6.tar.bz2 toolchain_gcc-5aff2e0142aca13849b4e51de503e71d5010efa6.zip |
Fix for b/23822150 (arm64 bad code for copysignl)
This bug was inherited from the google/gcc-4_9 branch; a
change was "temporarily" patched out in r216495, then never
restored.
Bug: 23822150
Change-Id: Ibfc9f65e108e9c9b3dca263920bdae3cc6f75080
Diffstat (limited to 'gcc-4.9')
-rw-r--r-- | gcc-4.9/gcc/expmed.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/gcc-4.9/gcc/expmed.c b/gcc-4.9/gcc/expmed.c index 0124a213b..ad39034dd 100644 --- a/gcc-4.9/gcc/expmed.c +++ b/gcc-4.9/gcc/expmed.c @@ -113,7 +113,7 @@ init_expmed_one_conv (struct init_expmed_rtl *all, enum machine_mode to_mode, - (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)); from_size = (GET_MODE_BITSIZE (from_mode) - (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)); - + /* Assume cost of zero-extend and sign-extend is the same. */ which = (to_size < from_size ? &all->trunc : &all->zext); @@ -679,13 +679,28 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, || (bitsize % BITS_PER_WORD == 0 && bitnum % BITS_PER_WORD == 0))) { /* Use the subreg machinery either to narrow OP0 to the required - words or to cope with mode punning between equal-sized modes. */ - rtx sub = simplify_gen_subreg (fieldmode, op0, GET_MODE (op0), - bitnum / BITS_PER_UNIT); - if (sub) + words or to cope with mode punning between equal-sized modes. + In the latter case, use subreg on the rhs side, not lhs. */ + rtx sub; + + if (bitsize == GET_MODE_BITSIZE (GET_MODE (op0))) { - emit_move_insn (sub, value); - return true; + sub = simplify_gen_subreg (GET_MODE (op0), value, fieldmode, 0); + if (sub) + { + emit_move_insn (op0, sub); + return true; + } + } + else + { + sub = simplify_gen_subreg (fieldmode, op0, GET_MODE (op0), + bitnum / BITS_PER_UNIT); + if (sub) + { + emit_move_insn (sub, value); + return true; + } } } @@ -1755,7 +1770,7 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, return convert_extracted_bit_field (result, mode, tmode, unsignedp); } - + return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, target, mode, tmode, true); } @@ -1899,7 +1914,7 @@ lshift_value (enum machine_mode mode, unsigned HOST_WIDE_INT value, int bitpos) { double_int val; - + val = double_int::from_uhwi (value); val = val.llshift (bitpos, HOST_BITS_PER_DOUBLE_INT); @@ -3372,7 +3387,7 @@ choose_multiplier (unsigned HOST_WIDE_INT d, int n, int precision, /* mlow = 2^(N + lgup)/d */ double_int val = double_int_zero.set_bit (pow); - mlow = val.div (double_int::from_uhwi (d), true, TRUNC_DIV_EXPR); + mlow = val.div (double_int::from_uhwi (d), true, TRUNC_DIV_EXPR); /* mhigh = (2^(N + lgup) + 2^(N + lgup - precision))/d */ val |= double_int_zero.set_bit (pow2); @@ -4033,7 +4048,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, /* Only deduct something for a REM if the last divide done was for a different constant. Then set the constant of the last divide. */ - max_cost = (unsignedp + max_cost = (unsignedp ? udiv_cost (speed, compute_mode) : sdiv_cost (speed, compute_mode)); if (rem_flag && ! (last_div_const != 0 && op1_is_constant |