------- Comment #24 from jamborm at gcc dot gnu dot org 2009-09-21 19:49 ------- OK, so I have finally got to the root of the assert failure in reg-stack.c described in the bug description. The file is indeed miscompiled, and the miscompiled function is VEC_char_base_replace. A very short one:
VEC_char_base_replace (struct VEC_char_base * vec_, unsigned int ix_, char obj_) { char old_obj_; unsigned int D.41028; <bb 2>: old_obj__4 = vec__1(D)->vec[ix__3(D)]; vec__1(D)->vec[ix__3(D)] = obj__5(D); return old_obj__4; } IPA-SRA runs the expression vec__1(D)->vec[ix__3(D)] through get_ref_base_and_extent, which unfortunately returns bogus pmax_size of 8. The aggregate in question is: struct VEC_char_base { unsigned num; unsigned alloc; char vec[1]; }; Obviously the punting condition has failed me (again :-). I have put some dumps into the function (on x86_64) to see why and these are the values after the while loop terminates: -------------------------------------------------- Finished with exp: *vec__1(D) bit_offset: 64, maxsize: 8 seen_variable_array_ref: 1, seen_union: 0 bit_offset + maxsize: 72 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))): 96 ------------------------------------------------------------ Since 72 is not equal to 96, the maxsize is not set to -1 even though it should. It seems that the underlying cause of this is that while the size of the array type (asize) is 8 bits, it is accounted for 32 in the size of the whole aggregate. Whether this is a bug or get_ref_base_and_extent should somehow take alignments into account, I don't know. Thus I'd like to ask Richi and others who know exact meanings of these sizes for advice. Thanks and sorry for the gross inconvenience, it wouldn't have occurred to me that I should do _less_ checking. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41395