Hi!
On 2025-02-27T21:51:11+0100, I wrote:
> With '-mfake-ptx-alloca' enabled, the user-visible behavior changes only
> for configurations where PTX 'alloca' is not available. Rather than a
> compile-time 'sorry, unimplemented: dynamic stack allocation not supported'
> in presence of dynamic stack allocation, compilation and assembly then
> succeeds. However, attempting to link in such '*.o' files then fails due
> to unresolved symbol '__GCC_nvptx__PTX_alloca_not_supported'.
>
> This is meant to be used in scenarios where large volumes of code are
> compiled, a small fraction of which runs into dynamic stack allocation, but
> these parts are not important for specific use cases, and we'd thus like the
> build to succeed, and error out just upon actual, very rare use of the
> offending '*.o' files.
This can be tuned further; I've pushed to trunk branch
commit 199f1abeef579912b4c40c42519825cedca6530f
"nvptx: Support '-mfake-ptx-alloca': defer failure to run-time 'alloca' usage",
see attached.
Similar to the implicit FAIL -> UNSUPPORTED due to compile-time detection
of 'sorry, unimplemented: dynamic stack allocation not supported' in
'gcc/testsuite/lib/gcc-dg.exp:gcc-dg-prune', we should also be able to
implement a corrsponding thing for this run-time failure, via new
machinery in the replacement 'gcc/testsuite/lib/gcc-dg.exp:${tool}_load',
via scanning and modifying 'result'. (..., but I'm not working on that
right now.)
Grüße
Thomas
>From 199f1abeef579912b4c40c42519825cedca6530f Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <[email protected]>
Date: Sun, 6 Apr 2025 17:44:18 +0200
Subject: [PATCH] nvptx: Support '-mfake-ptx-alloca': defer failure to run-time
'alloca' usage
Follow-up to commit 1146410c0feb0e82c689b1333fdf530a2b34dc2b
"nvptx: Support '-mfake-ptx-alloca'". '-mfake-ptx-alloca' is applicable only
for configurations where PTX 'alloca' is not supported, where target libraries
are built with it enabled (that is, libstdc++, libgfortran).
This change progresses:
[-FAIL:-]{+PASS:+} g++.dg/tree-ssa/pr20458.C -std=gnu++17 (test for excess errors)
[-UNRESOLVED:-]{+PASS:+} g++.dg/tree-ssa/pr20458.C -std=gnu++17 [-compilation failed to produce executable-]{+execution test+}
[-FAIL:-]{+PASS:+} g++.dg/tree-ssa/pr20458.C -std=gnu++26 (test for excess errors)
[-UNRESOLVED:-]{+PASS:+} g++.dg/tree-ssa/pr20458.C -std=gnu++26 [-compilation failed to produce executable-]{+execution test+}
UNSUPPORTED: g++.dg/tree-ssa/pr20458.C -std=gnu++98: exception handling not supported
..., and "enables" a few test cases:
FAIL: g++.old-deja/g++.other/sibcall1.C -std=gnu++17 (test for excess errors)
[Etc.]
FAIL: g++.old-deja/g++.other/unchanging1.C -std=gnu++17 (test for excess errors)
[Etc.]
..., which now (unrelatedly to 'alloca', and in the same way as configurations
where PTX 'alloca' is supported) FAIL due to:
unresolved symbol _Unwind_DeleteException
collect2: error: ld returned 1 exit status
Most importantly, it progresses ~830 libstdc++ test cases:
[-FAIL:-]{+PASS:+} [...] (test for excess errors)
..., with (if applicable, for most of them):
[-UNRESOLVED:-]{+PASS:+} [...] [-compilation failed to produce executable-]{+execution test+}
..., or just a few 'FAIL: [...] execution test' where these test cases also
FAIL in configurations where PTX 'alloca' is supported, or ~120 instances of
'FAIL: [...] execution test' due to run-time
'GCC/nvptx: sorry, unimplemented: dynamic stack allocation not supported'.
This change also resolves the cases noted in
commit bac2d8a246892334e24dfa7d62be0cd0648c5606
"nvptx: Build libgfortran with '-mfake-ptx-alloca' [PR107635]":
| With '-mfake-ptx-alloca', libgfortran again succeeds to build, and compared
| to before, we've got only a small number of regressions due to nvptx 'ld'
| complaining about 'unresolved symbol __GCC_nvptx__PTX_alloca_not_supported':
|
| [-PASS:-]{+FAIL:+} gfortran.dg/coarray/codimension_2.f90 -fcoarray=lib -O2 -lcaf_single (test for excess errors)
[-FAIL:-]{+PASS:+} gfortran.dg/coarray/codimension_2.f90 -fcoarray=lib -O2 -lcaf_single (test for excess errors)
| [-PASS:-]{+FAIL:+} gfortran.dg/coarray/event_4.f08 -fcoarray=lib -O2 -lcaf_single (test for excess errors)
| [-PASS:-]{+UNRESOLVED:+} gfortran.dg/coarray/event_4.f08 -fcoarray=lib -O2 -lcaf_single [-execution test-]{+compilation failed to produce executable+}
[-FAIL:-]{+PASS:+} gfortran.dg/coarray/event_4.f08 -fcoarray=lib -O2 -lcaf_single (test for excess errors)
[-UNRESOLVED:-]{+PASS:+} gfortran.dg/coarray/event_4.f08 -fcoarray=lib -O2 -lcaf_single [-compilation failed to produce executable-]{+execution test+}
| [-PASS:-]{+FAIL:+} gfortran.dg/coarray/fail_image_2.f08 -fcoarray=lib -O2 -lcaf_single (test for excess errors)
| [-PASS:-]{+UNRESOLVED:+} gfortran.dg/coarray/fail_image_2.f08 -fcoarray=lib -O2 -lcaf_single [-execution test-]{+compilation failed to produce executable+}
[-FAIL:-]{+PASS:+} gfortran.dg/coarray/fail_image_2.f08 -fcoarray=lib -O2 -lcaf_single (test for excess errors)
[-UNRESOLVED:-]{+PASS:+} gfortran.dg/coarray/fail_image_2.f08 -fcoarray=lib -O2 -lcaf_single [-compilation failed to produce executable-]{+execution test+}
| [-PASS:-]{+FAIL:+} gfortran.dg/coarray/proc_pointer_assign_1.f90 -fcoarray=lib -O2 -lcaf_single (test for excess errors)
| [-PASS:-]{+UNRESOLVED:+} gfortran.dg/coarray/proc_pointer_assign_1.f90 -fcoarray=lib -O2 -lcaf_single [-execution test-]{+compilation failed to produce executable+}
[-FAIL:-]{+PASS:+} gfortran.dg/coarray/proc_pointer_assign_1.f90 -fcoarray=lib -O2 -lcaf_single (test for excess errors)
[-UNRESOLVED:-]{+PASS:+} gfortran.dg/coarray/proc_pointer_assign_1.f90 -fcoarray=lib -O2 -lcaf_single [-compilation failed to produce executable-]{+execution test+}
| [-PASS:-]{+FAIL:+} gfortran.dg/coarray_43.f90 -O (test for excess errors)
[-FAIL:-]{+PASS:+} gfortran.dg/coarray_43.f90 -O (test for excess errors)
..., and further progresses:
[-FAIL:-]{+PASS:+} gfortran.dg/coarray_lib_comm_1.f90 -O0 (test for excess errors)
[-UNRESOLVED:-]{+FAIL:+} gfortran.dg/coarray_lib_comm_1.f90 -O0 [-compilation failed to produce executable-]{+execution test+}
[Etc.]
..., which now (unrelatedly to 'alloca', and in the same way as configurations
where PTX 'alloca' is supported) FAILs due to:
error : Prototype doesn't match for '_gfortran_caf_transfer_between_remotes' in 'input file 9 at offset 159897', first defined in 'input file 9 at offset 159897'
error : Prototype doesn't match for '_gfortran_caf_stop_numeric' in 'input file 9 at offset 159897', first defined in 'input file 9 at offset 159897'
nvptx-run: cuLinkAddData failed: device kernel image is invalid (CUDA_ERROR_INVALID_SOURCE, 300)
gcc/
* config/nvptx/nvptx.opt (-mfake-ptx-alloca): Update.
gcc/testsuite/
* gcc.target/nvptx/alloca-2-O0_-mfake-ptx-alloca.c: Adjust.
libgcc/
* config/nvptx/alloca.c: New.
* config/nvptx/t-nvptx (LIB2ADD): Add it.
---
gcc/config/nvptx/nvptx.opt | 10 ++---
.../nvptx/alloca-2-O0_-mfake-ptx-alloca.c | 7 ++--
libgcc/config/nvptx/alloca.c | 38 +++++++++++++++++++
libgcc/config/nvptx/t-nvptx | 3 +-
4 files changed, 49 insertions(+), 9 deletions(-)
create mode 100644 libgcc/config/nvptx/alloca.c
diff --git a/gcc/config/nvptx/nvptx.opt b/gcc/config/nvptx/nvptx.opt
index 02d36b33025b..9be81aecdddf 100644
--- a/gcc/config/nvptx/nvptx.opt
+++ b/gcc/config/nvptx/nvptx.opt
@@ -173,12 +173,12 @@ Target Var(nvptx_fake_ptx_alloca) Init(0) Undocumented
; With '-mfake-ptx-alloca' enabled, the user-visible behavior changes only
; for configurations where PTX 'alloca' is not available. Rather than a
; compile-time 'sorry, unimplemented: dynamic stack allocation not supported'
-; in presence of dynamic stack allocation, compilation and assembly then
-; succeeds. However, attempting to link in such '*.o' files then fails due
-; to unresolved symbol '__GCC_nvptx__PTX_alloca_not_supported'.
+; in presence of dynamic stack allocation, with '-mfake-ptx-alloca' enabled,
+; compilation, assembly, and linking succeeds, as does execution, in case that
+; 'alloca' is not attempted (if only used in error code paths, for example),
+; and a run-time failure only in case that 'alloca' is actually attempted.
;
; This is meant to be used in scenarios where large volumes of code are
; compiled, a small fraction of which runs into dynamic stack allocation, but
; these parts are not important for specific use cases, and we'd thus like the
-; build to succeed, and error out just upon actual, very rare use of the
-; offending '*.o' files.
+; build to succeed, and error out just upon actual, very rare use of 'alloca'.
diff --git a/gcc/testsuite/gcc.target/nvptx/alloca-2-O0_-mfake-ptx-alloca.c b/gcc/testsuite/gcc.target/nvptx/alloca-2-O0_-mfake-ptx-alloca.c
index 4cc4d0c93f28..92562cde4008 100644
--- a/gcc/testsuite/gcc.target/nvptx/alloca-2-O0_-mfake-ptx-alloca.c
+++ b/gcc/testsuite/gcc.target/nvptx/alloca-2-O0_-mfake-ptx-alloca.c
@@ -1,4 +1,4 @@
-/* { dg-do link } */
+/* { dg-do run } */
/* { dg-options {-O0 -mno-soft-stack} } */
/* { dg-additional-options -march=sm_30 } */
/* { dg-additional-options -mfake-ptx-alloca } */
@@ -13,6 +13,7 @@ main(void)
/* { dg-final { scan-assembler-times {(?n)^\.extern \.func \(\.param\.u64 %value_out\) __GCC_nvptx__PTX_alloca_not_supported \(\.param\.u64 %in_ar0\);$} 1 } } */
-/* { dg-message __GCC_nvptx__PTX_alloca_not_supported {unresolved symbol} { target *-*-* } 0 } */
+/* { dg-bogus __GCC_nvptx__PTX_alloca_not_supported {unresolved symbol} { target *-*-* } 0 } */
-/* { dg-final output-exists-not } */
+/* { dg-output {GCC/nvptx: sorry, unimplemented: dynamic stack allocation not supported[\r\n]+} }
+ { dg-shouldfail __GCC_nvptx__PTX_alloca_not_supported } */
diff --git a/libgcc/config/nvptx/alloca.c b/libgcc/config/nvptx/alloca.c
new file mode 100644
index 000000000000..09bdeb682859
--- /dev/null
+++ b/libgcc/config/nvptx/alloca.c
@@ -0,0 +1,38 @@
+/* Fake 'alloca' implementation.
+
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+ This file is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3, or (at your option) any
+ later version.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* For '-mfake-ptx-alloca', in case real PTX 'alloca' is not available.
+ With this function defined, we don't get a link-time failure
+ (unresolved symbol '__GCC_nvptx__PTX_alloca_not_supported'), but rather:
+ successful execution, in case that 'alloca' is not attempted (if only used
+ in error code paths, for example), and a run-time failure only in case that
+ 'alloca' is actually attempted. */
+
+void *
+__GCC_nvptx__PTX_alloca_not_supported (__SIZE_TYPE__ size __attribute__ ((unused)))
+{
+ __builtin_printf ("GCC/nvptx: sorry, unimplemented:"
+ " dynamic stack allocation not supported\n");
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgcc/config/nvptx/t-nvptx b/libgcc/config/nvptx/t-nvptx
index f295898d69fc..5e2e27898fd6 100644
--- a/libgcc/config/nvptx/t-nvptx
+++ b/libgcc/config/nvptx/t-nvptx
@@ -1,7 +1,8 @@
LIB2ADD=$(srcdir)/config/nvptx/reduction.c \
$(srcdir)/config/nvptx/mgomp.c \
$(srcdir)/config/nvptx/atomic.c \
- $(srcdir)/config/nvptx/unwind-nvptx.c
+ $(srcdir)/config/nvptx/unwind-nvptx.c \
+ $(srcdir)/config/nvptx/alloca.c
LIB2ADDEH=
LIB2FUNCS_EXCLUDE=
--
2.34.1