https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66812
--- Comment #9 from David Malcolm <dmalcolm at gcc dot gnu.org> --- Notes to self: For the given stmt, fre1's call to: val = vn_reference_lookup (gimple_assign_lhs (stmt), gimple_vuse (stmt), VN_WALK, NULL); is returning NULL for "val", whereas libgccjit is returning the const_int 0 node, hence the latter regards stmt as as redundant assignment and eliminates it. Within the call to vn_reference_lookup: 2232 vr1.set = get_alias_set (op); For cc1: (gdb) p vr1.set $24 = 0 (gdb) p wvnresult $26 = (vn_reference_t) 0x0 and it bails out of vn_reference_lookup here: 2262 return NULL_TREE; Whereas for libgccjit, the call to vn_reference_lookup does this: (gdb) p vr1.set $6 = 2 and walk_non_aliased_vuses returns non-NULL: (gdb) p wvnresult $7 = (vn_reference_t) 0x677dd0 libgccjit: (gdb) call get_alias_set (op) $11 = 2 cc1: (gdb) call get_alias_set(op) $27 = 0 and this is because of a langhook, implemented for C/C++/ObjC, but not (yet) for libgccjit: 837 alias_set_type 838 get_alias_set (tree t) 839 { (snip) 849 850 /* We can be passed either an expression or a type. This and the 851 language-specific routine may make mutually-recursive calls to each other 852 to figure out what to do. At each juncture, we see if this is a tree 853 that the language may need to handle specially. First handle things that 854 aren't types. */ 855 if (! TYPE_P (t)) 856 { 857 /* Give the language a chance to do something with this tree 858 before we look at it. */ 859 STRIP_NOPS (t); 860 set = lang_hooks.get_alias_set (t); 861 if (set != -1) 862 return set; c/c-objc-common.h:45:#undef LANG_HOOKS_GET_ALIAS_SET c/c-objc-common.h:46:#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set c-family/c-common.c: 5157 /* Return the typed-based alias set for T, which may be an expression 5158 or a type. Return -1 if we don't do anything special. */ 5159 5160 alias_set_type 5161 c_common_get_alias_set (tree t) 5162 { 5163 tree u; (snip) 5173 5174 /* Permit type-punning when accessing a union, provided the access 5175 is directly through the union. For example, this code does not 5176 permit taking the address of a union member and then storing 5177 through it. Even the type-punning allowed here is a GCC 5178 extension, albeit a common and useful one; the C standard says 5179 that such accesses have implementation-defined behavior. */ 5180 for (u = t; 5181 TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF; 5182 u = TREE_OPERAND (u, 0)) 5183 if (TREE_CODE (u) == COMPONENT_REF 5184 && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) 5185 return 0; For C, it's exiting at line 5185 for the given statement's LHS.