Skip to content

Conversation

LuoYuanke
Copy link
Contributor

@LuoYuanke LuoYuanke commented Sep 30, 2025

Variadic argument for NVPTX has been support in
486d00e
We can remove the sema check in front-end.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Sep 30, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 30, 2025

@llvm/pr-subscribers-clang

Author: Luo, Yuanke (LuoYuanke)

Changes

Variadic argument for NVPTX has been support in
486d00e
We can remove the sema check in front-end


Full diff: https://github.com/llvm/llvm-project/pull/161350.diff

3 Files Affected:

  • (modified) clang/include/clang/Driver/Options.td (+1-1)
  • (modified) clang/lib/Sema/SemaDecl.cpp (-11)
  • (modified) clang/test/SemaCUDA/vararg.cu (+5-20)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 6245cf33a0719..323ffea5afa59 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -8729,7 +8729,7 @@ def fcuda_include_gpubinary : Separate<["-"], "fcuda-include-gpubinary">,
   HelpText<"Incorporate CUDA device-side binary into host object file.">,
   MarshallingInfoString<CodeGenOpts<"CudaGpuBinaryFileName">>;
 def fcuda_allow_variadic_functions : Flag<["-"], "fcuda-allow-variadic-functions">,
-  HelpText<"Allow variadic functions in CUDA device code.">,
+  HelpText<"Deprecated; Allow variadic functions in CUDA device code.">,
   MarshallingInfoFlag<LangOpts<"CUDAAllowVariadicFunctions">>;
 def fno_cuda_host_device_constexpr : Flag<["-"], "fno-cuda-host-device-constexpr">,
   HelpText<"Don't treat unattributed constexpr functions as __host__ __device__.">,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9ef7a2698913d..357af2a50e75b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11041,17 +11041,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
             << CUDA().getConfigureFuncName();
       Context.setcudaConfigureCallDecl(NewFD);
     }
-
-    // Variadic functions, other than a *declaration* of printf, are not allowed
-    // in device-side CUDA code, unless someone passed
-    // -fcuda-allow-variadic-functions.
-    if (!getLangOpts().CUDAAllowVariadicFunctions && NewFD->isVariadic() &&
-        (NewFD->hasAttr<CUDADeviceAttr>() ||
-         NewFD->hasAttr<CUDAGlobalAttr>()) &&
-        !(II && II->isStr("printf") && NewFD->isExternC() &&
-          !D.isFunctionDefinition())) {
-      Diag(NewFD->getLocation(), diag::err_variadic_device_fn);
-    }
   }
 
   MarkUnusedFileScopedDecl(NewFD);
diff --git a/clang/test/SemaCUDA/vararg.cu b/clang/test/SemaCUDA/vararg.cu
index 0238f42dc40a9..62693e1d4a0af 100644
--- a/clang/test/SemaCUDA/vararg.cu
+++ b/clang/test/SemaCUDA/vararg.cu
@@ -1,11 +1,9 @@
 // REQUIRES: x86-registered-target
 // REQUIRES: nvptx-registered-target
 // RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fcuda-is-device -fsyntax-only \
-// RUN:   -verify -DEXPECT_VA_ARG_ERR -DEXPECT_VARARG_ERR %s
+// RUN:   -verify -DEXPECT_VA_ARG_ERR %s
 // RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fcuda-is-device -fsyntax-only \
 // RUN:   -fcuda-allow-variadic-functions -verify -DEXPECT_VA_ARG_ERR %s
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify \
-// RUN:   -DEXPECT_VARARG_ERR %s
 
 #include <stdarg.h>
 #include "Inputs/cuda.h"
@@ -30,28 +28,15 @@ __device__ void baz() {
 #endif
 }
 
-__device__ void vararg(const char* x, ...) {}
-#ifdef EXPECT_VARARG_ERR
-// expected-error@-2 {{CUDA device code does not support variadic functions}}
-#endif
+__device__ void vararg(const char* x, ...) {} // OK
 
 template <typename T>
-__device__ void vararg(T t, ...) {}
-#ifdef EXPECT_VARARG_ERR
-// expected-error@-2 {{CUDA device code does not support variadic functions}}
-#endif
+__device__ void vararg(T t, ...) {} // OK
 
 extern "C" __device__ int printf(const char* fmt, ...);  // OK, special case.
 
-// Definition of printf not allowed.
-extern "C" __device__ int printf(const char* fmt, ...) { return 0; }
-#ifdef EXPECT_VARARG_ERR
-// expected-error@-2 {{CUDA device code does not support variadic functions}}
-#endif
+extern "C" __device__ int printf(const char* fmt, ...) { return 0; } // OK
 
 namespace ns {
-__device__ int printf(const char* fmt, ...);
-#ifdef EXPECT_VARARG_ERR
-// expected-error@-2 {{CUDA device code does not support variadic functions}}
-#endif
+__device__ int printf(const char* fmt, ...); // OK
 }

Variadic argument for NVPTX has been support in
llvm@486d00e
We can remove the sema check in front-end.
Copy link
Contributor

@jhuber6 jhuber6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect this to completely remove usage of CUDAAllowVariadicFunctions and remove the associated driver handling code. That way passing it will result in the generic 'argument unused' warning. Though, I don't know if there was anything special about the old handling, the 'new' handling is ABI compatible with it, so I'd assume not but just in case I'll refer to @Artem-B

@jhuber6 jhuber6 requested a review from Artem-B September 30, 2025 12:47
@JonChesterfield
Copy link
Collaborator

This seems legitimate to me. The IR pass is enabled on nvptx and turns LLVM variadics into functions which match the PTX variadic calling convention as far as I know. I think the guard is still there on CUDA because Joseph and I were mostly thinking in terms of freestanding C++ when we wrote this.

@LuoYuanke
Copy link
Contributor Author

I'd expect this to completely remove usage of CUDAAllowVariadicFunctions and remove the associated driver handling code. That way passing it will result in the generic 'argument unused' warning. Though, I don't know if there was anything special about the old handling, the 'new' handling is ABI compatible with it, so I'd assume not but just in case I'll refer to @Artem-B

If we completely remove CUDAAllowVariadicFunctions, I'm afraid it may break compiling legacy code which is specified the -fcuda-allow-variadic-functions option.

@jhuber6
Copy link
Contributor

jhuber6 commented Sep 30, 2025

If we completely remove CUDAAllowVariadicFunctions, I'm afraid it may break compiling legacy code which is specified the -fcuda-allow-variadic-functions option.

The driver and cc1 flag would still exist, it would just be completely unused. The only concern here would be if the old handling was ABI compatible, but I think all the old handling did was suppress the warning to allow emitting variadic function signatures or something.

@arsenm
Copy link
Contributor

arsenm commented Sep 30, 2025

I'd expect the -f flag behavior to be independent of what the backend supports. What does nvcc do? I'd expect it to require an opt-in or language standard flag

@jhuber6
Copy link
Contributor

jhuber6 commented Sep 30, 2025

Pretty sure nvcc CUDA handles it by default https://godbolt.org/z/abqWz6ans

Copy link
Member

Artem-B commented Sep 30, 2025

-fcuda-allow-variadic-functions should be deprecated and made hidden, but we should still keep it around to avoid breaking existing users.

ABI compatibility is likely not a major issue as most of CUDA compilations consist of a single TU, and the relatively rare RDC compilations are usually withing the same library compiled with the same compiler. Before the new clang driver showed up, there were virtually no users who'd be affected by the ABI break, as RDC compilation with clang required a lot of additional external build changes. I'm aware of only one actual use case (build of NCCL inside of XLA https://github.com/openxla/xla/blob/45947e2a819102aef04454fc24f311f8a50e1c6a/third_party/nccl/build_defs.bzl.tpl#L232) and that's the "one library, one compiler" scenario that's not affected by the ABI change.

I think all the old handling did was suppress the warning to allow emitting variadic function signatures or something.

It evolved over time. Initially it allowed accepting variadic functions during parsing, but did not allow to generate any code for them. This was needed as some CUDA code relied on variadic function declarations as a wildcard for the template instantiations.
Eventually we've implemented code generation for the variadic functions, and then allowed variadics by default.

@JonChesterfield
Copy link
Collaborator

There is no abi break here as far as I can tell.

The variadic lowering pass lays things out the same way cuda's printf works and matches the documentation on ptx. As in if you've written a variadic function in ptx, calling it from IR is expected to work.

Also, it's going from refuse to compile to does compile, so there's nominally no pre-existing code to be compatible with.

There may be bugs in the lowering pass. I really should revive the x86/aarch64 implementations and/or chase wasm to get it running on non-gpu targets.

Copy link
Contributor

@jhuber6 jhuber6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove the handling and keep the flag, it should be fine based off of what Artem said now that we handle this by default.

@LuoYuanke
Copy link
Contributor Author

Just remove the handling and keep the flag, it should be fine based off of what Artem said now that we handle this by default.

Yes, I think that's what this PR does.

@jhuber6
Copy link
Contributor

jhuber6 commented Oct 5, 2025

Just remove the handling and keep the flag, it should be fine based off of what Artem said now that we handle this by default.

Yes, I think that's what this PR does.

Am I missing something, we still have CUDAAllowVariadicFunctions.

@LuoYuanke
Copy link
Contributor Author

Am I missing something, we still have CUDAAllowVariadicFunctions.

I understand now. Revised.

@LuoYuanke LuoYuanke merged commit a406eb4 into llvm:main Oct 6, 2025
9 checks passed
@LuoYuanke LuoYuanke deleted the varadic-arg-decl branch October 6, 2025 06:07
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 6, 2025

LLVM Buildbot has detected a new failure on builder clang-m68k-linux-cross running on suse-gary-m68k-cross while building clang at step 5 "ninja check 1".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/27/builds/17063

Here is the relevant piece of the build log for the reference
Step 5 (ninja check 1) failure: stage 1 checked (failure)
...
[239/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/AST/DeclTest.cpp.o
[240/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/QualTypeNamesTest.cpp.o
[241/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/LookupTest.cpp.o
[242/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/AST/DeclPrinterTest.cpp.o
[243/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp.o
[244/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/AST/RecursiveASTVisitorTest.cpp.o
[245/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/DependencyScanning/DependencyScannerTest.cpp.o
[246/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/AST/SourceLocationTest.cpp.o
[247/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/AST/StructuralEquivalenceTest.cpp.o
[248/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/AST/ASTImporterTest.cpp.o
FAILED: tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/AST/ASTImporterTest.cpp.o 
/usr/bin/c++ -DGTEST_HAS_RTTI=0 -DLLVM_BUILD_STATIC -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/stage1/tools/clang/unittests -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/unittests -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/include -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/stage1/tools/clang/include -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/stage1/include -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/llvm/include -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/unittests/Tooling -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/third-party/unittest/googletest/include -I/var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/third-party/unittest/googlemock/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-dangling-reference -Wno-redundant-move -Wno-pessimizing-move -Wno-array-bounds -Wno-stringop-overread -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -O3 -DNDEBUG -std=c++17  -Wno-variadic-macros -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -Wno-suggest-override -MD -MT tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/AST/ASTImporterTest.cpp.o -MF tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/AST/ASTImporterTest.cpp.o.d -o tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/AST/ASTImporterTest.cpp.o -c /var/lib/buildbot/workers/suse-gary-m68k-cross/clang-m68k-linux-cross/llvm/clang/unittests/AST/ASTImporterTest.cpp
c++: fatal error: Killed signal terminated program cc1plus
compilation terminated.
[249/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp.o
[250/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp.o
[251/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RangeSelectorTest.cpp.o
[252/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/Concept.cpp.o
[253/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp.o
[254/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp.o
[255/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp.o
[256/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp.o
[257/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp.o
[258/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp.o
[259/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp.o
[260/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp.o
[261/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp.o
[262/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp.o
[263/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp.o
[264/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp.o
[265/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp.o
[266/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp.o
[267/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp.o
[268/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/Class.cpp.o
[269/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp.o
[270/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/Attr.cpp.o
[271/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp.o
[272/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp.o
[273/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp.o
[274/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/CallbacksBinaryOperator.cpp.o
[275/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/CallbacksUnaryOperator.cpp.o
[276/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/CallbacksLeaf.cpp.o
[277/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/ASTMatchers/ASTMatchersNodeTest.cpp.o
[278/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/CallbacksCompoundAssignOperator.cpp.o
[279/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/Tooling/RecursiveASTVisitorTests/CallbacksCallExpr.cpp.o
[280/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/ASTMatchers/ASTMatchersNarrowingTest.cpp.o
[281/442] Building CXX object tools/clang/unittests/CMakeFiles/AllClangUnitTests.dir/ASTMatchers/ASTMatchersTraversalTest.cpp.o
ninja: build stopped: subcommand failed.

aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 6, 2025
…lvm#161350)

Variadic argument for NVPTX has been support in
llvm@486d00e
We can remove `CUDAAllowVariadicFunctions` option and its sema check. The CC1 option
`fcuda_allow_variadic_functions` is retained to not break the existing code building.

---------

Co-authored-by: Yuanke Luo <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants