diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-03-28 21:16:50 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-03-28 21:16:50 +0200 |
commit | 0a5c6d78b7159352185283c38c1359ecb3204c9f (patch) | |
tree | f97adb2bc8d5dc3da5a7c12b1506ca6c8ad462c1 /gcc | |
parent | 30a2c10eb639f1855fe7e060552f09c706efa532 (diff) | |
download | gcc-0a5c6d78b7159352185283c38c1359ecb3204c9f.zip gcc-0a5c6d78b7159352185283c38c1359ecb3204c9f.tar.gz gcc-0a5c6d78b7159352185283c38c1359ecb3204c9f.tar.bz2 |
re PR target/85095 (worse code generated)
PR target/85095
* config/i386/i386.md (*add<mode>3_carry_0, *addsi3_carry_zext_0,
*sub<mode>3_carry_0, *subsi3_carry_zext_0): New patterns.
* gcc.target/i386/pr85095-1.c: New test.
* gcc.target/i386/pr85095-2.c: New test.
* gcc.c-torture/execute/pr85095.c: New test.
From-SVN: r258931
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 57 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr85095.c | 52 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr85095-1.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr85095-2.c | 54 |
6 files changed, 205 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3ac9f9b..8da1441 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2018-03-28 Jakub Jelinek <jakub@redhat.com> + PR target/85095 + * config/i386/i386.md (*add<mode>3_carry_0, *addsi3_carry_zext_0, + *sub<mode>3_carry_0, *subsi3_carry_zext_0): New patterns. + PR tree-optimization/82004 * gimple-match-head.c (optimize_pow_to_exp): New function. * match.pd (pow(C,x) -> exp(log(C)*x)): Wrap with #if GIMPLE. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 5eb9e2f..b28e783 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6854,6 +6854,20 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "<MODE>")]) +(define_insn "*add<mode>3_carry_0" + [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") + (plus:SWI + (match_operator:SWI 3 "ix86_carry_flag_operator" + [(match_operand 2 "flags_reg_operand") (const_int 0)]) + (match_operand:SWI 1 "nonimmediate_operand" "0"))) + (clobber (reg:CC FLAGS_REG))] + "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)" + "adc{<imodesuffix>}\t{$0, %0|%0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "<MODE>")]) + (define_insn "*addsi3_carry_zext" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI @@ -6870,6 +6884,20 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) +(define_insn "*addsi3_carry_zext_0" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator" + [(reg FLAGS_REG) (const_int 0)]) + (match_operand:SI 1 "register_operand" "0")))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "adc{l}\t{$0, %k0|%k0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "SI")]) + ;; There is no point to generate ADCX instruction. ADC is shorter and faster. (define_insn "addcarry<mode>" @@ -6926,6 +6954,20 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "<MODE>")]) +(define_insn "*sub<mode>3_carry_0" + [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") + (minus:SWI + (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operator:SWI 3 "ix86_carry_flag_operator" + [(match_operand 2 "flags_reg_operand") (const_int 0)]))) + (clobber (reg:CC FLAGS_REG))] + "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)" + "sbb{<imodesuffix>}\t{$0, %0|%0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "<MODE>")]) + (define_insn "*subsi3_carry_zext" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI @@ -6943,6 +6985,21 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) +(define_insn "*subsi3_carry_zext_0" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (minus:SI + (match_operand:SI 1 "register_operand" "0") + (match_operator:SI 2 "ix86_carry_flag_operator" + [(reg FLAGS_REG) (const_int 0)])))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "sbb{l}\t{$0, %k0|%k0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "SI")]) + (define_insn "sub<mode>3_carry_ccc" [(set (reg:CCC FLAGS_REG) (compare:CCC diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 78a1ebb..62111d4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2018-03-28 Jakub Jelinek <jakub@redhat.com> + PR target/85095 + * gcc.target/i386/pr85095-1.c: New test. + * gcc.target/i386/pr85095-2.c: New test. + * gcc.c-torture/execute/pr85095.c: New test. + PR tree-optimization/82004 * gcc.dg/pr82004.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr85095.c b/gcc/testsuite/gcc.c-torture/execute/pr85095.c new file mode 100644 index 0000000..8b78b58 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr85095.c @@ -0,0 +1,52 @@ +/* PR target/85095 */ + +__attribute__((noipa)) unsigned long +f1 (unsigned long a, unsigned long b) +{ + unsigned long i = __builtin_add_overflow (a, b, &a); + return a + i; +} + +__attribute__((noipa)) unsigned long +f2 (unsigned long a, unsigned long b) +{ + unsigned long i = __builtin_add_overflow (a, b, &a); + return a - i; +} + +__attribute__((noipa)) unsigned long +f3 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a + i; +} + +__attribute__((noipa)) unsigned long +f4 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a - i; +} + +int +main () +{ + if (f1 (16UL, -18UL) != -2UL + || f1 (16UL, -17UL) != -1UL + || f1 (16UL, -16UL) != 1UL + || f1 (16UL, -15UL) != 2UL + || f2 (24UL, -26UL) != -2UL + || f2 (24UL, -25UL) != -1UL + || f2 (24UL, -24UL) != -1UL + || f2 (24UL, -23UL) != 0UL + || f3 (32U, -34U) != -2U + || f3 (32U, -33U) != -1U + || f3 (32U, -32U) != 1U + || f3 (32U, -31U) != 2U + || f4 (35U, -37U) != -2U + || f4 (35U, -36U) != -1U + || f4 (35U, -35U) != -1U + || f4 (35U, -34U) != 0U) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr85095-1.c b/gcc/testsuite/gcc.target/i386/pr85095-1.c new file mode 100644 index 0000000..4c882e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr85095-1.c @@ -0,0 +1,33 @@ +/* PR target/85095 * +/* { dg-do compile } */ +/* { dg-options "-O2 -masm=att" } */ + +unsigned int +foo (unsigned int a, unsigned int b) +{ + a += b; + if (a < b) a++; + return a; +} + +#ifdef __x86_64__ +unsigned long long +bar (unsigned long long a, unsigned long long b) +{ + a += b; + if (a < b) a++; + return a; +} + +unsigned long long +baz (unsigned int a, unsigned int b) +{ + a += b; + if (a < b) a++; + return a; +} +#endif + +/* { dg-final { scan-assembler-times "adcl\t\\\$0," 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "adcl\t\\\$0," 2 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "adcq\t\\\$0," 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr85095-2.c b/gcc/testsuite/gcc.target/i386/pr85095-2.c new file mode 100644 index 0000000..fbd7992 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr85095-2.c @@ -0,0 +1,54 @@ +/* PR target/85095 * +/* { dg-do compile } */ +/* { dg-options "-O2 -masm=att" } */ + +unsigned int +f1 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a + i; +} + +unsigned int +f2 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a - i; +} + +#ifdef __x86_64__ +unsigned long long +f3 (unsigned long long a, unsigned long long b) +{ + unsigned long long i = __builtin_add_overflow (a, b, &a); + return a + i; +} + +unsigned long long +f4 (unsigned long long a, unsigned long long b) +{ + unsigned long long i = __builtin_add_overflow (a, b, &a); + return a - i; +} + +unsigned long long +f5 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a + i; +} + +unsigned long long +f6 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a - i; +} +#endif + +/* { dg-final { scan-assembler-times "adcl\t\\\$0," 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "sbbl\t\\\$0," 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "adcl\t\\\$0," 2 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "sbbl\t\\\$0," 2 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "adcq\t\\\$0," 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "sbbq\t\\\$0," 1 { target { ! ia32 } } } } */ |