diff options
author | Tom de Vries <tdevries@suse.de> | 2022-02-03 14:00:02 +0100 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2022-02-08 09:54:30 +0100 |
commit | 04b54cc486cc6fcc40380445e500eaf46d7901dc (patch) | |
tree | e9b9461242182dd61d5342588d3e6b1673fc92f0 /gcc/config/nvptx/nvptx.cc | |
parent | 0af7ef050aed9f678d70d79931ede38374fde863 (diff) | |
download | gcc-04b54cc486cc6fcc40380445e500eaf46d7901dc.zip gcc-04b54cc486cc6fcc40380445e500eaf46d7901dc.tar.gz gcc-04b54cc486cc6fcc40380445e500eaf46d7901dc.tar.bz2 |
[nvptx] Fix .local atomic regressions
In PR target/104364, two problems were reported:
- in muniform-simt mode, an atom.cas insn is no longer executed in the
"master lane" only.
- in msoft-stack mode, an __atomic_compare_exchange_n on stack memory is
translated assuming it accesses local memory, while that's not the case.
Fix these by:
- ensuring that all insns with atomic attribute are also predicable, such
that the validate_change in nvptx_reorg_uniform_simt will succeed, and
asserting that it does, and
- guarding the local atomics implementation with a new function
nvptx_mem_local_p that correctly handles msoft-stack.
Tested on x86_64 with nvptx accelerator.
gcc/ChangeLog:
2022-02-04 Tom de Vries <tdevries@suse.de>
PR target/104364
* config/nvptx/nvptx-protos.h (nvptx_mem_local_p): Declare.
* config/nvptx/nvptx.cc (nvptx_reorg_uniform_simt): Assert that
change is validated.
(nvptx_mem_local_p): New function.
* config/nvptx/nvptx.md: Use nvptx_mem_local_p.
(define_c_enum "unspecv"): Add UNSPECV_CAS_LOCAL.
(define_insn "atomic_compare_and_swap<mode>_1_local"): New
non-atomic, non-predicable define_insn, factored out of ...
(define_insn "atomic_compare_and_swap<mode>_1"): ... here.
Make predicable again.
(define_expand "atomic_compare_and_swap<mode>"): Use
atomic_compare_and_swap<mode>_1_local.
gcc/testsuite/ChangeLog:
2022-02-04 Tom de Vries <tdevries@suse.de>
PR target/104364
* gcc.target/nvptx/softstack-2.c: New test.
* gcc.target/nvptx/uniform-simt-1.c: New test.
Diffstat (limited to 'gcc/config/nvptx/nvptx.cc')
-rw-r--r-- | gcc/config/nvptx/nvptx.cc | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc index b3bb97c..2a69492 100644 --- a/gcc/config/nvptx/nvptx.cc +++ b/gcc/config/nvptx/nvptx.cc @@ -3150,7 +3150,8 @@ nvptx_reorg_uniform_simt () rtx pred = nvptx_get_unisimt_predicate (); pred = gen_rtx_NE (BImode, pred, const0_rtx); pat = gen_rtx_COND_EXEC (VOIDmode, pred, pat); - validate_change (insn, &PATTERN (insn), pat, false); + bool changed_p = validate_change (insn, &PATTERN (insn), pat, false); + gcc_assert (changed_p); } } @@ -6894,6 +6895,28 @@ nvptx_libc_has_function (enum function_class fn_class, tree type) return default_libc_has_function (fn_class, type); } +bool +nvptx_mem_local_p (rtx mem) +{ + gcc_assert (GET_CODE (mem) == MEM); + + struct address_info info; + decompose_mem_address (&info, mem); + + if (info.base != NULL && REG_P (*info.base) + && REGNO_PTR_FRAME_P (REGNO (*info.base))) + { + if (TARGET_SOFT_STACK) + { + /* Frame-related doesn't mean local. */ + } + else + return true; + } + + return false; +} + #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE nvptx_option_override |