On 18/09/2019 20:55, Wilco Dijkstra wrote:
Hi Kyrill,

We should be able to "compress" the above 3 patterns into one using code
iterators.

Good point, that makes sense. I've committed this:

ChangeLog:
2019-09-18  Wilco Dijkstra  <wdijk...@arm.com>

        PR target/91738
        * config/arm/arm.md (<logical_op>di3): Expand explicitly.
        (one_cmpldi2): Likewise.
        * config/arm/arm.c (const_ok_for_dimode_op): Return true if one
        of the constant parts is simple.
        * config/arm/iterators.md (LOGICAL): Add new code iterator.
        (logical_op): Add new code attribute.
        (logical_OP): Likewise.
        * config/arm/predicates.md (arm_anddi_operand): Add predicate.
        (arm_iordi_operand): Add predicate.
        (arm_xordi_operand): Add predicate.

except we can do better than this...



--
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 
173e6363682c35aa72a9fa36c14b6324b59e347b..1fc90c62798978ea5abddb11fbf1d7acbc8a8dc3
 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -4273,8 +4273,8 @@ const_ok_for_dimode_op (HOST_WIDE_INT i, enum rtx_code 
code)
      case AND:
      case IOR:
      case XOR:
-      return (const_ok_for_op (hi_val, code) || hi_val == 0xFFFFFFFF)
-              && (const_ok_for_op (lo_val, code) || lo_val == 0xFFFFFFFF);
+      return const_ok_for_op (hi_val, code) || hi_val == 0xFFFFFFFF
+            || const_ok_for_op (lo_val, code) || lo_val == 0xFFFFFFFF;
      case PLUS:
        return arm_not_operand (hi, SImode) && arm_add_operand (lo, SImode);
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 
e23683114087f6cc9ee78376529da97cfe31d3a6..3943c4252b272d30f88f265e90ebc4cb88e3a615
 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -2176,6 +2176,49 @@ (define_expand "divdf3"
    "")
  
+; Expand logical operations. The mid-end expander does not split off memory
+; operands or complex immediates, which leads to fewer LDRD/STRD instructions.
+; So an explicit expander is needed to generate better code.
+
+(define_expand "<logical_op>di3"

(see below).  With that change, this just becomes <LOGICAL:optab>di3

+  [(set (match_operand:DI        0 "s_register_operand")
+       (LOGICAL:DI (match_operand:DI 1 "s_register_operand")
+                   (match_operand:DI 2 "arm_<logical_op>di_operand")))]
+  "TARGET_32BIT"
+  {
+      rtx low  = simplify_gen_binary (<logical_OP>, SImode,
+                                     gen_lowpart (SImode, operands[1]),
+                                     gen_lowpart (SImode, operands[2]));
+      rtx high = simplify_gen_binary (<logical_OP>, SImode,
+                                     gen_highpart (SImode, operands[1]),
+                                     gen_highpart_mode (SImode, DImode,
+                                                        operands[2]));
+
+      emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
+      emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
+      DONE;
+  }
+)
+
+(define_expand "one_cmpldi2"
+  [(set (match_operand:DI 0 "s_register_operand")
+       (not:DI (match_operand:DI 1 "s_register_operand")))]
+  "TARGET_32BIT"
+  {
+      rtx low  = simplify_gen_unary (NOT, SImode,
+                                    gen_lowpart (SImode, operands[1]),
+                                    SImode);
+      rtx high = simplify_gen_unary (NOT, SImode,
+                                    gen_highpart_mode (SImode, DImode,
+                                                       operands[1]),
+                                    SImode);
+
+      emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
+      emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
+      DONE;
+  }
+)
+
  ;; Split DImode and, ior, xor operations.  Simply perform the logical
  ;; operation on the upper and lower halves of the registers.
  ;; This is needed for atomic operations in arm_split_atomic_op.
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index 
fa6f0c0529d5364b1e1df705cb1029868578e38c..20fd96cb0445fcdf821c7c72f2dd30bae8590d0c
 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -239,6 +239,8 @@ (define_code_iterator COMPARISONS [eq gt ge le lt])
  ;; A list of ...
  (define_code_iterator IOR_XOR [ior xor])
+(define_code_iterator LOGICAL [and ior xor])
+
  ;; Operations on two halves of a quadword vector.
  (define_code_iterator VQH_OPS [plus smin smax umin umax])
@@ -285,6 +287,9 @@ (define_code_attr cmp_type [(eq "i") (gt "s") (ge "s") (lt "s") (le "s")]) (define_code_attr vfml_op [(plus "a") (minus "s")]) +(define_code_attr logical_op [(ior "ior") (xor "xor") (and "and")])

These should just be added to the existing 'optab' attribute, there's no need for an additional attribute.

+(define_code_attr logical_OP [(ior "IOR") (xor "XOR") (and "AND")])

You don't need this, just use <CODE> where you want this substitution.

+
  ;;----------------------------------------------------------------------------
  ;; Int iterators
  ;;----------------------------------------------------------------------------
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 
983faac8a72ef75e80cc34031c07c6435902c36f..8b36e7ee462235ad26e132f1ccf98d28c2487d67
 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -206,6 +206,21 @@ (define_predicate "arm_adddi_operand"
         (and (match_code "const_int")
            (match_test "const_ok_for_dimode_op (INTVAL (op), PLUS)"))))
+(define_predicate "arm_anddi_operand"
+  (ior (match_operand 0 "s_register_operand")
+       (and (match_code "const_int")
+           (match_test "const_ok_for_dimode_op (INTVAL (op), AND)"))))
+
+(define_predicate "arm_iordi_operand"
+  (ior (match_operand 0 "s_register_operand")
+       (and (match_code "const_int")
+           (match_test "const_ok_for_dimode_op (INTVAL (op), IOR)"))))
+
+(define_predicate "arm_xordi_operand"
+  (ior (match_operand 0 "s_register_operand")
+       (and (match_code "const_int")
+           (match_test "const_ok_for_dimode_op (INTVAL (op), XOR)"))))
+
  (define_predicate "arm_addimm_operand"
    (ior (match_operand 0 "arm_immediate_operand")
         (match_operand 0 "arm_neg_immediate_operand")))



R.

Reply via email to