https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80065

            Bug ID: 80065
           Summary: [7 Regression] sibling-call guard no longer working
           Product: gcc
           Version: 7.0.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org
  Target Milestone: ---

ruby uses

#define RB_GC_GUARD_PTR(ptr) \
    __extension__ ({volatile VALUE *rb_gc_guarded_ptr = (ptr);
rb_gc_guarded_ptr;})
#define RB_GC_GUARD(v) (*RB_GC_GUARD_PTR(&(v)))

to prevent sibling calls in code like

NODE*
rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
{
    struct parser_params *parser;
    NODE *node;

    TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type,
parser);
    lex_gets = lex_io_gets;
    lex_input = file;
    lex_pbeg = lex_p = lex_pend = 0;
    compile_for_eval = !!rb_parse_in_eval();

    node = yycompile(parser, fname, start);
    RB_GC_GUARD(vparser); /* prohibit tail call optimization */

    return node;
}

testcase:

int foo (int);
int bar (int x)
{
  int ret;
  ret = foo (x);
    *({volatile int *p = &x; p;});
  return ret;
}

this no longer works since we figure that nothing can ever observe the
volatile load in update-address-taken which rewrites x to a register.

Index: gcc/tree-ssa.c
===================================================================
--- gcc/tree-ssa.c      (revision 246188)
+++ gcc/tree-ssa.c      (working copy)
@@ -1422,6 +1422,8 @@ non_rewritable_mem_ref_base (tree ref)
       tree decl = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
       if (! DECL_P (decl))
        return NULL_TREE;
+      if (TREE_THIS_VOLATILE (decl) != TREE_THIS_VOLATILE (base))
+       return decl;
       if (! is_gimple_reg_type (TREE_TYPE (base))
          || VOID_TYPE_P (TREE_TYPE (base)))
        return decl;

re-instantiates previous behavior.

Reply via email to