]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
arm: don't allow movMcc when short-it but no vsel [PR124134]
authorRichard Earnshaw <rearnsha@arm.com>
Tue, 17 Feb 2026 16:19:32 +0000 (16:19 +0000)
committerRichard Earnshaw <rearnsha@arm.com>
Tue, 17 Feb 2026 17:59:53 +0000 (17:59 +0000)
Perverse combinations of options can lead to the compiler having to
work around unexpected situations.  Armv8 originally specified that
complex IT sequences were deprecated for performance (it was later
rescinded).  If the options restrict the floating-point unit to
one without vsel, then movMcc patterns need complex IT sequences
and we can end up with unmatched RTL patterns.  Avoid this by
failing early when the target patterns are disabled.

gcc/ChangeLog:

PR target/124134
* config/arm/arm.md (movsfcc): FAIL if using restricted IT
blocks and we lack VSEL.
(movdfcc): Likewise.

gcc/testsuite/ChangeLog:

PR target/124134
* gcc.target/arm/pr124134.c: New test.

gcc/config/arm/arm.md
gcc/testsuite/gcc.target/arm/pr124134.c [new file with mode: 0644]

index 4c3f1a5e2af81d60814345d86e21928733fbccf7..a3e6a362fdefebcbdbcecd43ec0caea700b9750f 100644 (file)
     enum rtx_code code = GET_CODE (operands[1]);
     rtx ccreg;
 
+    /* Perverse combinations of architecture options can't be supported
+       as they need conditional instructions.  */
+    if (TARGET_THUMB2 && arm_restrict_it && !TARGET_VFP5)
+      FAIL;
     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
                                          &XEXP (operands[1], 1)))
-       FAIL;
+      FAIL;
 
     code = GET_CODE (operands[1]);
     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
     enum rtx_code code = GET_CODE (operands[1]);
     rtx ccreg;
 
+    /* Perverse combinations of architecture options can't be supported
+       as they need conditional instructions.  */
+    if (TARGET_THUMB2 && arm_restrict_it && !TARGET_VFP5)
+      FAIL;
     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
                                          &XEXP (operands[1], 1)))
-       FAIL;
+      FAIL;
     code = GET_CODE (operands[1]);
     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
                                 XEXP (operands[1], 1), NULL_RTX);
diff --git a/gcc/testsuite/gcc.target/arm/pr124134.c b/gcc/testsuite/gcc.target/arm/pr124134.c
new file mode 100644 (file)
index 0000000..9d80f95
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v7a_fp_hard_ok } */
+/* { dg-add-options arm_arch_v7a_fp_hard } */
+/* { dg-additional-options "-O2 -mrestrict-it" } */
+double max___a, max___b;
+double max() {
+  if (max___a < max___b)
+    return max___b;
+  return max___a;
+}