Commit 0a5c6d78 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 30a2c10e
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.
......
......@@ -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
......
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.
......
/* 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;
}
/* 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 } } } } */
/* 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 } } } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment