This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[AArch64 11/14] Optimize and(s) patterns for HI/QI operands.


HImode and QImode operands can be handled in a more optimal way for
logical AND than for logical OR operations. An AND will never set
bits that are not already set in its operands, so the resulting
mode/precision depends on the least precision of its operands with
an implicit zero-extension to any larger precision.

These patterns help to avoid unnecessary zero-extension operations
on benchmarks, including some SPEC workloads.
---
 gcc/config/aarch64/aarch64.md   | 62 ++++++++++++++++++++++++++++++++++++++---
 gcc/config/aarch64/iterators.md |  2 ++
 2 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index b6453b6..6feedd3 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -2551,8 +2551,8 @@
 
 (define_insn "<optab><mode>3"
   [(set (match_operand:GPI 0 "register_operand" "=r,rk")
-	(LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
-		     (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
+	(OR:GPI (match_operand:GPI 1 "register_operand" "%r,r")
+		(match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
   ""
   "<logical>\\t%<w>0, %<w>1, %<w>2"
   [(set_attr "type" "logic_reg,logic_imm")]
@@ -2569,6 +2569,27 @@
   [(set_attr "type" "logic_reg,logic_imm")]
 )
 
+;; specialized form of AND for HI and QI
+(define_insn "and<mode>3"
+  [(set (match_operand:ALLI 0 "register_operand" "=r,rk")
+        (and:ALLI (match_operand:ALLI 1 "register_operand" "%r,r")
+                  (match_operand:ALLI 2 "aarch64_logical_operand" "r,<andconst>")))]
+  ""
+  "and\\t%<w>0, %<w>1, %<w>2"
+  [(set_attr "type" "logic_reg,logic_imm")]
+)
+
+;; zero_extend version of above
+(define_insn "*and<mode>3_zeroextend"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+        (zero_extend:GPI
+          (and:ALLX (match_operand:ALLX 1 "register_operand" "r")
+                    (match_operand:ALLX 2 "const_int_operand" "<andconst>"))))]
+  ""
+  "and\\t%w0, %w1, %w2"
+  [(set_attr "type" "logic_imm")]
+)
+
 (define_insn "*and<mode>3_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
@@ -2582,12 +2603,28 @@
   [(set_attr "type" "logics_reg,logics_imm")]
 )
 
+;; special variant for HI and QI operators (implicitly zero-extending)
+(define_insn "*and<mode>3_compare0"
+  [(set (reg:CC_NZ CC_REGNUM)
+        (compare:CC_NZ
+                (and:GPI (match_operand:SHORT 1 "register_operand" "%r,r")
+                         (match_operand:SHORT 2 "aarch64_logical_operand" "r,<andconst>"))
+                (const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r,r")
+        (and:GPI (match_dup 1) (match_dup 2)))]
+  ""
+  "@
+   ands\\t%<w>0, %<w>1, %<w>2
+   ands\\t%<w>0, %<w>1, %2"
+  [(set_attr "type" "logic_reg,logic_imm")]
+)
+
 ;; zero_extend version of above
 (define_insn "*andsi3_compare0_uxtw"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
-	 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
-		 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
+	 (and:SI (match_operand:ALLX 1 "register_operand" "%r,r")
+		 (match_operand:ALLX 2 "aarch64_logical_operand" "r,K"))
 	 (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r,r")
 	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
@@ -2628,6 +2665,23 @@
   [(set_attr "type" "logics_shift_imm")]
 )
 
+;; specialized form for bitfield tests
+(define_insn "*ands<mode>3_zeroextract_internal2"
+  [(set (reg:CC_NZ CC_REGNUM)
+        (compare:CC_NZ
+         (zero_extract:GPI (match_operand:GPI 0 "register_operand" "r")
+                           (match_operand 1 "const_int_operand" "n")
+                           (match_operand 2 "const_int_operand" "n"))
+         (const_int 0)))]
+  "aarch64_bitmask_imm((((HOST_WIDE_INT)1 << (UINTVAL(operands[1]))) - 1) << UINTVAL(operands[2]), <MODE>mode)"
+  "*
+  {
+    operands[3] = GEN_INT((((HOST_WIDE_INT)1 << (UINTVAL(operands[1]))) - 1) << UINTVAL(operands[2]));
+    return \"ands\\t<w>zr, %<w>0, %<w>3\";
+  }"
+  [(set_attr "type" "logics_reg")]
+)
+
 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
   [(set (match_operand:GPI 0 "register_operand" "=r")
 	(LOGICAL:GPI (SHIFT:GPI
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index f1339b8..edba829 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -341,6 +341,7 @@
 
 ;; Attribute to describe constants acceptable in logical operations
 (define_mode_attr lconst [(SI "K") (DI "L")])
+(define_mode_attr andconst [(QI "K") (HI "K") (SI "K") (DI "L")])
 
 ;; Map a mode to a specific constraint character.
 (define_mode_attr cmode [(QI "q") (HI "h") (SI "s") (DI "d")])
@@ -627,6 +628,7 @@
 
 ;; Code iterator for logical operations
 (define_code_iterator LOGICAL [and ior xor])
+(define_code_iterator OR [ior xor])
 
 ;; Code iterator for sign/zero extension
 (define_code_iterator ANY_EXTEND [sign_extend zero_extend])
-- 
1.9.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]