This fixes PHI value-numbering which did not correctly distinguish types in case of still VN_TOP PHI arguments.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2013-02-19 Richard Biener <rguent...@suse.de> PR tree-optimization/56384 * tree-ssa-sccvn.h (struct vn_phi_s): Add type member. (vn_hash_type): Split out from ... (vn_hash_constant_with_type): ... here. * tree-ssa-sccvn.c (vn_phi_compute_hash): Use vn_hash_type. (vn_phi_eq): Compare types from vn_phi_s structure. (vn_phi_lookup): Populate vn_phi_s type. (vn_phi_insert): Likewise. * gcc.dg/torture/pr56384.c: New testcase. Index: gcc/tree-ssa-sccvn.h =================================================================== *** gcc/tree-ssa-sccvn.h (revision 196134) --- gcc/tree-ssa-sccvn.h (working copy) *************** typedef struct vn_phi_s *** 67,72 **** --- 67,73 ---- hashval_t hashcode; vec<tree> phiargs; basic_block block; + tree type; tree result; } *vn_phi_t; typedef const struct vn_phi_s *const_vn_phi_t; *************** typedef struct vn_constant_s *** 122,138 **** enum vn_kind { VN_NONE, VN_CONSTANT, VN_NARY, VN_REFERENCE, VN_PHI }; enum vn_kind vn_get_stmt_kind (gimple); /* Hash the constant CONSTANT with distinguishing type incompatible constants in the types_compatible_p sense. */ static inline hashval_t vn_hash_constant_with_type (tree constant) { - tree type = TREE_TYPE (constant); return (iterative_hash_expr (constant, 0) ! + INTEGRAL_TYPE_P (type) ! + (INTEGRAL_TYPE_P (type) ! ? TYPE_PRECISION (type) + TYPE_UNSIGNED (type) : 0)); } /* Compare the constants C1 and C2 with distinguishing type incompatible --- 123,147 ---- enum vn_kind { VN_NONE, VN_CONSTANT, VN_NARY, VN_REFERENCE, VN_PHI }; enum vn_kind vn_get_stmt_kind (gimple); + /* Hash the type TYPE using bits that distinguishes it in the + types_compatible_p sense. */ + + static inline hashval_t + vn_hash_type (tree type) + { + return (INTEGRAL_TYPE_P (type) + + (INTEGRAL_TYPE_P (type) + ? TYPE_PRECISION (type) + TYPE_UNSIGNED (type) : 0)); + } + /* Hash the constant CONSTANT with distinguishing type incompatible constants in the types_compatible_p sense. */ static inline hashval_t vn_hash_constant_with_type (tree constant) { return (iterative_hash_expr (constant, 0) ! + vn_hash_type (TREE_TYPE (constant))); } /* Compare the constants C1 and C2 with distinguishing type incompatible Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 196134) --- gcc/tree-ssa-sccvn.c (working copy) *************** vn_phi_compute_hash (vn_phi_t vp1) *** 2401,2410 **** /* If all PHI arguments are constants we need to distinguish the PHI node via its type. */ ! type = TREE_TYPE (vp1->phiargs[0]); ! result += (INTEGRAL_TYPE_P (type) ! + (INTEGRAL_TYPE_P (type) ! ? TYPE_PRECISION (type) + TYPE_UNSIGNED (type) : 0)); FOR_EACH_VEC_ELT (vp1->phiargs, i, phi1op) { --- 2401,2408 ---- /* If all PHI arguments are constants we need to distinguish the PHI node via its type. */ ! type = vp1->type; ! result += vn_hash_type (type); FOR_EACH_VEC_ELT (vp1->phiargs, i, phi1op) { *************** vn_phi_eq (const void *p1, const void *p *** 2443,2450 **** /* If the PHI nodes do not have compatible types they are not the same. */ ! if (!types_compatible_p (TREE_TYPE (vp1->phiargs[0]), ! TREE_TYPE (vp2->phiargs[0]))) return false; /* Any phi in the same block will have it's arguments in the --- 2441,2447 ---- /* If the PHI nodes do not have compatible types they are not the same. */ ! if (!types_compatible_p (vp1->type, vp2->type)) return false; /* Any phi in the same block will have it's arguments in the *************** vn_phi_lookup (gimple phi) *** 2484,2489 **** --- 2481,2487 ---- def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def; shared_lookup_phiargs.safe_push (def); } + vp1.type = TREE_TYPE (gimple_phi_result (phi)); vp1.phiargs = shared_lookup_phiargs; vp1.block = gimple_bb (phi); vp1.hashcode = vn_phi_compute_hash (&vp1); *************** vn_phi_insert (gimple phi, tree result) *** 2516,2521 **** --- 2514,2520 ---- args.safe_push (def); } vp1->value_id = VN_INFO (result)->value_id; + vp1->type = TREE_TYPE (gimple_phi_result (phi)); vp1->phiargs = args; vp1->block = gimple_bb (phi); vp1->result = result;