[arm] Rip out DImode addition and subtraction splits.
authorRichard Earnshaw <rearnsha@arm.com>
Fri, 18 Oct 2019 19:01:40 +0000 (19:01 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Fri, 18 Oct 2019 19:01:40 +0000 (19:01 +0000)
The first step towards early splitting of addition and subtraction at
DImode is to rip out the old patterns that are designed to propagate
DImode through the RTL optimization passes and the do late splitting.

This patch does cause some code size regressions, but it should still
execute correctly.  We will progressively add back the optimizations
we had here in later patches.

A small number of tests in the Arm-specific testsuite do fail as a
result of this patch, but that's to be expected, since the
optimizations they are looking for have just been removed.  I've kept
the tests, but XFAILed them for now.

One small technical change is also done in this patch as part of the
cleanup: the uaddv<mode>4 expander is changed to use LTU as the branch
comparison.  This eliminates the need for CC_Cmode to recognize
somewhat bogus equality constraints.

gcc:
* arm.md (adddi3): Only accept register operands.
(arm_adddi3): Convert to simple insn with no split.  Do not accept
constants.
(adddi_sesidi_di): Delete patern.
(adddi_zesidi_di): Likewise.
(uaddv<mode>4): Use LTU as condition for branch.
(adddi3_compareV): Convert to simple insn with no split.
(addsi3_compareV_upper): Delete pattern.
(adddi3_compareC): Convert to simple insn with no split.  Correct
flags setting expression.
(addsi3_compareC_upper): Delete pattern.
(addsi3_compareC): Correct flags setting expression.
(subdi3_compare1): Convert to simple insn with no split.
(subsi3_carryin_compare): Delete pattern.
(arm_subdi3): Convert to simple insn with no split.
(subdi_zesidi): Delete pattern.
(subdi_di_sesidi): Delete pattern.
(subdi_zesidi_di): Delete pattern.
(subdi_sesidi_di): Delete pattern.
(subdi_zesidi_zesidi): Delete pattern.
(negvdi3): Use s_register_operand.
(negdi2_compare): Convert to simple insn with no split.
(negdi2_insn): Likewise.
(negsi2_carryin_compare): Delete pattern.
(negdi_zero_extendsidi): Delete pattern.
(arm_cmpdi_insn): Convert to simple insn with no split.
(negdi2): Don't call gen_negdi2_neon.
* config/arm/neon.md (adddi3_neon): Delete pattern.
(subdi3_neon): Delete pattern.
(negdi2_neon): Delete pattern.
(splits for negdi2_neon): Delete splits.

testsuite:
* gcc.target/arm/negdi-3.c: Add XFAILS.
* gcc.target/arm/pr3447-1.c: Likewise.
* gcc.target/arm/pr3447-3.c: Likewise.
* gcc.target/arm/pr3447-4.c: Likewise.

From-SVN: r277164

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/negdi-3.c
gcc/testsuite/gcc.target/arm/pr53447-1.c
gcc/testsuite/gcc.target/arm/pr53447-3.c
gcc/testsuite/gcc.target/arm/pr53447-4.c

index 724ce8e..05ae1ea 100644 (file)
@@ -1,3 +1,37 @@
+2019-10-18  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm.md (adddi3): Only accept register operands.
+       (arm_adddi3): Convert to simple insn with no split.  Do not accept
+       constants.
+       (adddi_sesidi_di): Delete patern.
+       (adddi_zesidi_di): Likewise.
+       (uaddv<mode>4): Use LTU as condition for branch.
+       (adddi3_compareV): Convert to simple insn with no split.
+       (addsi3_compareV_upper): Delete pattern.
+       (adddi3_compareC): Convert to simple insn with no split.  Correct
+       flags setting expression.
+       (addsi3_compareC_upper): Delete pattern.
+       (addsi3_compareC): Correct flags setting expression.
+       (subdi3_compare1): Convert to simple insn with no split.
+       (subsi3_carryin_compare): Delete pattern.
+       (arm_subdi3): Convert to simple insn with no split.
+       (subdi_zesidi): Delete pattern.
+       (subdi_di_sesidi): Delete pattern.
+       (subdi_zesidi_di): Delete pattern.
+       (subdi_sesidi_di): Delete pattern.
+       (subdi_zesidi_zesidi): Delete pattern.
+       (negvdi3): Use s_register_operand.
+       (negdi2_compare): Convert to simple insn with no split.
+       (negdi2_insn): Likewise.
+       (negsi2_carryin_compare): Delete pattern.
+       (negdi_zero_extendsidi): Delete pattern.
+       (arm_cmpdi_insn): Convert to simple insn with no split.
+       (negdi2): Don't call gen_negdi2_neon.
+       * config/arm/neon.md (adddi3_neon): Delete pattern.
+       (subdi3_neon): Delete pattern.
+       (negdi2_neon): Delete pattern.
+       (splits for negdi2_neon): Delete splits.
+
 2019-10-18  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/92153
index 3bf8cd6..e8ec426 100644 (file)
@@ -23581,8 +23581,6 @@ maybe_get_arm_condition_code (rtx comparison)
        {
        case LTU: return ARM_CS;
        case GEU: return ARM_CC;
-       case NE: return ARM_CS;
-       case EQ: return ARM_CC;
        default: return ARM_NV;
        }
 
index f861c72..241ba97 100644 (file)
  [(parallel
    [(set (match_operand:DI           0 "s_register_operand")
          (plus:DI (match_operand:DI 1 "s_register_operand")
-                  (match_operand:DI 2 "arm_adddi_operand")))
+                  (match_operand:DI 2 "s_register_operand")))
     (clobber (reg:CC CC_REGNUM))])]
   "TARGET_EITHER"
   "
   "
 )
 
-(define_insn_and_split "*arm_adddi3"
-  [(set (match_operand:DI          0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
-       (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
-                (match_operand:DI 2 "arm_general_adddi_operand"    "r,  0, r, Dd, Dd")))
+(define_insn "*arm_adddi3"
+  [(set (match_operand:DI 0 "s_register_operand"  "=&r,&r,&r")
+       (plus:DI (match_operand:DI 1 "s_register_operand" " %0,0,r")
+                (match_operand:DI 2 "s_register_operand" " r,0,r")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_32BIT"
-  "#"
-  "TARGET_32BIT"
-  [(parallel [(set (reg:CC_C CC_REGNUM)
-                  (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
-                                (match_dup 1)))
-             (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
-   (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
-                              (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
-  "
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[4] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
-    operands[2] = gen_lowpart (SImode, operands[2]);
-  }"
-  [(set_attr "conds" "clob")
-   (set_attr "length" "8")
-   (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*adddi_sesidi_di"
-  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
-       (plus:DI (sign_extend:DI
-                 (match_operand:SI 2 "s_register_operand" "r,r"))
-                (match_operand:DI 1 "s_register_operand" "0,r")))
-   (clobber (reg:CC CC_REGNUM))]
-  "TARGET_32BIT"
-  "#"
-  "TARGET_32BIT && reload_completed"
-  [(parallel [(set (reg:CC_C CC_REGNUM)
-                  (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
-                                (match_dup 1)))
-             (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
-   (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
-                                                    (const_int 31))
-                                       (match_dup 4))
-                              (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
-  "
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[4] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[2] = gen_lowpart (SImode, operands[2]);
-  }"
-  [(set_attr "conds" "clob")
-   (set_attr "length" "8")
-   (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*adddi_zesidi_di"
-  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
-       (plus:DI (zero_extend:DI
-                 (match_operand:SI 2 "s_register_operand" "r,r"))
-                (match_operand:DI 1 "s_register_operand" "0,r")))
-   (clobber (reg:CC CC_REGNUM))]
-  "TARGET_32BIT"
-  "#"
-  "TARGET_32BIT && reload_completed"
-  [(parallel [(set (reg:CC_C CC_REGNUM)
-                  (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
-                                (match_dup 1)))
-             (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
-   (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
-                              (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
-  "
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[4] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[2] = gen_lowpart (SImode, operands[2]);
-  }"
+  "adds\\t%Q0, %Q1, %Q2;adc\\t%R0, %R1, %R2"
   [(set_attr "conds" "clob")
    (set_attr "length" "8")
    (set_attr "type" "multiple")]
   "TARGET_32BIT"
 {
   emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
-  arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
+  arm_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]);
 
   DONE;
 })
  ]
 )
 
-(define_insn_and_split "adddi3_compareV"
+(define_insn "adddi3_compareV"
   [(set (reg:CC_V CC_REGNUM)
        (ne:CC_V
          (plus:TI
-           (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
-           (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
+           (sign_extend:TI (match_operand:DI 1 "s_register_operand" "r"))
+           (sign_extend:TI (match_operand:DI 2 "s_register_operand" "r")))
          (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
-   (set (match_operand:DI 0 "register_operand" "=&r")
+   (set (match_operand:DI 0 "s_register_operand" "=&r")
        (plus:DI (match_dup 1) (match_dup 2)))]
   "TARGET_32BIT"
-  "#"
-  "&& reload_completed"
-  [(parallel [(set (reg:CC_C CC_REGNUM)
-                  (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
-                                (match_dup 1)))
-             (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
-   (parallel [(set (reg:CC_V CC_REGNUM)
-                  (ne:CC_V
-                   (plus:DI (plus:DI
-                             (sign_extend:DI (match_dup 4))
-                             (sign_extend:DI (match_dup 5)))
-                            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
-                   (plus:DI (sign_extend:DI
-                             (plus:SI (match_dup 4) (match_dup 5)))
-                            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
-            (set (match_dup 3) (plus:SI (plus:SI
-                                         (match_dup 4) (match_dup 5))
-                                        (ltu:SI (reg:CC_C CC_REGNUM)
-                                                (const_int 0))))])]
-  "
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[4] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[5] = gen_highpart (SImode, operands[2]);
-    operands[2] = gen_lowpart (SImode, operands[2]);
-  }"
+  "adds\\t%Q0, %Q1, %Q2;adcs\\t%R0, %R1, %R2"
  [(set_attr "conds" "set")
    (set_attr "length" "8")
    (set_attr "type" "multiple")]
    (set_attr "type" "alus_sreg")]
 )
 
-(define_insn "*addsi3_compareV_upper"
-  [(set (reg:CC_V CC_REGNUM)
-       (ne:CC_V
-         (plus:DI
-          (plus:DI
-           (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
-           (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
-          (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
-         (plus:DI (sign_extend:DI
-                   (plus:SI (match_dup 1) (match_dup 2)))
-                  (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
-   (set (match_operand:SI 0 "register_operand" "=r")
-       (plus:SI
-        (plus:SI (match_dup 1) (match_dup 2))
-        (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
-  "TARGET_32BIT"
-  "adcs%?\\t%0, %1, %2"
-  [(set_attr "conds" "set")
-   (set_attr "type" "adcs_reg")]
-)
-
-(define_insn_and_split "adddi3_compareC"
+(define_insn "adddi3_compareC"
   [(set (reg:CC_C CC_REGNUM)
-       (ne:CC_C
-         (plus:TI
-           (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
-           (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
-         (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
+       (compare:CC_C
+         (plus:DI
+           (match_operand:DI 1 "register_operand" "r")
+           (match_operand:DI 2 "register_operand" "r"))
+         (match_dup 1)))
    (set (match_operand:DI 0 "register_operand" "=&r")
        (plus:DI (match_dup 1) (match_dup 2)))]
   "TARGET_32BIT"
-  "#"
-  "&& reload_completed"
-  [(parallel [(set (reg:CC_C CC_REGNUM)
-                  (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
-                                (match_dup 1)))
-             (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
-   (parallel [(set (reg:CC_C CC_REGNUM)
-                  (ne:CC_C
-                   (plus:DI (plus:DI
-                             (zero_extend:DI (match_dup 4))
-                             (zero_extend:DI (match_dup 5)))
-                            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
-                   (plus:DI (zero_extend:DI
-                             (plus:SI (match_dup 4) (match_dup 5)))
-                            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
-            (set (match_dup 3) (plus:SI
-                                (plus:SI (match_dup 4) (match_dup 5))
-                                (ltu:SI (reg:CC_C CC_REGNUM)
-                                        (const_int 0))))])]
-  "
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[4] = gen_highpart (SImode, operands[1]);
-    operands[5] = gen_highpart (SImode, operands[2]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[2] = gen_lowpart (SImode, operands[2]);
-  }"
+  "adds\\t%Q0, %Q1, %Q2;adcs\\t%R0, %R1, %R2"
  [(set_attr "conds" "set")
    (set_attr "length" "8")
    (set_attr "type" "multiple")]
 )
 
-(define_insn "*addsi3_compareC_upper"
-  [(set (reg:CC_C CC_REGNUM)
-       (ne:CC_C
-         (plus:DI
-          (plus:DI
-           (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
-           (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
-          (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
-         (plus:DI (zero_extend:DI
-                   (plus:SI (match_dup 1) (match_dup 2)))
-                  (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
-   (set (match_operand:SI 0 "register_operand" "=r")
-       (plus:SI
-        (plus:SI (match_dup 1) (match_dup 2))
-        (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
-  "TARGET_32BIT"
-  "adcs%?\\t%0, %1, %2"
-  [(set_attr "conds" "set")
-   (set_attr "type" "adcs_reg")]
-)
-
 (define_insn "addsi3_compareC"
    [(set (reg:CC_C CC_REGNUM)
-        (ne:CC_C
-         (plus:DI
-          (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
-          (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
-         (zero_extend:DI
-          (plus:SI (match_dup 1) (match_dup 2)))))
+        (compare:CC_C (plus:SI (match_operand:SI 1 "register_operand" "r")
+                               (match_operand:SI 2 "register_operand" "r"))
+                      (match_dup 1)))
     (set (match_operand:SI 0 "register_operand" "=r")
         (plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_32BIT"
   DONE;
 })
 
-(define_insn_and_split "subdi3_compare1"
+(define_insn "subdi3_compare1"
   [(set (reg:CC CC_REGNUM)
        (compare:CC
-         (match_operand:DI 1 "register_operand" "r")
-         (match_operand:DI 2 "register_operand" "r")))
-   (set (match_operand:DI 0 "register_operand" "=&r")
+         (match_operand:DI 1 "s_register_operand" "r")
+         (match_operand:DI 2 "s_register_operand" "r")))
+   (set (match_operand:DI 0 "s_register_operand" "=&r")
        (minus:DI (match_dup 1) (match_dup 2)))]
   "TARGET_32BIT"
-  "#"
-  "&& reload_completed"
-  [(parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (match_dup 1) (match_dup 2)))
-             (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
-   (parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (match_dup 4) (match_dup 5)))
-            (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
-                              (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])]
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[4] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[5] = gen_highpart (SImode, operands[2]);
-    operands[2] = gen_lowpart (SImode, operands[2]);
-   }
+  "subs\\t%Q0, %Q1, %Q2;sbcs\\t%R0, %R1, %R2"
   [(set_attr "conds" "set")
    (set_attr "length" "8")
    (set_attr "type" "multiple")]
    (set_attr "type" "adc_imm")]
 )
 
-(define_insn "*subsi3_carryin_compare"
-  [(set (reg:CC CC_REGNUM)
-       (compare:CC (match_operand:SI 1 "s_register_operand" "r")
-                   (match_operand:SI 2 "s_register_operand" "r")))
-   (set (match_operand:SI 0 "s_register_operand" "=r")
-       (minus:SI (minus:SI (match_dup 1) (match_dup 2))
-                 (match_operand:SI 3 "arm_borrow_operation" "")))]
-  "TARGET_32BIT"
-  "sbcs\\t%0, %1, %2"
-  [(set_attr "conds" "set")
-   (set_attr "type" "adcs_reg")]
-)
-
-(define_insn "*subsi3_carryin_compare_const"
-  [(set (reg:CC CC_REGNUM)
-       (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
-                   (match_operand:SI 2 "const_int_I_operand" "I")))
-   (set (match_operand:SI 0 "s_register_operand" "=r")
-       (minus:SI (plus:SI
-                  (match_dup 1)
-                  (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
-                 (match_operand:SI 4 "arm_borrow_operation" "")))]
-  "TARGET_32BIT
-   && (INTVAL (operands[2])
-       == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
-  "sbcs\\t%0, %1, #%n3"
-  [(set_attr "conds" "set")
-   (set_attr "type" "adcs_imm")]
-)
-
-(define_insn "*subsi3_carryin_compare_const0"
-  [(set (reg:CC CC_REGNUM)
-       (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
-                   (const_int 0)))
-   (set (match_operand:SI 0 "s_register_operand" "=r")
-       (minus:SI (match_dup 1)
-                 (match_operand:SI 2 "arm_borrow_operation" "")))]
-  "TARGET_32BIT"
-  "sbcs\\t%0, %1, #0"
-  [(set_attr "conds" "set")
-   (set_attr "type" "adcs_imm")]
-)
-
 (define_insn "*subsi3_carryin_shift"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
        (minus:SI (minus:SI
  [(parallel
    [(set (match_operand:DI            0 "s_register_operand")
          (minus:DI (match_operand:DI 1 "s_register_operand")
-                   (match_operand:DI 2 "s_register_operand")))
+                   (match_operand:DI 2 "s_register_operand")))
     (clobber (reg:CC CC_REGNUM))])]
   "TARGET_EITHER"
   "
 ")
 
-(define_insn_and_split "*arm_subdi3"
-  [(set (match_operand:DI           0 "arm_general_register_operand" "=&r,&r,&r")
+(define_insn "*arm_subdi3"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
        (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
                  (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_32BIT"
-  "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
-  "TARGET_32BIT"
-  [(parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (match_dup 1) (match_dup 2)))
-             (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
-   (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
-                              (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[4] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[5] = gen_highpart (SImode, operands[2]);
-    operands[2] = gen_lowpart (SImode, operands[2]);
-   }
-  [(set_attr "conds" "clob")
-   (set_attr "length" "8")
-   (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*subdi_di_zesidi"
-  [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
-       (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
-                 (zero_extend:DI
-                  (match_operand:SI 2 "s_register_operand"  "r,r"))))
-   (clobber (reg:CC CC_REGNUM))]
-  "TARGET_32BIT"
-  "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
-  "&& reload_completed"
-  [(parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (match_dup 1) (match_dup 2)))
-             (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
-   (set (match_dup 3) (minus:SI (match_dup 4)
-                               (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[4] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-   }
-  [(set_attr "conds" "clob")
-   (set_attr "length" "8")
-   (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*subdi_di_sesidi"
-  [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
-       (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
-                 (sign_extend:DI
-                  (match_operand:SI 2 "s_register_operand"  "r,r"))))
-   (clobber (reg:CC CC_REGNUM))]
-  "TARGET_32BIT"
-  "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
-  "&& reload_completed"
-  [(parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (match_dup 1) (match_dup 2)))
-             (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
-   (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
-                                         (ashiftrt:SI (match_dup 2)
-                                                      (const_int 31)))
-                                (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[4] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-  }
-  [(set_attr "conds" "clob")
-   (set_attr "length" "8")
-   (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*subdi_zesidi_di"
-  [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
-       (minus:DI (zero_extend:DI
-                  (match_operand:SI 2 "s_register_operand"  "r,r"))
-                 (match_operand:DI  1 "s_register_operand" "0,r")))
-   (clobber (reg:CC CC_REGNUM))]
-  "TARGET_ARM"
-  "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
-        ; is equivalent to:
-        ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
-  "&& reload_completed"
-  [(parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (match_dup 2) (match_dup 1)))
-             (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
-   (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
-                              (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[4] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-  }
-  [(set_attr "conds" "clob")
-   (set_attr "length" "8")
-   (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*subdi_sesidi_di"
-  [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
-       (minus:DI (sign_extend:DI
-                  (match_operand:SI 2 "s_register_operand"   "r,r"))
-                 (match_operand:DI  1 "s_register_operand"  "0,r")))
-   (clobber (reg:CC CC_REGNUM))]
-  "TARGET_ARM"
-  "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
-        ; is equivalent to:
-        ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
-  "&& reload_completed"
-  [(parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (match_dup 2) (match_dup 1)))
-             (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
-   (set (match_dup 3) (minus:SI (minus:SI
-                                (ashiftrt:SI (match_dup 2)
-                                             (const_int 31))
-                                (match_dup 4))
-                              (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[4] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-  }
-  [(set_attr "conds" "clob")
-   (set_attr "length" "8")
-   (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*subdi_zesidi_zesidi"
-  [(set (match_operand:DI            0 "s_register_operand" "=r")
-       (minus:DI (zero_extend:DI
-                  (match_operand:SI 1 "s_register_operand"  "r"))
-                 (zero_extend:DI
-                  (match_operand:SI 2 "s_register_operand"  "r"))))
-   (clobber (reg:CC CC_REGNUM))]
-  "TARGET_32BIT"
-  "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
-  "&& reload_completed"
-  [(parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (match_dup 1) (match_dup 2)))
-             (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
-   (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
-                              (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
-  {
-       operands[3] = gen_highpart (SImode, operands[0]);
-       operands[0] = gen_lowpart (SImode, operands[0]);
-  }
+  "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
   [(set_attr "conds" "clob")
    (set_attr "length" "8")
    (set_attr "type" "multiple")]
 })
 
 (define_expand "negvdi3"
-  [(match_operand:DI 0 "register_operand")
-   (match_operand:DI 1 "register_operand")
+  [(match_operand:DI 0 "s_register_operand")
+   (match_operand:DI 1 "s_register_operand")
    (match_operand 2 "")]
   "TARGET_ARM"
 {
 })
 
 
-(define_insn_and_split "negdi2_compare"
+(define_insn "negdi2_compare"
   [(set (reg:CC CC_REGNUM)
        (compare:CC
          (const_int 0)
-         (match_operand:DI 1 "register_operand" "0,r")))
-   (set (match_operand:DI 0 "register_operand" "=r,&r")
+         (match_operand:DI 1 "register_operand" "r,r")))
+   (set (match_operand:DI 0 "register_operand" "=&r,&r")
        (minus:DI (const_int 0) (match_dup 1)))]
   "TARGET_ARM"
-  "#"
-  "&& reload_completed"
-  [(parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (const_int 0) (match_dup 1)))
-             (set (match_dup 0) (minus:SI (const_int 0)
-                                          (match_dup 1)))])
-   (parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (const_int 0) (match_dup 3)))
-            (set (match_dup 2)
-                 (minus:SI
-                  (minus:SI (const_int 0) (match_dup 3))
-                  (ltu:SI (reg:CC CC_REGNUM)
-                          (const_int 0))))])]
-  {
-    operands[2] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[3] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-  }
+  "@
+   rsbs\\t%Q0, %Q1, #0;rscs\\t%R0, %R1, #0
+   rsbs\\t%Q0, %Q1, #0;sbcs\\t%R0, %R1, %R1, lsl #1"
   [(set_attr "conds" "set")
+   (set_attr "arch" "a,t2")
    (set_attr "length" "8")
    (set_attr "type" "multiple")]
 )
 )
 
 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
-;; The first alternative allows the common case of a *full* overlap.
-(define_insn_and_split "*negdi2_insn"
-  [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
-       (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
+(define_insn "*negdi2_insn"
+  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
+       (neg:DI (match_operand:DI 1 "s_register_operand"  "r,r")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_32BIT"
-  "#"  ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0          (ARM)
-       ; negs %Q0, %Q1    ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
-  "TARGET_32BIT"
-  [(parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (const_int 0) (match_dup 1)))
-             (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
-   (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
-                                (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
-  {
-    operands[2] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    operands[3] = gen_highpart (SImode, operands[1]);
-    operands[1] = gen_lowpart (SImode, operands[1]);
-  }
+  "@
+   rsbs\\t%Q0, %Q1, #0; rsc\\t%R0, %R1, #0
+   negs\\t%Q0, %Q1; sbc\\t%R0, %R1, %R1, lsl #1"
   [(set_attr "conds" "clob")
+   (set_attr "arch" "a,t2")
    (set_attr "length" "8")
    (set_attr "type" "multiple")]
 )
 
-(define_insn "*negsi2_carryin_compare"
-  [(set (reg:CC CC_REGNUM)
-       (compare:CC (const_int 0)
-                   (match_operand:SI 1 "s_register_operand" "r")))
-   (set (match_operand:SI 0 "s_register_operand" "=r")
-       (minus:SI (minus:SI (const_int 0)
-                           (match_dup 1))
-                 (match_operand:SI 2 "arm_borrow_operation" "")))]
-  "TARGET_ARM"
-  "rscs\\t%0, %1, #0"
-  [(set_attr "conds" "set")
-   (set_attr "type" "alus_imm")]
-)
-
 (define_expand "negsi2"
   [(set (match_operand:SI         0 "s_register_operand")
        (neg:SI (match_operand:SI 1 "s_register_operand")))]
    (set_attr "type" "multiple")]
 )
 
-(define_insn_and_split "*negdi_zero_extendsidi"
-  [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
-       (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
-   (clobber (reg:CC CC_REGNUM))]
-  "TARGET_32BIT"
-  "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
-      ;; Don't care what register is input to sbc,
-      ;; since we just need to propagate the carry.
-  "&& reload_completed"
-  [(parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (const_int 0) (match_dup 1)))
-             (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
-   (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
-                               (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
-  {
-    operands[2] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-  }
-  [(set_attr "conds" "clob")
-   (set_attr "length" "8")
-   (set_attr "type" "multiple")]   ;; length in thumb is 4
-)
-
 ;; abssi2 doesn't really clobber the condition codes if a different register
 ;; is being set.  To keep things simple, assume during rtl manipulations that
 ;; it does, but tell the final scan operator the truth.  Similarly for
 ;; if-conversion cannot reduce to a conditional compare, so we do
 ;; that directly.
 
-(define_insn_and_split "*arm_cmpdi_insn"
+(define_insn "*arm_cmpdi_insn"
   [(set (reg:CC_NCV CC_REGNUM)
        (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
                        (match_operand:DI 1 "arm_di_operand"       "rDi")))
    (clobber (match_scratch:SI 2 "=r"))]
   "TARGET_32BIT"
-  "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
-  "&& reload_completed"
-  [(set (reg:CC CC_REGNUM)
-       (compare:CC (match_dup 0) (match_dup 1)))
-   (parallel [(set (reg:CC CC_REGNUM)
-                  (compare:CC (match_dup 3) (match_dup 4)))
-             (set (match_dup 2)
-                  (minus:SI (match_dup 5)
-                            (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])]
-  {
-    operands[3] = gen_highpart (SImode, operands[0]);
-    operands[0] = gen_lowpart (SImode, operands[0]);
-    if (CONST_INT_P (operands[1]))
-      {
-       operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
-       if (operands[4] == const0_rtx)
-         operands[5] = operands[3];
-       else
-         operands[5] = gen_rtx_PLUS (SImode, operands[3],
-                                     gen_int_mode (-UINTVAL (operands[4]),
-                                                   SImode));
-      }
-    else
-      {
-        operands[4] = gen_highpart (SImode, operands[1]);
-        operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
-      }
-    operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[2] = gen_lowpart (SImode, operands[2]);
-  }
+  "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
   [(set_attr "conds" "set")
    (set_attr "length" "8")
    (set_attr "type" "multiple")]
index 5379447..0c5b6e4 100644 (file)
@@ -1,3 +1,10 @@
+2019-10-18  Richard Earnshaw  <rearnsha@arm.com>
+
+       * gcc.target/arm/negdi-3.c: Add XFAILS.
+       * gcc.target/arm/pr3447-1.c: Likewise.
+       * gcc.target/arm/pr3447-3.c: Likewise.
+       * gcc.target/arm/pr3447-4.c: Likewise.
+
 2019-10-18  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/69455
index 76ddf49..3f6f2d1 100644 (file)
@@ -11,7 +11,7 @@ Expected output:
         rsbs    r0, r0, #0
         sbc     r1, r1, r1
 */
-/* { 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 } } */
+/* { 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 *-*-* } } } */
index dc09418..0fd98b7 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-options "-O2" }  */
 /* { dg-require-effective-target arm32 } */
-/* { dg-final { scan-assembler-not "mov" } } */
+/* { dg-final { scan-assembler-not "mov" { xfail *-*-* } } } */
 
 void t0p(long long * p)
 {
index 8e48f11..79d3691 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-options "-O2" }  */
 /* { dg-require-effective-target arm32 } */
-/* { dg-final { scan-assembler-not "mov" } } */
+/* { dg-final { scan-assembler-not "mov" { xfail *-*-* } } } */
 
 
 void t0p(long long * p)
index 22acb97..bfa20df 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-options "-O2" }  */
 /* { dg-require-effective-target arm32 } */
-/* { dg-final { scan-assembler-not "mov" } } */
+/* { dg-final { scan-assembler-not "mov" { xfail *-*-* } } } */
 
 
 void t0p(long long * p)