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.