https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79054
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- I get > ./cc1 -quiet t.c -O2 -Wall -Walloc-size-larger-than=1234 -fdump-tree-all-alias t.c: In function ‘foo’: t.c:18:3: warning: argument 1 range [1236, 2147483647] exceeds maximum object size 1234 [-Walloc-size-larger-than=] sink (alloc (anti_range (INT_MIN + 2, 1235))); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ t.c:5:7: note: in a call to allocation function ‘alloc’ declared here void* alloc (int) __attribute__ ((alloc_size (1))); ^~~~~ t.c: In function ‘bar’: t.c:23:3: warning: argument 1 range [-2147483648, -1] is negative [-Walloc-size-larger-than=] sink (alloc (anti_range (0, INT_MAX))); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ t.c:5:7: note: in a call to allocation function ‘alloc’ declared here void* alloc (int) __attribute__ ((alloc_size (1))); ^~~~~ t.c: In function ‘foobar’: t.c:28:3: warning: argument 1 range [1236, 2147483647] exceeds maximum object size 1234 [-Walloc-size-larger-than=] sink (alloc (anti_range (INT_MIN + 2, 1235))); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ t.c:5:7: note: in a call to allocation function ‘alloc’ declared here void* alloc (int) __attribute__ ((alloc_size (1))); ^~~~~ t.c:29:3: warning: argument 1 range [-2147483648, -1] is negative [-Walloc-size-larger-than=] sink (alloc (anti_range (0, INT_MAX))); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ t.c:5:7: note: in a call to allocation function ‘alloc’ declared here void* alloc (int) __attribute__ ((alloc_size (1))); ^~~~~ with r244305, so not confirmed (x86_64-*-*). So VRP does <bb 2> [100.00%]: # USE = nonlocal # CLB = nonlocal val_10 = value (); # RANGE [0, 1] _11 = val_10 >= -2147483646; # RANGE [0, 1] _12 = val_10 <= 1235; # RANGE [0, 1] _13 = _11 & _12; if (_13 != 0) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] <bb 3> [50.00%]: <bb 4> [100.00%]: # val_14 = PHI <val_10(2), -2147483647(3)> gets asserts like <bb 2> [100.00%]: # USE = nonlocal # CLB = nonlocal val_10 = value (); # RANGE [0, 1] _11 = val_10 >= -2147483646; # RANGE [0, 1] _12 = val_10 <= 1235; # RANGE [0, 1] _13 = _11 & _12; if (_13 != 0) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] <bb 3> [50.00%]: val_19 = ASSERT_EXPR <val_10, val_10 >= -2147483646>; val_20 = ASSERT_EXPR <val_19, val_19 <= 1235>; <bb 4> [100.00%]: # val_14 = PHI <val_10(2), -2147483647(3)> so you can see that for val_14 we do not end up adding asserts for val_10 (because we do not rewrite PHIs). That's likely becuase we are missing to handle the "false" edge from _13 != 0 with the & handling. OTOH val_10 >= -214783646 & val_10 <= 1235 could have been folded to the simpler (unsigned)val_10 + CST >= CST. That is, fold-const.c's range_binop code needs (partial) moving to match.pd.