aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/combine.c7
2 files changed, 17 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index aa1d22f..9f1a5c2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2016-11-23 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR target/77881
+ PR bootstrap/78390
+ PR target/78438
+ PR bootstrap/78477
+ * combine.c (make_compound_operation_int): Do not convert a subreg of
+ a non-constant logical shift right to a zero_extract. Handle the case
+ where some zero bits have been shifted into the range covered by that
+ subreg.
+
2016-11-23 Richard Sandiford <richard.sandiford@arm.com>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
diff --git a/gcc/combine.c b/gcc/combine.c
index 93621bd..ae25ef3 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -8089,12 +8089,17 @@ make_compound_operation_int (machine_mode mode, rtx *x_ptr,
/* If the SUBREG is masking of a logical right shift,
make an extraction. */
if (GET_CODE (inner) == LSHIFTRT
+ && CONST_INT_P (XEXP (inner, 1))
&& GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner))
&& subreg_lowpart_p (x))
{
new_rtx = make_compound_operation (XEXP (inner, 0), next_code);
+ int width = GET_MODE_PRECISION (GET_MODE (inner))
+ - INTVAL (XEXP (inner, 1));
+ if (width > mode_width)
+ width = mode_width;
new_rtx = make_extraction (mode, new_rtx, 0, XEXP (inner, 1),
- mode_width, 1, 0, in_code == COMPARE);
+ width, 1, 0, in_code == COMPARE);
break;
}