From: Uros Bizjak Date: Tue, 4 Nov 2025 09:18:03 +0000 (+0100) Subject: i386: TEST insn should be merged with ADC/SBB insn [PR122390] X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0983945b7c1cdc575fefe9c61609e27f18b1ba3f;p=thirdparty%2Fgcc.git i386: TEST insn should be merged with ADC/SBB insn [PR122390] The attached testcase is currently compiled to: f1: cmpl %esi, %edi adcl %esi, %edi testl %edi, %edi js .L4 ... TEST insn should be merged with ADC/SBB insn. The patch provides missing combined insn patterns. PR target/122390 gcc/ChangeLog: * config/i386/i386.md (*add3_carry_2): New insn pattern. (*add3_carry_0_cc): Ditto. (*add3_carry_0r_cc): Ditto. (*sub3_carry_2): Ditto. (*sub3_carry_0_cc): Ditto. (*sub3_carry_0r_cc): Ditt. gcc/testsuite/ChangeLog: * gcc.target/i386/pr122390.c: New test. * gcc.target/i386/pr122390-1.c: New test. --- diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 4a2232e4023..3ea2439526b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -8860,6 +8860,35 @@ (match_dup 0))) (clobber (reg:CC FLAGS_REG))])]) +(define_insn "*add3_carry_2" + [(set (reg FLAGS_REG) + (compare + (plus:SWI + (plus:SWI + (match_operator:SWI 4 "ix86_carry_flag_operator" + [(match_operand 3 "flags_reg_operand") (const_int 0)]) + (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")) + (match_operand:SWI 2 "" ",,r,")) + (const_int 0))) + (set (match_operand:SWI 0 "nonimmediate_operand" "=m,,r,r") + (plus:SWI + (plus:SWI + (match_op_dup 4 [(match_dup 3) (const_int 0)]) + (match_dup 1)) + (match_dup 2)))] + "ix86_match_ccmode (insn, CCGOCmode) + && ix86_binary_operator_ok (PLUS, mode, operands, TARGET_APX_NDD)" + "@ + adc{}\t{%2, %0|%0, %2} + adc{}\t{%2, %0|%0, %2} + adc{}\t{%2, %1, %0|%0, %1, %2} + adc{}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "")]) + (define_insn "*add3_carry_0" [(set (match_operand:SWI 0 "nonimmediate_operand" "=m") (plus:SWI @@ -8874,6 +8903,26 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "")]) +(define_insn "*add3_carry_0_cc" + [(set (reg FLAGS_REG) + (compare + (plus:SWI + (match_operator:SWI 2 "ix86_carry_flag_operator" + [(match_operand 3 "flags_reg_operand") (const_int 0)]) + (match_operand:SWI 1 "nonimmediate_operand" "0")) + (const_int 0))) + (set (match_operand:SWI 0 "nonimmediate_operand" "=m") + (plus:SWI + (match_op_dup 2 [(match_dup 3) (const_int 0)]) + (match_dup 1)))] + "ix86_match_ccmode (insn, CCGOCmode) + && (!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1]))" + "adc{}\t{$0, %0|%0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "")]) + (define_insn "*add3_carry_0r" [(set (match_operand:SWI 0 "nonimmediate_operand" "=m") (plus:SWI @@ -8888,6 +8937,26 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "")]) +(define_insn "*add3_carry_0r_cc" + [(set (reg FLAGS_REG) + (compare + (plus:SWI + (match_operator:SWI 2 "ix86_carry_flag_unset_operator" + [(match_operand 3 "flags_reg_operand") (const_int 0)]) + (match_operand:SWI 1 "nonimmediate_operand" "0")) + (const_int 0))) + (set (match_operand:SWI 0 "nonimmediate_operand" "=m") + (plus:SWI + (match_op_dup 2 [(match_dup 3) (const_int 0)]) + (match_dup 1)))] + "ix86_match_ccmode (insn, CCGOCmode) + && (!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1]))" + "sbb{}\t{$-1, %0|%0, -1}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "")]) + (define_insn "*addqi3_carry_zext" [(set (match_operand:SWI248x 0 "register_operand" "=r,r") (zero_extend:SWI248x @@ -9456,6 +9525,35 @@ (match_dup 0))) (clobber (reg:CC FLAGS_REG))])]) +(define_insn "*sub3_carry_2" + [(set (reg FLAGS_REG) + (compare + (minus:SWI + (minus:SWI + (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r") + (match_operator:SWI 4 "ix86_carry_flag_operator" + [(match_operand 3 "flags_reg_operand") (const_int 0)])) + (match_operand:SWI 2 "" ",,r,")) + (const_int 0))) + (set (match_operand:SWI 0 "nonimmediate_operand" "=m,,r,r") + (minus:SWI + (minus:SWI + (match_dup 1) + (match_op_dup 4 [(match_dup 3) (const_int 0)])) + (match_dup 2)))] + "ix86_match_ccmode (insn, CCGOCmode) + && ix86_binary_operator_ok (MINUS, mode, operands, TARGET_APX_NDD)" + "@ + sbb{}\t{%2, %0|%0, %2} + sbb{}\t{%2, %0|%0, %2} + sbb{}\t{%2, %1, %0|%0, %1, %2} + sbb{}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "")]) + (define_insn "*sub3_carry_0" [(set (match_operand:SWI 0 "nonimmediate_operand" "=m") (minus:SWI @@ -9470,6 +9568,26 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "")]) +(define_insn "*sub3_carry_0_cc" + [(set (reg FLAGS_REG) + (compare + (minus:SWI + (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operator:SWI 2 "ix86_carry_flag_operator" + [(match_operand 3 "flags_reg_operand") (const_int 0)])) + (const_int 0))) + (set (match_operand:SWI 0 "nonimmediate_operand" "=m") + (minus:SWI + (match_dup 1) + (match_op_dup 2 [(match_dup 3) (const_int 0)])))] + "ix86_match_ccmode (insn, CCGOCmode) + && (!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1]))" + "sbb{}\t{$0, %0|%0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "")]) + (define_insn "*sub3_carry_0r" [(set (match_operand:SWI 0 "nonimmediate_operand" "=m") (minus:SWI @@ -9484,6 +9602,26 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "")]) +(define_insn "*sub3_carry_0r_cc" + [(set (reg FLAGS_REG) + (compare + (minus:SWI + (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operator:SWI 2 "ix86_carry_flag_unset_operator" + [(match_operand 3 "flags_reg_operand") (const_int 0)])) + (const_int 0))) + (set (match_operand:SWI 0 "nonimmediate_operand" "=m") + (minus:SWI + (match_dup 1) + (match_op_dup 2 [(match_dup 3) (const_int 0)])))] + "ix86_match_ccmode (insn, CCGOCmode) + && (!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1]))" + "adc{}\t{$-1, %0|%0, -1}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "")]) + (define_insn "*subqi3_carry_zext" [(set (match_operand:SWI248x 0 "register_operand" "=r,r") (zero_extend:SWI248x diff --git a/gcc/testsuite/gcc.target/i386/pr122390-1.c b/gcc/testsuite/gcc.target/i386/pr122390-1.c new file mode 100644 index 00000000000..9120dd440e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr122390-1.c @@ -0,0 +1,26 @@ +/* PR target/122390 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int f (int); +int g (int); + +int f1 (unsigned a, unsigned b) +{ + unsigned t = a < b; + int tt = a + b + t; + if (tt < 0) + return f(tt); + return g(tt); +} + +int f2 (unsigned a, unsigned b) +{ + unsigned t = a < b; + int tt = a - b - t; + if (tt < 0) + return f(tt); + return g(tt); +} + +/* { dg-final { scan-assembler-not "test" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr122390.c b/gcc/testsuite/gcc.target/i386/pr122390.c new file mode 100644 index 00000000000..a12849a4700 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr122390.c @@ -0,0 +1,44 @@ +/* PR target/122390 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int f (int); +int g (int); + +int f1 (unsigned a, unsigned b) +{ + unsigned t = a < b; + int tt = a + t; + if (tt == 0) + return f(tt); + return g(tt); +} + +int f2 (unsigned a, unsigned b) +{ + unsigned t = a <= b; + int tt = a + t; + if (tt < 0) + return f(tt); + return g(tt); +} + +int f3 (unsigned a, unsigned b) +{ + unsigned t = a > b; + int tt = a - t; + if (tt == 0) + return f(tt); + return g(tt); +} + +int f4 (unsigned a, unsigned b) +{ + unsigned t = a >= b; + int tt = a - t; + if (tt < 0) + return f(tt); + return g(tt); +} + +/* { dg-final { scan-assembler-not "test" } } */