diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index c74edd1aaef..b321cda1f22 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -10929,6 +10929,50 @@ (define_insn_and_split "*neg2_doubleword" (clobber (reg:CC FLAGS_REG))])] "split_double_mode (mode, &operands[0], 2, &operands[0], &operands[2]);") +;; Convert: +;; mov %esi, %edx +;; negl %eax +;; adcl $0, %edx +;; negl %edx +;; to: +;; xorl %edx, %edx +;; negl %eax +;; sbbl %esi, %edx + +(define_peephole2 + [(set (match_operand:SWI48 0 "general_reg_operand") + (match_operand:SWI48 1 "nonimmediate_gr_operand")) + (parallel + [(set (reg:CCC FLAGS_REG) + (ne:CCC (match_operand:SWI48 2 "general_reg_operand") (const_int 0))) + (set (match_dup 2) (neg:SWI48 (match_dup 2)))]) + (parallel + [(set (match_dup 0) + (plus:SWI48 (plus:SWI48 + (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)) + (match_dup 0)) + (const_int 0))) + (clobber (reg:CC FLAGS_REG))]) + (parallel + [(set (match_dup 0) + (neg:SWI48 (match_dup 0))) + (clobber (reg:CC FLAGS_REG))])] + "REGNO (operands[0]) != REGNO (operands[2]) + && !reg_mentioned_p (operands[0], operands[1]) + && !reg_mentioned_p (operands[2], operands[1])" + [(parallel + [(set (reg:CCC FLAGS_REG) + (ne:CCC (match_dup 2) (const_int 0))) + (set (match_dup 2) (neg:SWI48 (match_dup 2)))]) + (parallel + [(set (match_dup 0) + (minus:SWI48 (minus:SWI48 + (match_dup 0) + (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))) + (match_dup 1))) + (clobber (reg:CC FLAGS_REG))])] + "ix86_expand_clear (operands[0]);") + (define_insn "*neg_1" [(set (match_operand:SWI 0 "nonimmediate_operand" "=m") (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))) diff --git a/gcc/testsuite/gcc.target/i386/pr51954.c b/gcc/testsuite/gcc.target/i386/pr51954.c new file mode 100644 index 00000000000..5e757de22f9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr51954.c @@ -0,0 +1,15 @@ +/* PR target/51954 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "adc" } } */ + +#ifdef __x86_64__ +#define TYPE __int128 +#else +#define TYPE long long +#endif + +TYPE bar (TYPE x) +{ + return -x; +}