On Wed, Oct 23, 2019 at 04:42:19PM -0500, Segher Boessenkool wrote: > On Wed, Oct 23, 2019 at 05:00:58PM -0400, Michael Meissner wrote: > > On Tue, Oct 22, 2019 at 05:27:19PM -0500, Segher Boessenkool wrote: > > > On Wed, Oct 16, 2019 at 09:35:33AM -0400, Michael Meissner wrote: > > > > - int n = get_attr_length (insn) / 4; > > > > + /* If the insn tells us how many insns there are, use that. > > > > Otherwise use > > > > + the length/4. Adjust the insn length to remove the extra size > > > > that > > > > + prefixed instructions take. */ > > > > > > This should be temporary, until we have converted everything to use > > > num_insns, right? > > > > Well there were some 200+ places where length was set. > > Yes, and I did volunteer to do this work, if needed / wanted.
So I did this, but it does not work: I end up with out-of-range branches. I rewrote it in a different way: same thing. And again, and again. The fundamental problem is that the "length" attribute is special. It actually is four attributes: insn_current_length (that's the one you expect) insn_variable_length_p (true if the length of this insn depends on the (relative) addresses of any (other) insns) insn_min_length (minimum length: minimum of the alternatives) insn_default_length (which really should be called insn_max_length) which are used in the shorten pass (which actually makes branches *longer* in the normal case). The problem is that these are only computed for static values that are set in the "length" attribute in the machine description, while we actually want to set "length" based on some other attributes ("num_insns", "prefixed", "max_prefixed_insns"), either directly or via adjust_insn_length. The shorten pass (which lenghtens branches, unless -O0) does not notice most insns that can become longer, and eventually we ICE because of an out-of-range branch. Hrm, maybe if I force insn_variable_length_p to "true". Let me try that. Segher