------- Comment #4 from ebotcazou at gcc dot gnu dot org 2010-09-02 21:59 ------- It's IVOPTS so no way to get a reduced testcase. The analysis is for the stock sem_aggr.adb file compiled at -O2 -gnatpg for IA-64. We have:
table.68_174 = .builtin_alloca (D.5147_173); with pi->align = 16 D.5252_266 = &*table.68_174; with pi->align = 16 and then MEM[(struct sem_aggr__case_bounds[(size_type) <PLACEHOLDER_EXPR struct sem_aggr__case_table_type___XUP>.P_BOUNDS->LB0:<PLACEHOLDER_EXPR struct sem_aggr__case_table_type___XUP>.P_BOUNDS->UB0 >= <PLACEHOLDER_EXPR struct sem_aggr__case_table_type___XUP>.P_BOUNDS->LB0 ? (size_type) <PLACEHOLDER_EXPR struct sem_aggr__case_table_type___XUP>.P_BOUNDS->UB0 : (size_type) <PLACEHOLDER_EXPR struct sem_aggr__case_table_type___XUP>.P_BOUNDS->LB0 + -1] *)D.5252_266][D.6519_896]{lb: 1 sz: 12}; is replaced with MEM[(struct sem_aggr__case_bounds[(size_type) <PLACEHOLDER_EXPR struct sem_aggr__case_table_type___XUP>.P_BOUNDS->LB0:<PLACEHOLDER_EXPR struct sem_aggr__case_table_type___XUP>.P_BOUNDS->UB0 >= <PLACEHOLDER_EXPR struct sem_aggr__case_table_type___XUP>.P_BOUNDS->LB0 ? (size_type) <PLACEHOLDER_EXPR struct sem_aggr__case_table_type___XUP>.P_BOUNDS->UB0 : (size_type) <PLACEHOLDER_EXPR struct sem_aggr__case_table_type___XUP>.P_BOUNDS->LB0 + -1] *)D.6658_890] in IVOPTS. And copy_ref_info reads: /* We can transfer points-to information from an old pointer or decl base to the new one. */ But now duplicate_ssa_name_ptr_info duplicates more than the points-to info, it also duplicates the alignment info, which is wrong for arrays since the base decl (pointed to by D.5252_266) can be more aligned than the individual elements (pointed to by D.6658_890). Tentative patch (I cannot test it on IA-64 before next week): Index: tree-ssa-loop-ivopts.c =================================================================== --- tree-ssa-loop-ivopts.c (revision 163745) +++ tree-ssa-loop-ivopts.c (working copy) @@ -5891,8 +5891,8 @@ copy_ref_info (tree new_ref, tree old_re else if (TREE_CODE (new_ref) == MEM_REF) new_ptr_base = TREE_OPERAND (new_ref, 0); - /* We can transfer points-to information from an old pointer - or decl base to the new one. */ + /* We can transfer points-to information from an old pointer or base decl + to the new one, as well as some amount of alignment information. */ if (new_ptr_base && TREE_CODE (new_ptr_base) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (new_ptr_base)) @@ -5901,11 +5901,18 @@ copy_ref_info (tree new_ref, tree old_re tree base = get_base_address (old_ref); if (!base) ; - else if ((INDIRECT_REF_P (base) - || TREE_CODE (base) == MEM_REF) - && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME) - duplicate_ssa_name_ptr_info - (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))); + else if ((INDIRECT_REF_P (base) || TREE_CODE (base) == MEM_REF) + && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME + && SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))) + { + struct ptr_info_def *pi; + duplicate_ssa_name_ptr_info + (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))); + pi = SSA_NAME_PTR_INFO (new_ptr_base); + pi->misalign + = -(TYPE_ALIGN (TREE_TYPE (new_ref)) / BITS_PER_UNIT) + & (pi->align - 1); + } else if (TREE_CODE (base) == VAR_DECL || TREE_CODE (base) == PARM_DECL || TREE_CODE (base) == RESULT_DECL) -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45421