[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 724ce8e25c7e0fb8d06619b6234283e6634fc535..05ae1eaa0889b72acff4bec7067f12ab73e02355 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 3bf8cd637596e543467e901172bc70d0d0092803..e8ec426a0f870a0b965622405dbd39655b99290b 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 f861c72ccfc895405f0fa8afa4fe827bbad41a0d..241ba97c4bacdfcc79df717c7755df09e5ce00dd 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 5379447194bc37f811de3e0496c6fa7d79648b8f..0c5b6e4180dbdf649fd158181ca6769e3a949be6 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 76ddf49fc0ddb8b0287b8e30f72962ea25d12438..3f6f2d1c2bb640d7a6bbddd41210511dbcdddbcc 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 dc094180c85092febd18be7eef2887e6f1d7640f..0fd98b791feb5d0ef61a25d4ed1cb89c47ea1264 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 8e48f119b748244a4032a9ab39fcae022d7527e6..79d3691ee14cb6dd5a798166378f1615266ead48 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 22acb97270e2eec424be5cd6a82ee65bca07f72e..bfa20df7ccd4e6df92bece852bb9c09ffd9433ad 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)