diff mbox series

Add peephole to eliminate redundant comparison after cmpccxadd.

Message ID 20230711031356.3066611-1-hongtao.liu@intel.com
State New
Headers show
Series Add peephole to eliminate redundant comparison after cmpccxadd. | expand

Commit Message

Liu, Hongtao July 11, 2023, 3:13 a.m. UTC
Similar like we did for cmpxchg, but extended to all
ix86_comparison_int_operator since cmpccxadd set EFLAGS exactly same
as CMP.

Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,},
Ok for trunk?

gcc/ChangeLog:

	PR target/110591
	* config/i386/sync.md (cmpccxadd_<mode>): Add a new
	define_peephole2 after the pattern.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/pr110591.c: New test.
---
 gcc/config/i386/sync.md                  | 56 ++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr110591.c | 66 ++++++++++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr110591.c

Comments

Hongtao Liu July 11, 2023, 3:23 a.m. UTC | #1
Please ignore this patch, I'm testing another patch to separate non
swap operands case where a setcc is not needed in the peephole2.

On Tue, Jul 11, 2023 at 11:14 AM liuhongt via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Similar like we did for cmpxchg, but extended to all
> ix86_comparison_int_operator since cmpccxadd set EFLAGS exactly same
> as CMP.
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,},
> Ok for trunk?
>
> gcc/ChangeLog:
>
>         PR target/110591
>         * config/i386/sync.md (cmpccxadd_<mode>): Add a new
>         define_peephole2 after the pattern.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/i386/pr110591.c: New test.
> ---
>  gcc/config/i386/sync.md                  | 56 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr110591.c | 66 ++++++++++++++++++++++++
>  2 files changed, 122 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr110591.c
>
> diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md
> index e1fa1504deb..43f6421bcb8 100644
> --- a/gcc/config/i386/sync.md
> +++ b/gcc/config/i386/sync.md
> @@ -1105,3 +1105,59 @@ (define_insn "cmpccxadd_<mode>"
>    output_asm_insn (buf, operands);
>    return "";
>  })
> +
> +(define_peephole2
> +  [(set (match_operand:SWI48x 0 "register_operand")
> +       (match_operand:SWI48x 1 "x86_64_general_operand"))
> +   (parallel [(set (match_dup 0)
> +                  (unspec_volatile:SWI48x
> +                    [(match_operand:SWI48x 2 "memory_operand")
> +                     (match_dup 0)
> +                     (match_operand:SWI48x 3 "register_operand")
> +                     (match_operand:SI 4 "const_int_operand")]
> +                    UNSPECV_CMPCCXADD))
> +             (set (match_dup 2)
> +                  (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD))
> +             (clobber (reg:CC FLAGS_REG))])
> +   (set (reg FLAGS_REG)
> +       (compare (match_operand:SWI48x 5 "register_operand")
> +                (match_operand:SWI48x 6 "x86_64_general_operand")))
> +   (set (match_operand:QI 7 "nonimmediate_operand")
> +       (match_operator:QI 8 "ix86_comparison_int_operator"
> +         [(reg FLAGS_REG) (const_int 0)]))]
> +  "TARGET_CMPCCXADD && TARGET_64BIT
> +   && ((rtx_equal_p (operands[0], operands[5])
> +       && rtx_equal_p (operands[1], operands[6]))
> +       || ((rtx_equal_p (operands[0], operands[6])
> +           && rtx_equal_p (operands[1], operands[5]))
> +          && peep2_regno_dead_p (4, FLAGS_REG)))"
> +  [(set (match_dup 0)
> +       (match_dup 1))
> +   (parallel [(set (match_dup 0)
> +                  (unspec_volatile:SWI48x
> +                    [(match_dup 2)
> +                     (match_dup 0)
> +                     (match_dup 3)
> +                     (match_dup 4)]
> +                    UNSPECV_CMPCCXADD))
> +             (set (match_dup 2)
> +                  (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD))
> +             (clobber (reg:CC FLAGS_REG))])
> +   (set (match_dup 7)
> +       (match_op_dup 8
> +         [(match_dup 9) (const_int 0)]))]
> +{
> +  operands[9] = gen_rtx_REG (GET_MODE (XEXP (operands[8], 0)), FLAGS_REG);
> +  if (rtx_equal_p (operands[0], operands[6])
> +     && rtx_equal_p (operands[1], operands[5])
> +     && swap_condition (GET_CODE (operands[8])) != GET_CODE (operands[8]))
> +     {
> +       operands[8] = shallow_copy_rtx (operands[8]);
> +       enum rtx_code ccode = swap_condition (GET_CODE (operands[8]));
> +       PUT_CODE (operands[8], ccode);
> +       operands[9] = gen_rtx_REG (SELECT_CC_MODE (ccode,
> +                                                 operands[6],
> +                                                 operands[5]),
> +                                  FLAGS_REG);
> +     }
> +})
> diff --git a/gcc/testsuite/gcc.target/i386/pr110591.c b/gcc/testsuite/gcc.target/i386/pr110591.c
> new file mode 100644
> index 00000000000..32a515b429e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr110591.c
> @@ -0,0 +1,66 @@
> +/* { dg-do compile { target { ! ia32 } } } */
> +/* { dg-options "-mcmpccxadd -O2" } */
> +/* { dg-final { scan-assembler-not {cmp[lq]?[ \t]+} } } */
> +/* { dg-final { scan-assembler-times {cmpoxadd[ \t]+} 12 } } */
> +
> +#include <immintrin.h>
> +
> +_Bool foo_setg (int *ptr, int v)
> +{
> +    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) > v;
> +}
> +
> +_Bool foo_setl (int *ptr, int v)
> +{
> +    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) < v;
> +}
> +
> +_Bool foo_sete(int *ptr, int v)
> +{
> +    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) == v;
> +}
> +
> +_Bool foo_setne(int *ptr, int v)
> +{
> +    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) != v;
> +}
> +
> +_Bool foo_setge(int *ptr, int v)
> +{
> +    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) >= v;
> +}
> +
> +_Bool foo_setle(int *ptr, int v)
> +{
> +    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) <= v;
> +}
> +
> +_Bool fooq_setg (long long *ptr, long long v)
> +{
> +    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) > v;
> +}
> +
> +_Bool fooq_setl (long long *ptr, long long v)
> +{
> +    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) < v;
> +}
> +
> +_Bool fooq_sete(long long *ptr, long long v)
> +{
> +    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) == v;
> +}
> +
> +_Bool fooq_setne(long long *ptr, long long v)
> +{
> +    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) != v;
> +}
> +
> +_Bool fooq_setge(long long *ptr, long long v)
> +{
> +    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) >= v;
> +}
> +
> +_Bool fooq_setle(long long *ptr, long long v)
> +{
> +    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) <= v;
> +}
> --
> 2.39.1.388.g2fc9e9ca3c
>
diff mbox series

Patch

diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md
index e1fa1504deb..43f6421bcb8 100644
--- a/gcc/config/i386/sync.md
+++ b/gcc/config/i386/sync.md
@@ -1105,3 +1105,59 @@  (define_insn "cmpccxadd_<mode>"
   output_asm_insn (buf, operands);
   return "";
 })
+
+(define_peephole2
+  [(set (match_operand:SWI48x 0 "register_operand")
+	(match_operand:SWI48x 1 "x86_64_general_operand"))
+   (parallel [(set (match_dup 0)
+		   (unspec_volatile:SWI48x
+		     [(match_operand:SWI48x 2 "memory_operand")
+		      (match_dup 0)
+		      (match_operand:SWI48x 3 "register_operand")
+		      (match_operand:SI 4 "const_int_operand")]
+		     UNSPECV_CMPCCXADD))
+	      (set (match_dup 2)
+		   (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD))
+	      (clobber (reg:CC FLAGS_REG))])
+   (set (reg FLAGS_REG)
+	(compare (match_operand:SWI48x 5 "register_operand")
+		 (match_operand:SWI48x 6 "x86_64_general_operand")))
+   (set (match_operand:QI 7 "nonimmediate_operand")
+	(match_operator:QI 8 "ix86_comparison_int_operator"
+	  [(reg FLAGS_REG) (const_int 0)]))]
+  "TARGET_CMPCCXADD && TARGET_64BIT
+   && ((rtx_equal_p (operands[0], operands[5])
+	&& rtx_equal_p (operands[1], operands[6]))
+       || ((rtx_equal_p (operands[0], operands[6])
+	    && rtx_equal_p (operands[1], operands[5]))
+	   && peep2_regno_dead_p (4, FLAGS_REG)))"
+  [(set (match_dup 0)
+	(match_dup 1))
+   (parallel [(set (match_dup 0)
+		   (unspec_volatile:SWI48x
+		     [(match_dup 2)
+		      (match_dup 0)
+		      (match_dup 3)
+		      (match_dup 4)]
+		     UNSPECV_CMPCCXADD))
+	      (set (match_dup 2)
+		   (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD))
+	      (clobber (reg:CC FLAGS_REG))])
+   (set (match_dup 7)
+	(match_op_dup 8
+	  [(match_dup 9) (const_int 0)]))]
+{
+  operands[9] = gen_rtx_REG (GET_MODE (XEXP (operands[8], 0)), FLAGS_REG);
+  if (rtx_equal_p (operands[0], operands[6])
+     && rtx_equal_p (operands[1], operands[5])
+     && swap_condition (GET_CODE (operands[8])) != GET_CODE (operands[8]))
+     {
+       operands[8] = shallow_copy_rtx (operands[8]);
+       enum rtx_code ccode = swap_condition (GET_CODE (operands[8]));
+       PUT_CODE (operands[8], ccode);
+       operands[9] = gen_rtx_REG (SELECT_CC_MODE (ccode,
+						  operands[6],
+						  operands[5]),
+				   FLAGS_REG);
+     }
+})
diff --git a/gcc/testsuite/gcc.target/i386/pr110591.c b/gcc/testsuite/gcc.target/i386/pr110591.c
new file mode 100644
index 00000000000..32a515b429e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr110591.c
@@ -0,0 +1,66 @@ 
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mcmpccxadd -O2" } */
+/* { dg-final { scan-assembler-not {cmp[lq]?[ \t]+} } } */
+/* { dg-final { scan-assembler-times {cmpoxadd[ \t]+} 12 } } */
+
+#include <immintrin.h>
+
+_Bool foo_setg (int *ptr, int v)
+{
+    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) > v;
+}
+
+_Bool foo_setl (int *ptr, int v)
+{
+    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) < v;
+}
+
+_Bool foo_sete(int *ptr, int v)
+{
+    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) == v;
+}
+
+_Bool foo_setne(int *ptr, int v)
+{
+    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) != v;
+}
+
+_Bool foo_setge(int *ptr, int v)
+{
+    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) >= v;
+}
+
+_Bool foo_setle(int *ptr, int v)
+{
+    return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) <= v;
+}
+
+_Bool fooq_setg (long long *ptr, long long v)
+{
+    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) > v;
+}
+
+_Bool fooq_setl (long long *ptr, long long v)
+{
+    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) < v;
+}
+
+_Bool fooq_sete(long long *ptr, long long v)
+{
+    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) == v;
+}
+
+_Bool fooq_setne(long long *ptr, long long v)
+{
+    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) != v;
+}
+
+_Bool fooq_setge(long long *ptr, long long v)
+{
+    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) >= v;
+}
+
+_Bool fooq_setle(long long *ptr, long long v)
+{
+    return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) <= v;
+}