Bug 61772 - RTL if-conversion removes asm volatile goto
Summary: RTL if-conversion removes asm volatile goto
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.8.4
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-07-10 13:03 UTC by Michael Matz
Modified: 2015-02-17 06:53 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Patch (509 bytes, patch)
2014-07-10 13:06 UTC, Michael Matz
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Matz 2014-07-10 13:03:26 UTC
This is reduced from a bug our kernel people hit.  The problem is
the use of asm volatile gotos inside a conditional, when the outgoing
blocks of the asm-goto are itself both empty.  Ala:

------------------------- snip ---------------------------------------
/* { dg-do compile } */
/* { dg-final { scan-assembler-times "XXX" 2 } } */

static inline __attribute__((always_inline)) int dec_and_test (int *i)
{
    asm volatile goto ("XXX %0, %l[cc_label]"
                       : : "m" (*i) : "memory" : cc_label);
    return 0;
cc_label:
    return 1;
}
extern int getit (int *);
int f (int *i, int cond)
{
  if (cond) {
      getit (0);
      if (dec_and_test (i))
        getit (i);
      return 42;
  }
  if (dec_and_test (i))
    (void)1;
  return getit (i);
}
------------------ snap ----------------------------------------------

This should have two "XXX" in the resulting assembler, but will have only
one with any optimization level.  It's the RTL if conversion that removes
the seemingly empty second dec_and_test(), because the then-block is
empty and because it doesn't check that the removed jump really is only
a jump without side effects.

I don't know if it's a regression (it probably isn't as I don't see that ifcvt.c
was touched with the introduction of asm gotos), but it at least affects
trunk and 4.8.
Comment 1 Michael Matz 2014-07-10 13:06:34 UTC
Created attachment 33102 [details]
Patch

Possible patch for the problem.  There are many predicates for testing various
forms of jump, after pondering and reading the comments about various of them
being deprecated, or leaving through only very specific forms of jumps I think
that onlyjump_p is the best one (it only rejects jumps with additional non-dead
side-effects).
Comment 2 Michael Matz 2014-07-15 14:11:39 UTC
Author: matz
Date: Tue Jul 15 14:11:06 2014
New Revision: 212563

URL: https://gcc.gnu.org/viewcvs?rev=212563&root=gcc&view=rev
Log:
        PR rtl-optimization/61772
        * ifcvt.c (dead_or_predicable): Check jump to be free of side
        effects.

testsuite/
        * gcc.dg/torture/pr61772.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr61772.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/ifcvt.c
    trunk/gcc/testsuite/ChangeLog
Comment 3 Andrew Pinski 2015-02-17 06:53:27 UTC
Fixed.