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.
Tested on powerpc64-linux {-m32,-m64} (where it fixes the regression
c-c++-common/torture/vector-compare-1.c fails at -O1, and where it also
has a bootstrap failure with some other patches). Also tested that the
x86_64 compiler still generates the wanted code for the PR77881 testcase.
Segher
2016-11-23 Segher Boessenkool <[email protected]>
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.
---
gcc/combine.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/gcc/combine.c b/gcc/combine.c
index c025125..ca944c6 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -8143,12 +8143,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;
}
--
1.9.3