On Fri, Nov 12, 2021 at 8:13 AM Jakub Jelinek <ja...@redhat.com> wrote: > > On Fri, Nov 12, 2021 at 07:55:26AM -0800, H.J. Lu wrote: > > > I have following patch queued for testing for this... > > > > > > 2021-11-12 Jakub Jelinek <ja...@redhat.com> > > > > > > PR target/103205 > > > * config/i386/sync.md (atomic_bit_test_and_set<mode>, > > > atomic_bit_test_and_complement<mode>, > > > atomic_bit_test_and_reset<mode>): Use OPTAB_WIDEN instead of > > > OPTAB_DIRECT. > > > > > > * gcc.target/i386/pr103205.c: New test. > > > > Can you include my tests? Or you can leave out your test and I can check > > in my tests after your fix has been checked in. > > I'd prefer the latter. >
Here is the v2 patch on top of yours. -- H.J.
From 9520fa78ae04e845905d8bb2bab88cf429bf7840 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.to...@gmail.com> Date: Fri, 12 Nov 2021 07:21:43 -0800 Subject: [PATCH v2] Check optab before transforming atomic bit test and operations Check optab before transforming equivalent, but slighly different cases of atomic bit test and operations to their canonical forms. gcc/ PR target/103205 * tree-ssa-ccp.c (optimize_atomic_bit_test_and): Check optab before transforming equivalent, but slighly different cases to their canonical forms. gcc/testsuite/ PR target/103205 * gcc.target/i386/pr103205-1a.c: New test. * gcc.target/i386/pr103205-1b.c: Likewise. * gcc.target/i386/pr103205-2a.c: Likewise. * gcc.target/i386/pr103205-2b.c: Likewise. * gcc.target/i386/pr103205-3.c: Likewise. * gcc.target/i386/pr103205-4.c: Likewise. --- diff --git a/gcc/testsuite/gcc.target/i386/pr103205-1a.c b/gcc/testsuite/gcc.target/i386/pr103205-1a.c new file mode 100644 index 00000000000..3ea74b68059 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103205-1a.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=himode_math" } */ + +extern short foo; + +int +foo1 (void) +{ + return __sync_fetch_and_and(&foo, ~1) & 1; +} + +int +foo2 (void) +{ + return __sync_fetch_and_or (&foo, 1) & 1; +} + +int +foo3 (void) +{ + return __sync_fetch_and_xor (&foo, 1) & 1; +} + +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btrw" 1 } } */ +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btsw" 1 } } */ +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btcw" 1 } } */ +/* { dg-final { scan-assembler-not "cmpxchgw" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr103205-1b.c b/gcc/testsuite/gcc.target/i386/pr103205-1b.c new file mode 100644 index 00000000000..061ffb8f95f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103205-1b.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^himode_math" } */ + +#include "pr103205-1a.c" + +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btrw" 1 } } */ +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btsw" 1 } } */ +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btcw" 1 } } */ +/* { dg-final { scan-assembler-not "cmpxchgw" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr103205-2a.c b/gcc/testsuite/gcc.target/i386/pr103205-2a.c new file mode 100644 index 00000000000..4b2fb1f7c29 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103205-2a.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=himode_math" } */ + +extern unsigned short foo; + +unsigned short +foo1 (void) +{ + return __sync_fetch_and_and(&foo, ~1) & 1; +} + +unsigned short +foo2 (void) +{ + return __sync_fetch_and_or (&foo, 1) & 1; +} + +unsigned short +foo3 (void) +{ + return __sync_fetch_and_xor (&foo, 1) & 1; +} + +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btrw" 1 } } */ +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btsw" 1 } } */ +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btcw" 1 } } */ +/* { dg-final { scan-assembler-not "cmpxchgw" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr103205-2b.c b/gcc/testsuite/gcc.target/i386/pr103205-2b.c new file mode 100644 index 00000000000..0190d7c8c20 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103205-2b.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^himode_math" } */ + +#include "pr103205-2a.c" + +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btrw" 1 } } */ +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btsw" 1 } } */ +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btcw" 1 } } */ +/* { dg-final { scan-assembler-not "cmpxchgw" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr103205-3.c b/gcc/testsuite/gcc.target/i386/pr103205-3.c new file mode 100644 index 00000000000..8500f6d7e63 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103205-3.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern char foo; + +int +foo1 (void) +{ + return __sync_fetch_and_and(&foo, ~1) & 1; +} + +int +foo2 (void) +{ + return __sync_fetch_and_or (&foo, 1) & 1; +} + +int +foo3 (void) +{ + return __sync_fetch_and_xor (&foo, 1) & 1; +} + +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*cmpxchgb" 3 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr103205-4.c b/gcc/testsuite/gcc.target/i386/pr103205-4.c new file mode 100644 index 00000000000..e7f20c5ab7f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103205-4.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern char foo; + +unsigned char +foo1 (void) +{ + return __sync_fetch_and_and(&foo, ~1) & 1; +} + +unsigned char +foo2 (void) +{ + return __sync_fetch_and_or (&foo, 1) & 1; +} + +unsigned char +foo3 (void) +{ + return __sync_fetch_and_xor (&foo, 1) & 1; +} + +/* { dg-final { scan-assembler-times "lock;?\[ \t\]*cmpxchgb" 3 } } */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 0f79e9f05bd..fec68b5fc73 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -3366,6 +3366,21 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip, || !gimple_vdef (call)) return; + switch (fn) + { + case IFN_ATOMIC_BIT_TEST_AND_SET: + optab = atomic_bit_test_and_set_optab; + break; + case IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT: + optab = atomic_bit_test_and_complement_optab; + break; + case IFN_ATOMIC_BIT_TEST_AND_RESET: + optab = atomic_bit_test_and_reset_optab; + break; + default: + return; + } + tree bit = nullptr; mask = gimple_call_arg (call, 1); @@ -3384,6 +3399,10 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip, if (lhs != use_rhs) return; + if (optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs))) + == CODE_FOR_nothing) + return; + gimple *g; gimple_stmt_iterator gsi; tree var; @@ -3628,21 +3647,6 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip, } } - switch (fn) - { - case IFN_ATOMIC_BIT_TEST_AND_SET: - optab = atomic_bit_test_and_set_optab; - break; - case IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT: - optab = atomic_bit_test_and_complement_optab; - break; - case IFN_ATOMIC_BIT_TEST_AND_RESET: - optab = atomic_bit_test_and_reset_optab; - break; - default: - return; - } - if (optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs))) == CODE_FOR_nothing) return; -- 2.33.1