diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-05-03 14:56:12 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-05-03 14:56:12 +0200 |
commit | 47954c4e773ef399e269f0660a74369b3fb95f93 (patch) | |
tree | a94c8648366d4d082e453944d835339cf069619d /gcc | |
parent | 3c21604ff116e07ed3ea58a93339820d0dc8af67 (diff) | |
download | gcc-47954c4e773ef399e269f0660a74369b3fb95f93.zip gcc-47954c4e773ef399e269f0660a74369b3fb95f93.tar.gz gcc-47954c4e773ef399e269f0660a74369b3fb95f93.tar.bz2 |
re PR rtl-optimization/57130 (Incorrect "and --> extract" conversion in combine)
PR rtl-optimization/57130
* combine.c (make_compound_operation) <case SUBREG>: Pass
SET instead of COMPARE as in_code to the recursive call
if needed.
* gcc.c-torture/execute/pr57130.c: New test.
From-SVN: r198579
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/combine.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr57130.c | 21 |
4 files changed, 51 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2b906eb..4bd0ea7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-05-03 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/57130 + * combine.c (make_compound_operation) <case SUBREG>: Pass + SET instead of COMPARE as in_code to the recursive call + if needed. + 2013-05-03 Uros Bizjak <ubizjak@gmail.com> * config/i386/i386.md (isa): Add x64_sse4_noavx and x64_avx members. diff --git a/gcc/combine.c b/gcc/combine.c index 6d58b19..0792ba3 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7697,8 +7697,24 @@ make_compound_operation (rtx x, enum rtx_code in_code) what it originally did, do this SUBREG as a force_to_mode. */ { rtx inner = SUBREG_REG (x), simplified; - - tem = make_compound_operation (inner, in_code); + enum rtx_code subreg_code = in_code; + + /* If in_code is COMPARE, it isn't always safe to pass it through + to the recursive make_compound_operation call. */ + if (subreg_code == COMPARE + && (!subreg_lowpart_p (x) + || GET_CODE (inner) == SUBREG + /* (subreg:SI (and:DI (reg:DI) (const_int 0x800000000)) 0) + is (const_int 0), rather than + (subreg:SI (lshiftrt:DI (reg:DI) (const_int 35)) 0). */ + || (GET_CODE (inner) == AND + && CONST_INT_P (XEXP (inner, 1)) + && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner)) + && exact_log2 (UINTVAL (XEXP (inner, 1))) + >= GET_MODE_BITSIZE (mode)))) + subreg_code = SET; + + tem = make_compound_operation (inner, subreg_code); simplified = simplify_subreg (mode, tem, GET_MODE (inner), SUBREG_BYTE (x)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e40150a..25a131c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-05-03 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/57130 + * gcc.c-torture/execute/pr57130.c: New test. + 2013-05-03 Uros Bizjak <ubizjak@gmail.com> * gcc.target/i386/sse2-init-v2di-2.c: Update scan assembler string. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr57130.c b/gcc/testsuite/gcc.c-torture/execute/pr57130.c new file mode 100644 index 0000000..6113203 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr57130.c @@ -0,0 +1,21 @@ +/* PR rtl-optimization/57130 */ + +struct S { int a, b, c, d; } s[2] = { { 6, 8, -8, -5 }, { 0, 2, -1, 2 } }; + +__attribute__((noinline, noclone)) void +foo (struct S r) +{ + static int cnt; + if (__builtin_memcmp (&r, &s[cnt++], sizeof r) != 0) + __builtin_abort (); +} + +int +main () +{ + struct S r = { 6, 8, -8, -5 }; + foo (r); + r = (struct S) { 0, 2, -1, 2 }; + foo (r); + return 0; +} |