https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87445
Bug ID: 87445 Summary: missing null test optimization for a pointer member Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- Because f() is declared nonnull, GCC successfully eliminates the unnecessary null pointer test in function g below. However, it fails to perform the same simplification in function h(). I noticed this after adding attribute nonnull to a few GCC functions in tree.h didn't have the effect on the emitted object code that I expected. For example, in something as simple as the following, GCC doesn't eliminate the unnecessary test: extern HOST_WIDE_INT tree_to_shwi (const_tree) ATTRIBUTE_NONNULL (1); HOST_WIDE_INT foobar (tree t) { HOST_WIDE_INT x = tree_to_shwi (TYPE_SIZE (t)); if (!TYPE_SIZE (t)) __builtin_abort (); return x; } $ cat t.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout t.c __attribute__ ((nonnull)) int f (void*); struct S { void *p; }; int g (void *p) { int i = f (p); if (!p) // folded to false __builtin_abort (); // eliminated return i; } int h (struct S *p) { int i = f (p->p); if (!p->p) // not folded but could be __builtin_abort (); // not eliminated return i; } ;; Function g (g, funcdef_no=0, decl_uid=1910, cgraph_uid=1, symbol_order=0) g (void * p) { int i; <bb 2> [local count: 1073741824]: i_4 = f (p_2(D)); [tail call] return i_4; } ;; Function h (h, funcdef_no=1, decl_uid=1914, cgraph_uid=2, symbol_order=1) h (struct S * p) { int i; void * _1; void * _2; <bb 2> [local count: 1073741824]: _1 = p_4(D)->p; i_6 = f (_1); _2 = p_4(D)->p; if (_2 == 0B) goto <bb 3>; [0.00%] else goto <bb 4>; [99.96%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073312328]: return i_6; }