I have a port that has: (insn 47 46 48 18 (parallel [ (unspec_volatile:DI [ (const_int 128 [0x80]) (const_int 6 [0x6]) ] UNSPECV_SPECIAL_OP) (set (mem/v:BLK (scratch:DI) [0 A8]) (unspec:BLK [ (mem/v:BLK (scratch:DI) [0 A8]) ] UNSPEC_MEMORY_BARRIER))
The UNSPEC_MEMORY_BARRIER is the usual memory barrier, and the other unspec is a random complex instruction that the optimizer will never have a clue about. I caught lra trying to reload the scratch address into a register and then aborting later as it isn’t a use, a clobber or an asm_input. The code that asserts this is: /* It is a special insn like USE or CLOBBER. We should recognize any regular insn otherwise LRA can do nothing with this insn. */ gcc_assert (GET_CODE (PATTERN (insn)) == USE || GET_CODE (PATTERN (insn)) == CLOBBER || GET_CODE (PATTERN (insn)) == ASM_INPUT); in lra.c I notice that if I put in the below, I can get lra to not do the reload. I get the feeling that I’m missing something from my port someplace else that would have prevented lra from doing this, as we have a ton of ports that have this form of memory barrier. avr nopv is one such instance. [ checking ] Oh, avr is one such port, but, it doesn’t use lra. :-( Hum… So, I guess the question is, is this an lra bug, or a port bug? When I use the avr patterns for nopv on an lra port, the pattern then doesn’t work. diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 382281c..c82aa3f 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -2855,6 +2855,7 @@ process_address_1 (int nop, bool check_only_p, if (! check_only_p) change_p = equiv_address_substitution (&ad); if (ad.base_term != NULL + && GET_CODE (*ad.base_term) != SCRATCH && (process_addr_reg (ad.base_term, check_only_p, before, (ad.autoinc_p @@ -2898,7 +2899,9 @@ process_address_1 (int nop, bool check_only_p, All these cases involve a non-autoinc address, so there is no point revalidating other types. */ - if (ad.autoinc_p || valid_address_p (&ad)) + if (ad.autoinc_p + || (ad.base_term && GET_CODE (*ad.base_term) == SCRATCH) + || valid_address_p (&ad)) return change_p; /* Any index existed before LRA started, so we can assume that the