public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix up thread_jump handling of jumps with clobbers (PR rtl-optimization/88904)
@ 2019-01-21 22:32 Jakub Jelinek
  2019-01-22  8:32 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2019-01-21 22:32 UTC (permalink / raw)
  To: Richard Biener, Eric Botcazou, Jan Hubicka; +Cc: gcc-patches

Hi!

The following patch is miscompiled on arm thumb1, where there is
(jump_insn 32 31 33 4 (parallel [
            (set (pc)
                (if_then_else (ne (zero_extract:SI (reg:SI 3 r3 [orig:127 ret+8 ] [127])
                            (const_int 1 [0x1])
                            (const_int 0 [0]))
                        (const_int 0 [0]))
                    (label_ref 40)
                    (pc)))
            (clobber (reg:SI 3 r3 [137]))
        ]) "pr88904.c":19:3 843 {*tbit_cbranch}
     (int_list:REG_BR_PROB 719407028 (nil))
 -> 40)
instruction as BB_END (b).  thread_jump sees the same condition in 2 of
these jumps, originally each one is comparing a different value in r3.
It processes with cselib's help first the bb containing the first jump and
then goes through all the instructions in b, computing the nonequal bitmap
which registers contain different values from the earlier bb.
After going through the entire b, it checks that the cond2 in BB_END (b)
doesn't use any of the registers that are different (in nonequal bitmap)
and later on that there aren't any other differences.
The problem is that when a register has CLOBBER, it is cleared from the
nonequal bitmap, so, if we check cond2 after processing the above JUMP_INSN,
we don't actually see any differences; but the condition uses the registers
from before that JUMP_INSN, where there is a difference.

The following patch fixes it by moving the cond2 verification right before
we process the last insn in b; we still need to process it for the decision
if there are any real differences later.

Bootstrapped/regtested on x86_64-linux and i686-linux, will
bootstrap/regtest on armv7hl-linux too, ok for trunk?

2019-01-21  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/88904
	* cfgcleanup.c (thread_jump): Verify cond2 doesn't mention
	any nonequal registers before processing BB_END (b).

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

--- gcc/cfgcleanup.c.jj	2019-01-01 12:37:19.147942300 +0100
+++ gcc/cfgcleanup.c	2019-01-21 16:45:52.576636305 +0100
@@ -338,6 +338,13 @@ thread_jump (edge e, basic_block b)
        insn != NEXT_INSN (BB_END (b)) && !failed;
        insn = NEXT_INSN (insn))
     {
+      /* cond2 must not mention any register that is not equal to the
+	 former block.  Check this before processing that instruction,
+	 as BB_END (b) could contain also clobbers.  */
+      if (insn == BB_END (b)
+	  && mentions_nonequal_regs (cond2, nonequal))
+	goto failed_exit;
+
       if (INSN_P (insn))
 	{
 	  rtx pat = PATTERN (insn);
@@ -362,11 +369,6 @@ thread_jump (edge e, basic_block b)
       goto failed_exit;
     }
 
-  /* cond2 must not mention any register that is not equal to the
-     former block.  */
-  if (mentions_nonequal_regs (cond2, nonequal))
-    goto failed_exit;
-
   EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, rsi)
     goto failed_exit;
 
--- gcc/testsuite/gcc.c-torture/execute/pr88904.c.jj	2019-01-21 16:47:16.194265770 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr88904.c	2019-01-21 16:46:59.278543027 +0100
@@ -0,0 +1,38 @@
+/* PR rtl-optimization/88904 */
+
+volatile int v;
+
+__attribute__((noipa)) void
+bar (const char *x, const char *y, int z)
+{
+  if (!v)
+    __builtin_abort ();
+  asm volatile ("" : "+g" (x));
+  asm volatile ("" : "+g" (y));
+  asm volatile ("" : "+g" (z));
+}
+
+#define my_assert(e) ((e) ? (void) 0 : bar (#e, __FILE__, __LINE__))
+
+typedef struct {
+  unsigned M1;
+  unsigned M2 : 1;
+  int : 0;
+  unsigned M3 : 1;
+} S;
+
+S
+foo ()
+{
+  S result = {0, 0, 1};
+  return result;
+}
+
+int
+main ()
+{
+  S ret = foo ();
+  my_assert (ret.M2 == 0);
+  my_assert (ret.M3 == 1);
+  return 0;
+}

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix up thread_jump handling of jumps with clobbers (PR rtl-optimization/88904)
  2019-01-21 22:32 [PATCH] Fix up thread_jump handling of jumps with clobbers (PR rtl-optimization/88904) Jakub Jelinek
@ 2019-01-22  8:32 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2019-01-22  8:32 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Eric Botcazou, Jan Hubicka, gcc-patches

On Mon, 21 Jan 2019, Jakub Jelinek wrote:

> Hi!
> 
> The following patch is miscompiled on arm thumb1, where there is
> (jump_insn 32 31 33 4 (parallel [
>             (set (pc)
>                 (if_then_else (ne (zero_extract:SI (reg:SI 3 r3 [orig:127 ret+8 ] [127])
>                             (const_int 1 [0x1])
>                             (const_int 0 [0]))
>                         (const_int 0 [0]))
>                     (label_ref 40)
>                     (pc)))
>             (clobber (reg:SI 3 r3 [137]))
>         ]) "pr88904.c":19:3 843 {*tbit_cbranch}
>      (int_list:REG_BR_PROB 719407028 (nil))
>  -> 40)
> instruction as BB_END (b).  thread_jump sees the same condition in 2 of
> these jumps, originally each one is comparing a different value in r3.
> It processes with cselib's help first the bb containing the first jump and
> then goes through all the instructions in b, computing the nonequal bitmap
> which registers contain different values from the earlier bb.
> After going through the entire b, it checks that the cond2 in BB_END (b)
> doesn't use any of the registers that are different (in nonequal bitmap)
> and later on that there aren't any other differences.
> The problem is that when a register has CLOBBER, it is cleared from the
> nonequal bitmap, so, if we check cond2 after processing the above JUMP_INSN,
> we don't actually see any differences; but the condition uses the registers
> from before that JUMP_INSN, where there is a difference.
> 
> The following patch fixes it by moving the cond2 verification right before
> we process the last insn in b; we still need to process it for the decision
> if there are any real differences later.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, will
> bootstrap/regtest on armv7hl-linux too, ok for trunk?

OK.

Richard.

> 2019-01-21  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR rtl-optimization/88904
> 	* cfgcleanup.c (thread_jump): Verify cond2 doesn't mention
> 	any nonequal registers before processing BB_END (b).
> 
> 	* gcc.c-torture/execute/pr88904.c: New test.
> 
> --- gcc/cfgcleanup.c.jj	2019-01-01 12:37:19.147942300 +0100
> +++ gcc/cfgcleanup.c	2019-01-21 16:45:52.576636305 +0100
> @@ -338,6 +338,13 @@ thread_jump (edge e, basic_block b)
>         insn != NEXT_INSN (BB_END (b)) && !failed;
>         insn = NEXT_INSN (insn))
>      {
> +      /* cond2 must not mention any register that is not equal to the
> +	 former block.  Check this before processing that instruction,
> +	 as BB_END (b) could contain also clobbers.  */
> +      if (insn == BB_END (b)
> +	  && mentions_nonequal_regs (cond2, nonequal))
> +	goto failed_exit;
> +
>        if (INSN_P (insn))
>  	{
>  	  rtx pat = PATTERN (insn);
> @@ -362,11 +369,6 @@ thread_jump (edge e, basic_block b)
>        goto failed_exit;
>      }
>  
> -  /* cond2 must not mention any register that is not equal to the
> -     former block.  */
> -  if (mentions_nonequal_regs (cond2, nonequal))
> -    goto failed_exit;
> -
>    EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, rsi)
>      goto failed_exit;
>  
> --- gcc/testsuite/gcc.c-torture/execute/pr88904.c.jj	2019-01-21 16:47:16.194265770 +0100
> +++ gcc/testsuite/gcc.c-torture/execute/pr88904.c	2019-01-21 16:46:59.278543027 +0100
> @@ -0,0 +1,38 @@
> +/* PR rtl-optimization/88904 */
> +
> +volatile int v;
> +
> +__attribute__((noipa)) void
> +bar (const char *x, const char *y, int z)
> +{
> +  if (!v)
> +    __builtin_abort ();
> +  asm volatile ("" : "+g" (x));
> +  asm volatile ("" : "+g" (y));
> +  asm volatile ("" : "+g" (z));
> +}
> +
> +#define my_assert(e) ((e) ? (void) 0 : bar (#e, __FILE__, __LINE__))
> +
> +typedef struct {
> +  unsigned M1;
> +  unsigned M2 : 1;
> +  int : 0;
> +  unsigned M3 : 1;
> +} S;
> +
> +S
> +foo ()
> +{
> +  S result = {0, 0, 1};
> +  return result;
> +}
> +
> +int
> +main ()
> +{
> +  S ret = foo ();
> +  my_assert (ret.M2 == 0);
> +  my_assert (ret.M3 == 1);
> +  return 0;
> +}
> 
> 	Jakub
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-01-22  8:32 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-21 22:32 [PATCH] Fix up thread_jump handling of jumps with clobbers (PR rtl-optimization/88904) Jakub Jelinek
2019-01-22  8:32 ` Richard Biener

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).