From 712871dde1fb2d29b4f742fababb645cd3b1dbbe Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Wed, 23 Nov 2016 15:33:13 +0100 Subject: [PATCH] combine: Convert subreg-of-lshiftrt to zero_extract properly (PR78390) r242414, for PR77881, introduces some bugs (PR78390, PR78438, PR78477). It all has the same root cause: that patch makes combine convert every lowpart subreg of a logical shift right to a zero_extract. This cannot work at all if it is not a constant shift, and it has to be a bit more careful exactly which bits it extracts. 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. From-SVN: r242757 --- gcc/ChangeLog | 11 +++++++++++ gcc/combine.c | 7 ++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aa1d22f92d7..9f1a5c2e0ba 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2016-11-23 Segher Boessenkool + + 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 Alan Hayward David Sherwood diff --git a/gcc/combine.c b/gcc/combine.c index 93621bd02fb..ae25ef35ed9 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; } -- 2.30.2