public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/redhat/heads/gcc-8-branch)] optabs: Don't reuse target for multi-word expansions if it overlaps operand(s) [PR97073] Date: Mon, 28 Sep 2020 09:16:24 +0000 (GMT) [thread overview] Message-ID: <20200928091624.AA9E8384A881@sourceware.org> (raw) https://gcc.gnu.org/g:e5438c920c4d6ffad6eb85640698f4ff0307c0d7 commit e5438c920c4d6ffad6eb85640698f4ff0307c0d7 Author: Jakub Jelinek <jakub@redhat.com> Date: Sun Sep 27 23:18:26 2020 +0200 optabs: Don't reuse target for multi-word expansions if it overlaps operand(s) [PR97073] The following testcase is miscompiled on i686-linux, because we try to expand a double-word bitwise logic operation with op0 being a (mem:DI u) and target (mem:DI u+4), i.e. partial overlap, and thus end up with: movl 4(%esp), %eax andl u, %eax movl %eax, u+4 ! movl u+4, %eax optimized out andl 8(%esp), %eax movl %eax, u+8 rather than with the desired: movl 4(%esp), %edx movl 8(%esp), %eax andl u, %edx andl u+4, %eax movl %eax, u+8 movl %edx, u+4 because the store of the first word to target overwrites the second word of the operand. expand_binop for this (and several similar places) already check for target == op0 or target == op1, this patch just adds reg_overlap_mentioned_p calls next to it. Pedantically, at least for some of these it might be sufficient to force a different target if there is overlap but target is not rtx_equal_p to the operand (e.g. in this bitwise logical case, but e.g. not in the shift cases where there is reordering), though that would go against the preexisting target == op? checks and the rationale that REG_EQUAL notes in that case isn't correct. 2020-09-27 Jakub Jelinek <jakub@redhat.com> PR middle-end/97073 * optabs.c (expand_binop, expand_absneg_bit, expand_unop, expand_copysign_bit): Check reg_overlap_mentioned_p between target and operand(s) and if it returns true, force a pseudo as target. * gcc.c-torture/execute/pr97073.c: New test. (cherry picked from commit a4b31d5807f2bc67c8999b3d53369cf2a5c6e1ec) Diff: --- gcc/optabs.c | 14 +++++++++++++- gcc/testsuite/gcc.c-torture/execute/pr97073.c | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/gcc/optabs.c b/gcc/optabs.c index 51d838d4f93..9e93097fa55 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -1363,6 +1363,8 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, if (target == 0 || target == op0 || target == op1 + || reg_overlap_mentioned_p (target, op0) + || reg_overlap_mentioned_p (target, op1) || !valid_multiword_target_p (target)) target = gen_reg_rtx (int_mode); @@ -1437,6 +1439,8 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, if (target == 0 || target == op0 || target == op1 + || reg_overlap_mentioned_p (target, op0) + || reg_overlap_mentioned_p (target, op1) || !valid_multiword_target_p (target)) target = gen_reg_rtx (int_mode); @@ -1495,6 +1499,8 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, || target == op0 || target == op1 || !REG_P (target) + || reg_overlap_mentioned_p (target, op0) + || reg_overlap_mentioned_p (target, op1) || !valid_multiword_target_p (target)) target = gen_reg_rtx (int_mode); @@ -2632,6 +2638,7 @@ expand_absneg_bit (enum rtx_code code, scalar_float_mode mode, if (target == 0 || target == op0 + || reg_overlap_mentioned_p (target, op0) || (nwords > 1 && !valid_multiword_target_p (target))) target = gen_reg_rtx (mode); @@ -2910,7 +2917,10 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target, int i; rtx_insn *insns; - if (target == 0 || target == op0 || !valid_multiword_target_p (target)) + if (target == 0 + || target == op0 + || reg_overlap_mentioned_p (target, op0) + || !valid_multiword_target_p (target)) target = gen_reg_rtx (int_mode); start_sequence (); @@ -3420,6 +3430,8 @@ expand_copysign_bit (scalar_float_mode mode, rtx op0, rtx op1, rtx target, if (target == 0 || target == op0 || target == op1 + || reg_overlap_mentioned_p (target, op0) + || reg_overlap_mentioned_p (target, op1) || (nwords > 1 && !valid_multiword_target_p (target))) target = gen_reg_rtx (mode); diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97073.c b/gcc/testsuite/gcc.c-torture/execute/pr97073.c new file mode 100644 index 00000000000..1955e6b8bd2 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr97073.c @@ -0,0 +1,21 @@ +/* PR middle-end/97073 */ +/* { dg-additional-options "-mno-stv" { target i?86-*-* x86_64-*-* } } */ + +typedef unsigned long long L; +union U { L i; struct T { unsigned k; L l; } j; } u; + +__attribute__((noinline,noclone)) void +foo (L x) +{ + u.j.l = u.i & x; +} + +int +main () +{ + u.i = 5; + foo (-1ULL); + if (u.j.l != 5) + __builtin_abort (); + return 0; +}
reply other threads:[~2020-09-28 9:16 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200928091624.AA9E8384A881@sourceware.org \ --to=jakub@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).