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