https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114741
Tamar Christina <tnfchris at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |tnfchris at gcc dot gnu.org, | |vmakarov at gcc dot gnu.org --- Comment #5 from Tamar Christina <tnfchris at gcc dot gnu.org> --- (In reply to Andrew Pinski from comment #4) > (In reply to Wilco from comment #2) > > It looks like the underlying bug is '^' being incorrectly treated like '?' > > in record_reg_classes (which is never used during reload). Fixing that > > results in the expected code being generated in all cases. It looks this > > issue was introduced in the original commit > > d1457701461d5a49ca6b5d8a6d1c83a37a6dc771 > > static const struct cpu_regmove_cost generic_armv9_a_regmove_cost = > { > 1, /* GP2GP */ > /* Spilling to int<->fp instead of memory is recommended so set > realistic costs compared to memmov_cost. */ > 3, /* GP2FP */ > 2, /* FP2GP */ > 2 /* FP2FP */ > }; > > > Note these costs are broken. > TARGET_REGISTER_MOVE_COST has this to say about the special value 2: > ``` > If reload sees an insn consisting of a single set between two hard > registers, and if TARGET_REGISTER_MOVE_COST applied to their classes returns > a value of 2, reload does not check to ensure that the constraints of the > insn are met. Setting a cost of other than 2 will allow reload to verify > that the constraints are met. You should do this if the ‘movm’ pattern’s > constraints do not allow such copying. > ``` > > The way I implemented this for thunderx was have GP2GP being cost of 2 and > then be relative from there. That gave better code generation in general and > even less spilling. I know I wrote about this before too. I don't think this is related to this at all the old generic costs, which armv8 was taken from doesn't use 2, and is broken https://github.com/gcc-mirror/gcc/blob/master/gcc/config/aarch64/tuning_models/generic.h#L42 generic-armv8-a doesn't use 2 and is broken https://github.com/gcc-mirror/gcc/blob/master/gcc/config/aarch64/tuning_models/generic_armv8_a.h#L43 neoverse-n2 uses 2 and isn't broken https://github.com/gcc-mirror/gcc/blob/master/gcc/config/aarch64/tuning_models/neoversen2.h I think the issue is what Wilco mentioned before. The GCC docs claim that ^ shouldn't affect initial costing/IRA, but it clearly does. it's penalizing the r->r alternative during initial costing and not just during lra if a reload is needed. so the question to Vlad is it correct that ^ is treated the same way as ? during initial costing? i.e. it's penalizing the alternative.