[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 91b80e5..4d2812a 100644 (file)
@@ -1,5 +1,12 @@
 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.
        (TARGET_INSN_COST): Override default definition.
 
index f53dbc2..74f417f 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 6ccc875..8d0b6be 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 ae9d216..d5d934d 100644 (file)
@@ -1,5 +1,9 @@
 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.
        * gcc.target/arm/pr53447-3.c: Remove XFAIL.
        * gcc.target/arm/pr53447-4.c: Remove XFAIL.
index 3f6f2d1..76ddf49 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 } } */