diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/expr.c | 15 |
2 files changed, 17 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fe1d9c3..a9263af 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -2,6 +2,14 @@ Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> + * expr.c (emit_group_load_1): Tighten check for whether an + access involves only one operand of a CONCAT. Use extract_bit_field + for constants if the bit range does span the whole operand. + +2016-11-16 Richard Sandiford <richard.sandiford@arm.com> + Alan Hayward <alan.hayward@arm.com> + David Sherwood <david.sherwood@arm.com> + * rtlanal.c (rtx_addr_can_trap_p_1): Handle unknown sizes. 2016-11-16 Richard Sandiford <richard.sandiford@arm.com> @@ -2175,19 +2175,22 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize) { unsigned int slen = GET_MODE_SIZE (GET_MODE (src)); unsigned int slen0 = GET_MODE_SIZE (GET_MODE (XEXP (src, 0))); + unsigned int elt = bytepos / slen0; + unsigned int subpos = bytepos % slen0; - if ((bytepos == 0 && bytelen == slen0) - || (bytepos != 0 && bytepos + bytelen <= slen)) + if (subpos + bytelen <= slen0) { /* The following assumes that the concatenated objects all have the same size. In this case, a simple calculation can be used to determine the object and the bit field to be extracted. */ - tmps[i] = XEXP (src, bytepos / slen0); - if (! CONSTANT_P (tmps[i]) - && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode)) + tmps[i] = XEXP (src, elt); + if (subpos != 0 + || subpos + bytelen != slen0 + || (!CONSTANT_P (tmps[i]) + && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode))) tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT, - (bytepos % slen0) * BITS_PER_UNIT, + subpos * BITS_PER_UNIT, 1, NULL_RTX, mode, mode, false); } else |