https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81785
Marek Polacek <mpolacek at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |mpolacek at gcc dot gnu.org --- Comment #3 from Marek Polacek <mpolacek at gcc dot gnu.org> --- Re-adding richi's comment. I'm going to try the following. --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- We emit int k = -2147483648; return x + ((sizetype) ((long unsigned int) k * 4) + 18446744065119617028); and it seems we end up zero-extending k. I believe that's because of the (premature) optimization in pointer_int_sum: /* If what we are about to multiply by the size of the elements contains a constant term, apply distributive law and multiply that constant term separately. This helps produce common subexpressions. */ if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR) && !TREE_CONSTANT (intop) && TREE_CONSTANT (TREE_OPERAND (intop, 1)) && TREE_CONSTANT (size_exp) /* If the constant comes from pointer subtraction, skip this optimization--it would cause an error. */ && TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE /* If the constant is unsigned, and smaller than the pointer size, then we must skip this optimization. This is because it could cause an overflow error if the constant is negative but INTOP is not. */ && (!TYPE_UNSIGNED (TREE_TYPE (intop)) || (TYPE_PRECISION (TREE_TYPE (intop)) == TYPE_PRECISION (TREE_TYPE (ptrop))))) { enum tree_code subcode = resultcode; tree int_type = TREE_TYPE (intop); if (TREE_CODE (intop) == MINUS_EXPR) subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR); /* Convert both subexpression types to the type of intop, because weird cases involving pointer arithmetic can result in a sum or difference with different type args. */ ptrop = build_binary_op (EXPR_LOCATION (TREE_OPERAND (intop, 1)), subcode, ptrop, convert (int_type, TREE_OPERAND (intop, 1)), true); intop = convert (int_type, TREE_OPERAND (intop, 0)); } compilable testcase: int * __attribute__((__noinline__, __noclone__)) foo(int x[]) { int k = (-__INT_MAX__ - 1); return x + (k - __INT_MAX__); } I suggest trying to remove the above... (doing so fixes the testcase)