[arm] Implement negscc using SBC when appropriate.
authorRichard Earnshaw <rearnsha@arm.com>
Fri, 18 Oct 2019 19:03:11 +0000 (19:03 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Fri, 18 Oct 2019 19:03:11 +0000 (19:03 +0000)
When the carry flag is appropriately set by a comprison, negscc
patterns can expand into a simple SBC of a register with itself.  This
means we can convert two conditional instructions into a single
non-conditional instruction.  Furthermore, in Thumb2 we can avoid the
need for an IT instruction as well.  This patch also fixes the remaining
testcase that we initially XFAILed in the first patch of this series.

gcc:
* config/arm/arm.md (negscc_borrow): New pattern.
(mov_negscc): Don't split if the insn would match negscc_borrow.
* config/arm/thumb2.md (thumb2_mov_negscc): Likewise.
(thumb2_mov_negscc_strict_it): Likewise.

testsuite:
* gcc.target/arm/negdi-3.c: Remove XFAIL markers.

From-SVN: r277175

gcc/ChangeLog
gcc/config/arm/arm.md
gcc/config/arm/thumb2.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/negdi-3.c

index 91b80e52f504d704654ddf27db08d0ff74fcbd4e..4d2812a08937cc8b2758135987be17d8aa9ed5f3 100644 (file)
@@ -1,3 +1,10 @@
+2019-10-18  Richard Earnshaw  <rearnsha@arm.com>
+
+       * config/arm/arm.md (negscc_borrow): New pattern.
+       (mov_negscc): Don't split if the insn would match negscc_borrow.
+       * config/arm/thumb2.md (thumb2_mov_negscc): Likewise.
+       (thumb2_mov_negscc_strict_it): Likewise.
+
 2019-10-18  Richard Earnshaw  <rearnsha@arm.com>
 
        * config/arm/arm.c (arm_insn_cost): New function.
index f53dbc27207c6d6736fb72b709e046ddc7ed12d5..74f417fbe4b20d390251e70acdeb0a08c6187745 100644 (file)
    (set_attr "type" "multiple")]
 )
 
+(define_insn "*negscc_borrow"
+  [(set (match_operand:SI 0 "s_register_operand" "=r")
+       (neg:SI (match_operand:SI 1 "arm_borrow_operation" "")))]
+  "TARGET_32BIT"
+  "sbc\\t%0, %0, %0"
+  [(set_attr "conds" "use")
+   (set_attr "length" "4")
+   (set_attr "type" "adc_reg")]
+)
+
 (define_insn_and_split "*mov_negscc"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
        (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
                 [(match_operand 2 "cc_register" "") (const_int 0)])))]
-  "TARGET_ARM"
+  "TARGET_ARM && !arm_borrow_operation (operands[1], SImode)"
   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
-  "TARGET_ARM"
+  "&& true"
   [(set (match_dup 0)
         (if_then_else:SI (match_dup 1)
                          (match_dup 3)
index 6ccc875e2b4e7b8ce256e52da966dfe220c6f5d6..8d0b6be920518e891c1d3a88274b70395a44a124 100644 (file)
   [(set (match_operand:SI 0 "s_register_operand" "=r")
        (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
                 [(match_operand 2 "cc_register" "") (const_int 0)])))]
-  "TARGET_THUMB2 && !arm_restrict_it"
+  "TARGET_THUMB2
+   && !arm_restrict_it
+   && !arm_borrow_operation (operands[1], SImode)"
   "#"   ; "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
   "&& true"
   [(set (match_dup 0)
   [(set (match_operand:SI 0 "low_register_operand" "=l")
        (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
                 [(match_operand 2 "cc_register" "") (const_int 0)])))]
-  "TARGET_THUMB2 && arm_restrict_it"
+  "TARGET_THUMB2
+   && arm_restrict_it
+   && !arm_borrow_operation (operands[1], SImode)"
   "#"   ; ";mvn\\t%0, #0 ;it\\t%D1\;mov%D1\\t%0, #0\"
   "&& reload_completed"
   [(set (match_dup 0)
index ae9d216e1e3d88345400a1fb22a22c7b9e979467..d5d934d1b8623593b4b776b631006d8298a953c9 100644 (file)
@@ -1,3 +1,7 @@
+2019-10-18  Richard Earnshaw  <rearnsha@arm.com>
+
+       * gcc.target/arm/negdi-3.c: Remove XFAIL markers.
+
 2019-10-18  Richard Earnshaw  <rearnsha@arm.com>
 
        * gcc.target/arm/pr53447-1.c: Remove XFAIL.
index 3f6f2d1c2bb640d7a6bbddd41210511dbcdddbcc..76ddf49fc0ddb8b0287b8e30f72962ea25d12438 100644 (file)
@@ -11,7 +11,7 @@ Expected output:
         rsbs    r0, r0, #0
         sbc     r1, r1, r1
 */
-/* { dg-final { scan-assembler-times "rsb" 1 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "sbc" 1 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "mov" 0 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "rsc" 0 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "rsb" 1 } } */
+/* { dg-final { scan-assembler-times "sbc" 1 } } */
+/* { dg-final { scan-assembler-times "mov" 0 } } */
+/* { dg-final { scan-assembler-times "rsc" 0 } } */