Hi!

The following testcase ICEs on arm.  The problem is that the following
peephole tries to match adjacent *arm_movsi_insn + *arm_cmpsi_insn;
the *arm_movsi_insn uses =rk, rk constraints and *arm_cmpsi_insn
uses r, IL constraints for what is matched by the peephole2.  Peephole2s
work only with predicates and not constraints, and the instruction that
the peephole2 turns those two into is *movsi_compare0, which uses
=r, r constraints.  As operands[1] is the same between the two insns,
sp (k constraint) is not possible for it, but as appears in the testcase,
we try to match sp = non-sp; cc = cmp (non-sp, 0) into
[ cc = cmp (non-sp, 0); sp = non-sp ] insn which isn't then recognized,
because it doesn't match the =r constraint.
I couldn't find a predicate that would do what we need here, the peephole2
uses arm_general_register_operand which matches SUBREGs as well as REGs
and requires <= 15 REGNO or pseudo register.  There is also
arm_hard_general_register_operand predicate that matches only REGs and
requires <= 15 REGNO, so slightly closer to what we need, but nothing
that would require <= LAST_ARM_REGNUM && != SP_REGNUM.

The following patch fixes it just by excluding SP destination in the
peephole2 condition, bootstrapped/regtested on armv7hl-linux-gnueabi,
ok for trunk?

Yet another option would be
s/arm_general_register_operand/arm_hard_general_register_operand/g
in the peephole2 and use
"TARGET_ARM && REGNO (operands[0]) != SP_REGNUM"
as condition.
And yet another option would be to add some predicate that would be
arm_hard_general_register_operand and would require that REGNO != SP_REGNUM
and use it in this peephole2.  But I'd need a suggestion how to call
that predicate, because I have no idea how arm calls core? registers
except sp.

2020-02-01  Jakub Jelinek  <ja...@redhat.com>

        PR target/91913
        * config/arm/arm.md (movsi + cmpsi -> movsi_compare0 peephole2):
        Punt if destination is sp register.

        * gfortran.dg/pr91913.f90: New test.

--- gcc/config/arm/arm.md.jj    2020-01-30 12:57:52.062102735 +0100
+++ gcc/config/arm/arm.md       2020-01-31 15:55:47.199979148 +0100
@@ -11227,7 +11227,7 @@ (define_peephole2
        (match_operand:SI 1 "arm_general_register_operand" ""))
    (set (reg:CC CC_REGNUM)
        (compare:CC (match_dup 1) (const_int 0)))]
-  "TARGET_ARM"
+  "TARGET_ARM && REG_P (operands[0]) && REGNO (operands[0]) != SP_REGNUM"
   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
              (set (match_dup 0) (match_dup 1))])]
   ""
--- gcc/testsuite/gfortran.dg/pr91913.f90.jj    2020-01-31 15:54:06.839475636 
+0100
+++ gcc/testsuite/gfortran.dg/pr91913.f90       2020-01-31 15:53:52.265692947 
+0100
@@ -0,0 +1,5 @@
+! PR target/91913
+! { dg-do compile }
+! { dg-options "-std=legacy -Ofast --param max-cse-insns=0 -fno-schedule-insns 
-fsanitize=null" }
+
+include 'string_ctor_1.f90'

        Jakub

Reply via email to