> This patch also completely replaces get_bit_range (which is where > PR52097 ICEs) by a trivial implementation.
How does it short-circuit the decision made by get_best_mode exactly? By making get_bit_range return non-zero in more cases? > There is PR52134 which will make this patch cause 1 gnat regression. This looks rather benign to me. > * gimplify.c (gimplify_expr): Translate bitfield accesses > to BIT_FIELD_REFs of the representative. This part isn't in the patch. > + /* Return a new underlying object for a bitfield started with FIELD. */ > + > + static tree > + start_bitfield_representative (tree field) > + { > + tree repr = make_node (FIELD_DECL); > + DECL_FIELD_OFFSET (repr) = DECL_FIELD_OFFSET (field); > + /* Force the representative to begin at an BITS_PER_UNIT aligned ...at a BITS_PER_UNIT aligned... > + boundary - C++ may use tail-padding of a base object to > + continue packing bits so the bitfield region does not start > + at bit zero (see g++.dg/abi/bitfield5.C for example). > + Unallocated bits may happen for other reasons as well, > + for example Ada which allows explicit bit-granular structure layout. > */ + DECL_FIELD_BIT_OFFSET (repr) > + = size_binop (BIT_AND_EXPR, > + DECL_FIELD_BIT_OFFSET (field), > + bitsize_int (~(BITS_PER_UNIT - 1))); > + SET_DECL_OFFSET_ALIGN (repr, DECL_OFFSET_ALIGN (field)); > + DECL_SIZE (repr) = DECL_SIZE (field); > + DECL_PACKED (repr) = DECL_PACKED (field); > + DECL_CONTEXT (repr) = DECL_CONTEXT (field); > + return repr; Any particular reason to set DECL_SIZE but not DECL_SIZE_UNIT here? They are generally set together. > + > + /* Finish up a bitfield group that was started by creating the underlying > + object REPR with the last fied in the bitfield group FIELD. */ ...the last field... > + /* Round up bitsize to multiples of BITS_PER_UNIT. */ > + bitsize = (bitsize + BITS_PER_UNIT - 1) & ~(BITS_PER_UNIT - 1); > + > + /* Find the smallest nice mode to use. > + ??? Possibly use get_best_mode with appropriate arguments instead > + (which would eventually require splitting representatives here). */ > + for (modesize = bitsize; modesize <= maxbitsize; modesize += > BITS_PER_UNIT) + { > + mode = mode_for_size (modesize, MODE_INT, 1); > + if (mode != BLKmode) > + break; > + } The double loop looks superfluous. Why not re-using the implementation of smallest_mode_for_size? for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) if (GET_MODE_PRECISION (mode) >= bitsize) break; if (mode != VOIDmode && GET_MODE_PRECISION (mode) > maxbitsize) mode = VOIDmode; if (mode == VOIDmode) ... -- Eric Botcazou