aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2015-10-09 16:03:57 (GMT)
committerThan McIntosh <thanm@google.com>2015-10-09 16:12:46 (GMT)
commit5aff2e0142aca13849b4e51de503e71d5010efa6 (patch)
tree4ddf3573d2b94a78d31f54a660ccaac10203b601 /gcc-4.9/gcc
parent08a14db5158fa3c3dd5b7a2828dec06b54b4e916 (diff)
downloadtoolchain_gcc-5aff2e0142aca13849b4e51de503e71d5010efa6.zip
toolchain_gcc-5aff2e0142aca13849b4e51de503e71d5010efa6.tar.gz
toolchain_gcc-5aff2e0142aca13849b4e51de503e71d5010efa6.tar.bz2
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/gcc')
-rw-r--r--gcc-4.9/gcc/expmed.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/gcc-4.9/gcc/expmed.c b/gcc-4.9/gcc/expmed.c
index 0124a21..ad39034 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