]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR target/85095 (worse code generated)
authorJakub Jelinek <jakub@redhat.com>
Fri, 22 Jun 2018 21:02:07 +0000 (23:02 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 22 Jun 2018 21:02:07 +0000 (23:02 +0200)
Backported from mainline
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.

* 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: r261942

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr85095.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr85095-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr85095-2.c [new file with mode: 0644]

index 95a00693a56cd9becbc53be6d665e8fefee31d70..05e9df4ee30abd16e5b4acec3147f870e7a05f8f 100644 (file)
@@ -1,6 +1,12 @@
 2018-06-22  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       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.
+
        2018-03-23  Jakub Jelinek  <jakub@redhat.com>
 
        PR inline-asm/85022
index 191f3f1b2024f9953aa1942dd5233e1d102c482a..5d0cd5311b7c2b25c7274afbe5a9c0c37050e82b 100644 (file)
    (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
    (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>"
    (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
    (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 "subborrow<mode>"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
index fbd33d85f3b1cd87939cfe07edf4ed4fce330e5d..d3eb5b9300979db22cddf88688515140108fa2ae 100644 (file)
@@ -1,6 +1,13 @@
 2018-06-22  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       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.
+
        2018-03-27  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/85076
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr85095.c b/gcc/testsuite/gcc.c-torture/execute/pr85095.c
new file mode 100644 (file)
index 0000000..abcb178
--- /dev/null
@@ -0,0 +1,52 @@
+/* PR target/85095 */
+
+__attribute__((noinline, noclone)) unsigned long
+f1 (unsigned long a, unsigned long b)
+{
+  unsigned long i = __builtin_add_overflow (a, b, &a);
+  return a + i;
+}
+
+__attribute__((noinline, noclone)) unsigned long
+f2 (unsigned long a, unsigned long b)
+{
+  unsigned long i = __builtin_add_overflow (a, b, &a);
+  return a - i;
+}
+
+__attribute__((noinline, noclone)) unsigned long
+f3 (unsigned int a, unsigned int b)
+{
+  unsigned int i = __builtin_add_overflow (a, b, &a);
+  return a + i;
+}
+
+__attribute__((noinline, noclone)) 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 (file)
index 0000000..4c882e0
--- /dev/null
@@ -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 (file)
index 0000000..fbd7992
--- /dev/null
@@ -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 } } } } */