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")))

Reply via email to