@@ -2067,6 +2067,16 @@
"addze %0,%1"
[(set_attr "type" "add")])
+;; Non-canonical form of add<mode>3_carry_in_0
+(define_insn "*add<mode>3_carry_in_0_2"
+ [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+ (plus:GPR (reg:GPR CA_REGNO)
+ (match_operand:GPR 1 "gpc_reg_operand" "r")))
+ (clobber (reg:GPR CA_REGNO))]
+ ""
+ "addze %0,%1"
+ [(set_attr "type" "add")])
+
(define_insn "add<mode>3_carry_in_m1"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
@@ -2078,6 +2088,95 @@
[(set_attr "type" "add")])
+;; PR target/43892 -> subf<mode>3_carry ; add<mode>3_carry_in_0
+(define_insn_and_split "*add<mode>3_geu"
+ [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+ (plus:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r")
+ (match_operand:P 2 "gpc_reg_operand" "r"))
+ (match_operand:P 3 "gpc_reg_operand" "r")))
+ (clobber (match_scratch:P 4 "=r"))
+ (clobber (reg:P CA_REGNO))]
+ ""
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ if (GET_CODE (operands[4]) == SCRATCH)
+ operands[4] = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_subf<mode>3_carry (operands[4], operands[1], operands[2]));
+ emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[3]));
+ DONE;
+}
+ [(set_attr "type" "two")
+ (set_attr "length" "8")])
+
+;; PR target/43892 -> subf<mode>3_carry ; add<mode>3_carry_in_0
+(define_insn_and_split "*add<mode>3_leu"
+ [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+ (plus:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
+ (match_operand:P 2 "gpc_reg_operand" "r"))
+ (match_operand:P 3 "gpc_reg_operand" "r")))
+ (clobber (match_scratch:P 4 "=r"))
+ (clobber (reg:P CA_REGNO))]
+ ""
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ if (GET_CODE (operands[4]) == SCRATCH)
+ operands[4] = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_subf<mode>3_carry (operands[4], operands[2], operands[1]));
+ emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[3]));
+ DONE;
+}
+ [(set_attr "type" "two")
+ (set_attr "length" "8")])
+
+;; PR target/43892 -> subf<mode>3_carry_in_xx ; subf<mode>3
+(define_insn_and_split "*subf<mode>3_carry_in_xx_subf"
+ [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+ (plus:P (minus:P (match_operand:P 1 "gpc_reg_operand" "r")
+ (reg:P CA_REGNO))
+ (const_int 1)))
+ (clobber (match_scratch:P 2 "=r"))
+ (clobber (reg:P CA_REGNO))]
+ ""
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ if (GET_CODE (operands[2]) == SCRATCH)
+ operands[2] = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_subf<mode>3_carry_in_xx (operands[2]));
+ emit_insn (gen_sub<mode>3 (operands[0], operands[1], operands[2]));
+ DONE;
+}
+ [(set_attr "type" "two")
+ (set_attr "length" "8")])
+
+;; PR target/43892 -> add<mode>3_carry ; add<mode>3_carry_in_0
+(define_insn_and_split "*add<mode>3_carry_in_addc"
+ [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+ (plus:P (plus:P
+ (ltu:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
+ (match_operand:P 2 "gpc_reg_operand" "r"))
+ (match_dup 1))
+ (match_dup 2))
+ (match_dup 1)))
+ (clobber (reg:P CA_REGNO))]
+ ""
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ emit_insn (gen_add<mode>3_carry (operands[0], operands[1], operands[2]));
+ emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[0]));
+ DONE;
+}
+ [(set_attr "type" "two")
+ (set_attr "length" "8")])
+
+
(define_expand "one_cmpl<mode>2"
[(set (match_operand:SDI 0 "gpc_reg_operand")
(not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
new file mode 100644
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned long add_leu(unsigned long a, unsigned long b, unsigned long c) {
+ return a + (b <= c);
+}
+
+unsigned long add_geu(unsigned long a, unsigned long b, unsigned long c) {
+ return a + (b >= c);
+}
+
+/* { dg-final { scan-assembler-times "addze " 2 } } */
new file mode 100644
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+unsigned long foo(unsigned long sum, unsigned long x)
+{
+ unsigned long z = sum + x;
+ if (sum + x < x)
+ z++;
+ return z;
+}
+
+/* { dg-final { scan-assembler "addze " } } */