diff mbox series

[12/29,arm] Implement negscc using SBC when appropriate.

Message ID 20191018194900.34795-13-Richard.Earnshaw@arm.com
State New
Headers show
Series Rewrite DImode arithmetic support | expand

Commit Message

Richard Earnshaw (lists) Oct. 18, 2019, 7:48 p.m. UTC
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.
---
 gcc/config/arm/arm.md                  | 14 ++++++++++++--
 gcc/config/arm/thumb2.md               |  8 ++++++--
 gcc/testsuite/gcc.target/arm/negdi-3.c |  8 ++++----
 3 files changed, 22 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index f53dbc27207..74f417fbe4b 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -6612,13 +6612,23 @@  (define_insn_and_split "*mov_scc"
    (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)
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 6ccc875e2b4..8d0b6be9205 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -368,7 +368,9 @@  (define_insn_and_split "*thumb2_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_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)
@@ -387,7 +389,9 @@  (define_insn_and_split "*thumb2_mov_negscc_strict_it"
   [(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)
diff --git a/gcc/testsuite/gcc.target/arm/negdi-3.c b/gcc/testsuite/gcc.target/arm/negdi-3.c
index 3f6f2d1c2bb..76ddf49fc0d 100644
--- a/gcc/testsuite/gcc.target/arm/negdi-3.c
+++ b/gcc/testsuite/gcc.target/arm/negdi-3.c
@@ -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 } } */