backport: re PR rtl-optimization/82192 (gcc produces incorrect code with -O2 and bit-field)

Backported from mainline
	2017-09-15  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/82192
	* combine.c (make_extraction): Don't look through non-paradoxical
	SUBREGs or TRUNCATE if pos + len is or might be bigger than
	inner's mode.

	* gcc.c-torture/execute/pr82192.c: New test.

From-SVN: r254177
This commit is contained in:
Jakub Jelinek 2017-10-27 22:32:21 +02:00 committed by Jakub Jelinek
parent ee3ac71709
commit eeecd15ffc
4 changed files with 54 additions and 2 deletions

View File

@ -1,3 +1,13 @@
2017-10-27 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2017-09-15 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/82192
* combine.c (make_extraction): Don't look through non-paradoxical
SUBREGs or TRUNCATE if pos + len is or might be bigger than
inner's mode.
2017-10-27 Jakub Jelinek <jakub@redhat.com>
PR target/82703

View File

@ -7397,7 +7397,14 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
if (pos_rtx && CONST_INT_P (pos_rtx))
pos = INTVAL (pos_rtx), pos_rtx = 0;
if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner))
if (GET_CODE (inner) == SUBREG
&& subreg_lowpart_p (inner)
&& (paradoxical_subreg_p (inner)
/* If trying or potentionally trying to extract
bits outside of is_mode, don't look through
non-paradoxical SUBREGs. See PR82192. */
|| (pos_rtx == NULL_RTX
&& pos + len <= GET_MODE_PRECISION (is_mode))))
{
/* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...),
consider just the QI as the memory to extract from.
@ -7423,7 +7430,12 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
if (new_rtx != 0)
return gen_rtx_ASHIFT (mode, new_rtx, XEXP (inner, 1));
}
else if (GET_CODE (inner) == TRUNCATE)
else if (GET_CODE (inner) == TRUNCATE
/* If trying or potentionally trying to extract
bits outside of is_mode, don't look through
TRUNCATE. See PR82192. */
&& pos_rtx == NULL_RTX
&& pos + len <= GET_MODE_PRECISION (is_mode))
inner = XEXP (inner, 0);
inner_mode = GET_MODE (inner);

View File

@ -1,3 +1,11 @@
2017-10-27 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2017-09-15 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/82192
* gcc.c-torture/execute/pr82192.c: New test.
2017-10-27 Jakub Jelinek <jakub@redhat.com>
PR target/82703

View File

@ -0,0 +1,22 @@
/* PR rtl-optimization/82192 */
unsigned long long int a = 0x95dd3d896f7422e2ULL;
struct S { unsigned int m : 13; } b;
__attribute__((noinline, noclone)) void
foo (void)
{
b.m = ((unsigned) a) >> (0x644eee9667723bf7LL
| a & ~0xdee27af8U) - 0x644eee9667763bd8LL;
}
int
main ()
{
if (__INT_MAX__ != 0x7fffffffULL)
return 0;
foo ();
if (b.m != 0)
__builtin_abort ();
return 0;
}