https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87813
Bug ID: 87813 Summary: sprintf pass calling evrp at -O0 and setting global ranges which affect strnlen expansion Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: aldyh at gcc dot gnu.org Target Milestone: --- For gcc.c-torture/execute/builtins/strnlen.c at -Og, the -fprintf-return-value pass does not change the IL, but is setting global range information, which in turn, is affecting builtin strnlen expansion. This is because AFAICT the sprintf pass calls evrp on the entire IL regardless of its need: edge sprintf_dom_walker::before_dom_children (basic_block bb) { evrp_range_analyzer.enter (bb); for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); ) { /* Iterate over statements, looking for function calls. */ gimple *stmt = gsi_stmt (si); /* First record ranges generated by this statement. */ evrp_range_analyzer.record_ranges_from_stmt (stmt, false); etc. For example: +Visiting statement: +# USE = anything +_1 = strnlen ("", r_0_3_17); Notice this is the sprintf optimization pass, not the strlen pass. Setting global ranges for these "peeks" into strnlen arguments causes changes in the behavior of expand_builtin_strnlen(): wide_int min, max; enum value_range_kind rng = get_range_info (bound, &min, &max); if (rng != VR_RANGE) return NULL_RTX; etc. This is similar to the discussion I started here, where Martin correctly pointed out that it wasn't just warnings but printf optimizations which were touching global range information: https://gcc.gnu.org/ml/gcc-patches/2018-07/msg00420.html Further down thread, Jeff said he'd volunteer to fix this. I'm just documenting it here, so we don't forget about it. Meta question-- do we want to be running a full evrp at -O0 (or -Og in this case)? Thanks folks.