Quoting Ilya Enkovich <enkovich....@gmail.com>:
Hi, I'm fighting with mode switching (to be more precise with create_pre_exit function) trying to make it work for MPX. I saw create_pre_exit had some stability issues before and now I'm facing similar issues trying to have it working when bound register is returned by function in addition to GPR. The more I look into create_pre_exit code, the more I think it makes some assumptions which are wrong. Also it is very sensitive to the code structure and simple changes in exit block crashes pre-exit block creation. And in some cases it seems to me function does not fail by accident.
Basically, create_pre_exit is paranoid about values being returned in likely spilled registers, and/or the return value copy depending on a mode switch. This makes sense for the SH (integer/struct values are returned in r0 - is likely spilled; floating point return in fr0/dr0 / more or less mode switched), but I'm not aware that it makes sense for other mode switched architectures. Well, maybe x86/ia_64, it's got a likely spilled return register, and does MPX make the copies mode switched?
There is an additional hard reg used for returned value and now returned value is stored in non subsequent registers. I think that to successfully cover all cases here, function_value target hook should be used to determine returned hard regs, rather than use the last 'use' insn to determine required hard regs. Does it sound reasonable?
Yes. While it used to be the case that mode switching was only done for targets that returned values in a single locations, your post shows we can no longer make this assumption. I suppose we could also avoid a lot of useless processing if we just don't worry about return value copies as such (i.e. having to stay last as much as possible) if the return register(s) is/are not likely spilled. In that case, we could really handle the pre-exit block like any other block.