https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79929
Jeffrey A. Law <law at redhat dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P4 Status|UNCONFIRMED |NEW Last reconfirmed| |2017-03-07 CC| |law at redhat dot com Ever confirmed|0 |1 --- Comment #2 from Jeffrey A. Law <law at redhat dot com> --- Note, this triggers at O2 and above, but not at O1. This really looks like bogus code coming out of the Fortran front-end. I've got no clue why it's generating this code: [ ... ] _32 = _yerrmsg_19(D) + 5; _33 = _yerrmsg_19(D); [ ... ] ;; basic block 6, loop depth 0, count 0, freq 0, maybe hot ;; prev block 5, next block 7, flags: (NEW, REACHABLE) ;; pred: 5 (TRUE_VALUE) _7 = (unsigned long) _33; _8 = (unsigned long) _32; _9 = MIN_EXPR <_7, _8>; __builtin_memmove (yerrmsg_25(D), pstr.0_29, _9); _10 = (unsigned long) _32; _11 = (unsigned long) _33; if (_10 < _11) goto <bb 7>; [0.00%] else goto <bb 8>; [0.00%] ;; succ: 7 (TRUE_VALUE) ;; 8 (FALSE_VALUE) ;; basic block 7, loop depth 0, count 0, freq 0, maybe hot ;; prev block 6, next block 8, flags: (NEW, REACHABLE) ;; pred: 6 (TRUE_VALUE) _12 = (unsigned long) _33; _13 = (unsigned long) _32; _14 = _12 - _13; _15 = (sizetype) _32; _16 = yerrmsg_25(D) + _15; __builtin_memset (_16, 32, _14); ;; succ: 8 (FALLTHRU) So the test at the end of bb6 is really an overflow test. (x + 5 < x). The assignment to _14 is going to overflow. We end up in this match.pd pattern: /* (T)P - (T)(P + A) -> -(T) A */ (for add (plus pointer_plus) (simplify (minus (convert @0) (convert (add @@0 @1))) (if (element_precision (type) <= element_precision (TREE_TYPE (@1)) /* For integer types, if A has a smaller type than T the result depends on the possible overflow in P + A. E.g. T=size_t, A=(unsigned)429497295, P>0. However, if an overflow in P + A would cause undefined behavior, we can assume that there is no overflow. */ || (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))) /* For pointer types, if the conversion of A to the final type requires a sign- or zero-extension, then we have to punt - it is not defined which one is correct. */ || (POINTER_TYPE_P (TREE_TYPE (@0)) && TREE_CODE (@1) == INTEGER_CST && tree_int_cst_sign_bit (@1) == 0)) (negate (convert @1))))) Which results in: __builtin_memset (_16, 32, 18446744073709551611); Which we quite reasonably warn for. AFAICT this looks like bogus code coming out of the Fortran front-end to me. I don't see any way to mitigate in the optimization pipeline.