mirror of git://gcc.gnu.org/git/gcc.git
re PR rtl-optimization/67028 (combine bug. Different assumptions about subreg in different places.)
PR rtl-optimization/67028 * combine.c (simplify_comparison): Fix comment. Rearrange code. Add test to see if a const_int fits in the new mode. gcc/testsuite/ PR rtl-optimization/67028 * gcc.dg/pr67028.c: New testcase. From-SVN: r226731
This commit is contained in:
parent
0fa95f4ead
commit
1aeec6dc1f
|
|
@ -1,3 +1,9 @@
|
|||
2015-08-08 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
PR rtl-optimization/67028
|
||||
* combine.c (simplify_comparison): Fix comment. Rearrange code.
|
||||
Add test to see if a const_int fits in the new mode.
|
||||
|
||||
2015-08-07 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* config/rx/rx.c (rx_mode_dependent_address_p): Remove unneeded asserts.
|
||||
|
|
|
|||
|
|
@ -12057,14 +12057,15 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1
|
||||
/* If this is (and:M1 (subreg:M1 X:M2 0) (const_int C1)) where C1
|
||||
fits in both M1 and M2 and the SUBREG is either paradoxical
|
||||
or represents the low part, permute the SUBREG and the AND
|
||||
and try again. */
|
||||
if (GET_CODE (XEXP (op0, 0)) == SUBREG)
|
||||
if (GET_CODE (XEXP (op0, 0)) == SUBREG
|
||||
&& CONST_INT_P (XEXP (op0, 1)))
|
||||
{
|
||||
unsigned HOST_WIDE_INT c1;
|
||||
tmode = GET_MODE (SUBREG_REG (XEXP (op0, 0)));
|
||||
unsigned HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
|
||||
/* Require an integral mode, to avoid creating something like
|
||||
(AND:SF ...). */
|
||||
if (SCALAR_INT_MODE_P (tmode)
|
||||
|
|
@ -12074,16 +12075,20 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
|
|||
have a defined value due to the AND operation.
|
||||
However, if we commute the AND inside the SUBREG then
|
||||
they no longer have defined values and the meaning of
|
||||
the code has been changed. */
|
||||
the code has been changed.
|
||||
Also C1 should not change value in the smaller mode,
|
||||
see PR67028 (a positive C1 can become negative in the
|
||||
smaller mode, so that the AND does no longer mask the
|
||||
upper bits). */
|
||||
&& ((WORD_REGISTER_OPERATIONS
|
||||
&& mode_width > GET_MODE_PRECISION (tmode)
|
||||
&& mode_width <= BITS_PER_WORD)
|
||||
&& mode_width <= BITS_PER_WORD
|
||||
&& trunc_int_for_mode (c1, tmode) == (HOST_WIDE_INT) c1)
|
||||
|| (mode_width <= GET_MODE_PRECISION (tmode)
|
||||
&& subreg_lowpart_p (XEXP (op0, 0))))
|
||||
&& CONST_INT_P (XEXP (op0, 1))
|
||||
&& mode_width <= HOST_BITS_PER_WIDE_INT
|
||||
&& HWI_COMPUTABLE_MODE_P (tmode)
|
||||
&& ((c1 = INTVAL (XEXP (op0, 1))) & ~mask) == 0
|
||||
&& (c1 & ~mask) == 0
|
||||
&& (c1 & ~GET_MODE_MASK (tmode)) == 0
|
||||
&& c1 != mask
|
||||
&& c1 != GET_MODE_MASK (tmode))
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
2015-08-08 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
PR rtl-optimization/67028
|
||||
* gcc.dg/pr67028.c: New testcase.
|
||||
|
||||
2015-08-07 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR rtl-optimization/67029
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-options "-O3" } */
|
||||
|
||||
short c = 0;
|
||||
|
||||
int __attribute__ ((noinline)) f(void)
|
||||
{
|
||||
int d = 5;
|
||||
signed char e = (c != 1) * -2;
|
||||
int a = (unsigned short)e > d;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (!f())
|
||||
__builtin_abort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue