We have been using CCmode, which is not correct for this case.
Mirror the same code from the arm target.

        * config/aarch64/aarch64.c (aarch64_select_cc_mode):
        Recognize usub*_carryinC patterns.
        * config/aarch64/aarch64.md (usubvti4): Use CC_NOTC.
        (usub<GPI>3_carryinC): Likewise.
        (*usub<GPI>3_carryinC_z1): Likewise.
        (*usub<GPI>3_carryinC_z2): Likewise.
        (*usub<GPI>3_carryinC): Likewise.
---
 gcc/config/aarch64/aarch64.c  |  9 +++++++++
 gcc/config/aarch64/aarch64.md | 18 +++++++++---------
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index c09b7bcb7f0..d80afc36889 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -9532,6 +9532,15 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
       && const_dword_umaxp1 (y, mode_x))
     return CC_NOTCmode;
 
+  /* A test for unsigned overflow from a subtract with borrow.  */
+  if ((mode_x == DImode || mode_x == TImode)
+      && (code == GEU || code == LTU)
+      && code_x == ZERO_EXTEND
+      && ((GET_CODE (y) == PLUS
+          && aarch64_borrow_operation (XEXP (y, 0), mode_x))
+         || aarch64_borrow_operation (y, mode_x)))
+    return CC_NOTCmode;
+
   /* A test for signed overflow.  */
   if ((mode_x == DImode || mode_x == TImode)
       && (code == NE || code == EQ)
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 7d4a63f9a2a..a0a872c6d94 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -2954,7 +2954,7 @@
                           CODE_FOR_subdi3_compare1,
                           CODE_FOR_subdi3_compare1,
                           CODE_FOR_usubdi3_carryinC);
-  aarch64_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
+  aarch64_gen_unlikely_cbranch (LTU, CC_NOTCmode, operands[3]);
   DONE;
 })
 
@@ -3367,8 +3367,8 @@
 
 (define_expand "usub<GPI:mode>3_carryinC"
   [(parallel
-     [(set (reg:CC CC_REGNUM)
-          (compare:CC
+     [(set (reg:CC_NOTC CC_REGNUM)
+          (compare:CC_NOTC
             (zero_extend:<DWI>
               (match_operand:GPI 1 "aarch64_reg_or_zero"))
             (plus:<DWI>
@@ -3383,8 +3383,8 @@
 )
 
 (define_insn "*usub<GPI:mode>3_carryinC_z1"
-  [(set (reg:CC CC_REGNUM)
-       (compare:CC
+  [(set (reg:CC_NOTC CC_REGNUM)
+       (compare:CC_NOTC
          (const_int 0)
          (plus:<DWI>
            (zero_extend:<DWI>
@@ -3400,8 +3400,8 @@
 )
 
 (define_insn "*usub<GPI:mode>3_carryinC_z2"
-  [(set (reg:CC CC_REGNUM)
-       (compare:CC
+  [(set (reg:CC_NOTC CC_REGNUM)
+       (compare:CC_NOTC
          (zero_extend:<DWI>
            (match_operand:GPI 1 "register_operand" "r"))
          (match_operand:<DWI> 2 "aarch64_borrow_operation" "")))
@@ -3415,8 +3415,8 @@
 )
 
 (define_insn "*usub<GPI:mode>3_carryinC"
-  [(set (reg:CC CC_REGNUM)
-       (compare:CC
+  [(set (reg:CC_NOTC CC_REGNUM)
+       (compare:CC_NOTC
          (zero_extend:<DWI>
            (match_operand:GPI 1 "register_operand" "r"))
          (plus:<DWI>
-- 
2.20.1

Reply via email to