https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119006
--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> --- --- gcc/ipa-icf.cc.jj 2025-01-02 11:23:19.997468267 +0100 +++ gcc/ipa-icf.cc 2025-02-27 13:48:15.069430554 +0100 @@ -1810,6 +1810,9 @@ sem_variable::equals (tree t1, tree t2) tree y1 = TREE_OPERAND (t1, 1); tree y2 = TREE_OPERAND (t2, 1); + if (!func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))) + return return_false (); + if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2))) return return_false (); doesn't fix that though, I guess the MEM_REFs are compared with operand_equal_p instead. And, operand_equal_p normally compares the types of the MEM_REFs and checks alias_ptr_types_compatible_p for the types of the MEM_REF offsets. But doesn't do that in the OEP_ADDRESS_OF case, which is what happens here, _1 = &this_5(D)->a; because everything is in ADDR_EXPR. Such details are irrelevant for the value of the ADDR_EXPR, but get_range_strlen_tree still cares about. So, shall we introduce some new OEP_* flag used for the ICF operand_equal_p that will make it check the MEM_REF details even when OEP_ADDRESS_OF? Or check for that manually in ipa-icf-gimple.cc (compare_operand)? Perhaps all we care about is if toplevel t1 is ADDR_EXPR check if the operand is equal too?