or1k: Fix code quality for volatile memory loads
authorStafford Horne <shorne@gmail.com>
Sun, 21 Jul 2019 20:58:54 +0000 (20:58 +0000)
committerStafford Horne <shorne@gcc.gnu.org>
Sun, 21 Jul 2019 20:58:54 +0000 (20:58 +0000)
Volatile memory does not match the memory_operand predicate.  This
causes extra extend/mask instructions instructions when reading
from volatile memory.  On OpenRISC loading volatile memory can be
treated the same as regular memory loads which supports combined
sign/zero extends.  Fixing this eliminates the need for extra
extend/mask instructions.

This also adds a test provided by Richard Selvaggi which uncovered the
issue while we were looking into another issue.

gcc/ChangeLog:

PR target/90363
* config/or1k/or1k.md (zero_extend<mode>si2): Update predicate.
(extend<mode>si2): Update predicate.
* gcc/config/or1k/predicates.md (volatile_mem_operand): New.
(reg_or_mem_operand): New.

gcc/testsuite/ChangeLog:

PR target/90363
* gcc.target/or1k/swap-1.c: New test.
* gcc.target/or1k/swap-2.c: New test.

From-SVN: r273647

gcc/ChangeLog
gcc/config/or1k/or1k.md
gcc/config/or1k/predicates.md
gcc/testsuite/ChangeLog

index 7f070e87f27061ca1e78ae65270348117527540e..59e11bccfbd5c1b5fc105317790fe894d5d9e6d5 100644 (file)
@@ -1,3 +1,11 @@
+2019-07-22  Stafford Horne  <shorne@gmail.com>
+
+       PR target/90363
+       * config/or1k/or1k.md (zero_extend<mode>si2): Update predicate.
+       (extend<mode>si2): Update predicate.
+       * gcc/config/or1k/predicates.md (volatile_mem_operand): New.
+       (reg_or_mem_operand): New.
+
 2019-07-21  Iain Sandoe  <iain@sandoe.co.uk>
 
        * config/rs6000/rs6000.c (TARGET_NO_PROTOTYPE): Move from here...
index 2dad51cd46beef5de288c21819bd7feab5744a74..757d899c44239f93c173afa648d977792903a143 100644 (file)
 ;; 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>
 
 (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
index 879236bca49a6c8cf952ed122a143007779eb0c8..dad1c5d4be302cab3a7a70be3e8b17e5a85e5911 100644 (file)
 
 (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")))
index fc9b4c8d24fa067cfb2d0562e931e7b378d5bfad..95e73d9fa482fb8d25cbe1d050e24046a7a709bf 100644 (file)
@@ -1,3 +1,9 @@
+2019-07-22  Stafford Horne  <shorne@gmail.com>
+
+       PR target/90363
+       * gcc.target/or1k/swap-1.c: New test.
+       * gcc.target/or1k/swap-2.c: New test.
+
 2019-07-20  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * gcc.target/powerpc/volatile-mem.c: New testcase.