https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90363
--- Comment #2 from Stafford Horne <shorne at gcc dot gnu.org> --- (In reply to Segher Boessenkool from comment #1) > Trying 13 -> 14: > 13: r51:QI=[r50:SI+low(`*.LANCHOR0')] > REG_DEAD r50:SI > 14: r43:SI=zero_extend(r51:QI) > REG_DEAD r51:QI > Failed to match this instruction: > (set (reg:SI 43 [ g_doswap.0_2+-3 ]) > (zero_extend:SI (mem/v/c:QI (lo_sum:SI (reg/f:SI 50) > (symbol_ref:SI ("*.LANCHOR0") [flags 0x182])) [0 g_doswap+0 > S1 A8]))) > > The mem arg in that does not match nonimmediate_operand, since it is const. > You want something like reg_or_mem_operand. Yes, thanks sorry, I did investigation a while ago. I forgot to add when I was creating this bug. The issue is that the volatile does not match non immediate_operand. The following patch fixes that: iff --git a/gcc/config/or1k/or1k.md b/gcc/config/or1k/or1k.md index 2dad51cd46b..757d899c442 100644 --- a/gcc/config/or1k/or1k.md +++ b/gcc/config/or1k/or1k.md @@ -328,11 +328,11 @@ ;; Sign Extending ;; ------------------------------------------------------------------------- -;; Zero extension can always be done with AND and an extending load. +;; Zero extension can always be done with AND or an extending load. (define_insn "zero_extend<mode>si2" [(set (match_operand:SI 0 "register_operand" "=r,r") - (zero_extend:SI (match_operand:I12 1 "nonimmediate_operand" "r,m")))] + (zero_extend:SI (match_operand:I12 1 "reg_or_mem_operand" "r,m")))] "" "@ l.andi\t%0, %1, <zext_andi> @@ -344,7 +344,7 @@ (define_insn "extend<mode>si2" [(set (match_operand:SI 0 "register_operand" "=r,r") - (sign_extend:SI (match_operand:I12 1 "nonimmediate_operand" "r,m")))] + (sign_extend:SI (match_operand:I12 1 "reg_or_mem_operand" "r,m")))] "TARGET_SEXT" "@ l.ext<ldst>s\t%0, %1 diff --git a/gcc/config/or1k/predicates.md b/gcc/config/or1k/predicates.md index 879236bca49..b895f1b4228 100644 --- a/gcc/config/or1k/predicates.md +++ b/gcc/config/or1k/predicates.md @@ -82,3 +82,21 @@ (define_predicate "equality_comparison_operator" (match_code "ne,eq")) + +;; Borrowed from rs6000 +; Return true if the operand is in volatile memory. Note that during the +;; RTL generation phase, memory_operand does not return TRUE for volatile +;; memory references. So this function allows us to recognize volatile +;; references where it's safe. +(define_predicate "volatile_mem_operand" + (and (match_code "mem") + (match_test "MEM_VOLATILE_P (op)") + (if_then_else (match_test "reload_completed") + (match_operand 0 "memory_operand") + (match_test "memory_address_p (mode, XEXP (op, 0))")))) + +;; Return true if the operand is a register or memory; including volatile +;; memory. +(define_predicate "reg_or_mem_operand" + (ior (match_operand 0 "nonimmediate_operand") + (match_operand 0 "volatile_mem_operand")))