[PATCH 4/5][Arm] New pattern for CSNEG instructions
authorSudi Das <sudi.das@arm.com>
Fri, 18 Sep 2020 15:31:12 +0000 (16:31 +0100)
committerOmar Tahir <omar.tahir@arm.com>
Fri, 18 Sep 2020 16:05:05 +0000 (17:05 +0100)
This patch adds a new pattern, *thumb2_csneg, for generating CSNEG
instructions. It also restricts *if_neg_move and *thumb2_negscc to only match
if !TARGET_COND_ARITH which prevents undesirable matches during ifcvt.

gcc/ChangeLog:

* config/arm/thumb2.md (*thumb2_csneg): New.
(*thumb2_negscc): Don't match if TARGET_COND_ARITH.
* config/arm/arm.md (*if_neg_move): Don't match if TARGET_COND_ARITH.

gcc/testsuite/ChangeLog:

* gcc.target/arm/csneg.c: New test.

Co-authored-by: Omar Tahir <omar.tahir@arm.com>
gcc/config/arm/arm.md
gcc/config/arm/thumb2.md
gcc/testsuite/gcc.target/arm/csneg.c [new file with mode: 0644]

index dd13c77e889a3d8b9c31dabdaf50cafbf63196f4..bffdb0b3987f640491fb798ff97503451a74f299 100644 (file)
          [(match_operand 3 "cc_register" "") (const_int 0)])
         (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
         (match_operand:SI 1 "s_register_operand" "0,0")))]
-  "TARGET_32BIT"
+  "TARGET_32BIT && !TARGET_COND_ARITH"
   "#"
   "&& reload_completed"
   [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
index 0ff5a537f8f3bce3120c2598acaf46fd968bfbd2..2a8fdf24c535e311a78bbb1c576e80d4a88eebd6 100644 (file)
                 [(match_operand:SI 1 "s_register_operand" "r")
                  (match_operand:SI 2 "arm_rhs_operand" "rI")])))
    (clobber (reg:CC CC_REGNUM))]
-  "TARGET_THUMB2"
+  "TARGET_THUMB2 && !TARGET_COND_ARITH"
   "#"
   "&& reload_completed"
   [(const_int 0)]
    (set_attr "predicable" "no")]
 )
 
+(define_insn "*thumb2_csneg"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "=r, r")
+        (if_then_else:SI
+         (match_operand 1 "arm_comparison_operation" "")
+         (neg:SI (match_operand:SI 2 "arm_general_register_operand" "r, r"))
+         (match_operand:SI 3 "reg_or_zero_operand" "r, Pz")))]
+  "TARGET_COND_ARITH"
+  "@
+   csneg\\t%0, %3, %2, %D1
+   csneg\\t%0, zr, %2, %D1"
+  [(set_attr "type" "csel")
+   (set_attr "predicable" "no")]
+)
+
 (define_insn "*thumb2_movcond"
   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts")
        (if_then_else:SI
diff --git a/gcc/testsuite/gcc.target/arm/csneg.c b/gcc/testsuite/gcc.target/arm/csneg.c
new file mode 100644 (file)
index 0000000..e486062
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8_1m_main_ok } */
+/* { dg-options "-O2 -march=armv8.1-m.main" } */
+
+int
+test_csneg32_condasn1(int w0, int w1, int w2, int w3)
+{
+  int w4;
+
+  /* { dg-final { scan-assembler "csneg\tr\[0-9\]*.*ne" } } */
+  w4 = (w0 == w1) ? -w2 : w3;
+  return w4;
+}
+
+int
+test_csneg32_condasn2(int w0, int w1, int w2, int w3)
+{
+  int w4;
+
+  /* { dg-final { scan-assembler "csneg\tr\[0-9\]*.*eq" } } */
+  w4 = (w0 == w1) ? w3 : -w2;
+  return w4;
+}
+
+unsigned long long
+test_csneg_uxtw (unsigned int a, unsigned int b, unsigned int c)
+{
+  unsigned int val;
+
+  /* { dg-final { scan-assembler "csneg\tr\[0-9\]*.*ne" } } */
+  val = a ? b : -c;
+  return val;
+}