Skip to content

Conversation

@jmmartinez
Copy link
Contributor

@jmmartinez jmmartinez commented Apr 28, 2025

Preprocessing the preprocessor output again interacts poorly with some flag combinations when we perform a separate preprocessing stage. In our case, -no-integrated-cpp -dD triggered this issue; but I guess that other flags could also trigger problems (-save-temps instead of -no-integrated-cpp).

Full context (which is quite weird I'll admit):

  • To cache OpenCL kernel compilation results, we use the -no-integrated-cpp for the driver to generate a separate preprocessing command (clang -E) before the rest of the compilation.
  • Some OpenCL C language features are implemented as macro definitions (in opencl-c-base.h). The semantic analysis queries the preprocessor to check if these are defined or not, for example, when we checks if a builtin is available when using -fdeclare-opencl-builtins.
  • To preserve these #define directives, on the preprocessor's output, we use -dD. However, other #define directives are also maintained besides OpenCL ones; which triggers the issue shown in this PR.

A better fix for our particular case could have been to move the language features implemented as macros into some sort of a flag to be used together with -fdeclare-opencl-builtins.
But I also thought that not preprocessing preprocessor outputs seemed like something desirable. I hope to work on this on a follow up.

@jmmartinez jmmartinez requested a review from lamb-j April 28, 2025 16:33
@jmmartinez jmmartinez self-assigned this Apr 28, 2025
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Apr 28, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 28, 2025

@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-clang-modules

@llvm/pr-subscribers-clang

Author: Juan Manuel Martinez Caamaño (jmmartinez)

Changes

This is a draft while I'm trying to figure out what's left to do.

This has issues with the test Modules/initializers.cpp.
The function CompilerInstance::createModuleFromSource creates a FrontendInput that "is preprocessed" from the preprocessed source string that is passed as argument (the module contents). However, this does not seem preprocessed (at least for this test).

InputKind::ModuleMap, /*Preprocessed*/true));

I'm not familiar with modules and I'm not sure if it's this patch, or the test that has issues.

Other failures are fixed with #137623


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

3 Files Affected:

  • (modified) clang/include/clang/Lex/Preprocessor.h (+5)
  • (modified) clang/lib/Frontend/InitPreprocessor.cpp (+7)
  • (added) clang/test/Preprocessor/preprocess-cpp-output.c (+10)
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index f2dfd3a349b8b..63774e48a468b 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -1831,6 +1831,11 @@ class Preprocessor {
     MacroExpansionInDirectivesOverride = true;
   }
 
+  void SetDisableMacroExpansion() {
+    DisableMacroExpansion = true;
+    MacroExpansionInDirectivesOverride = false;
+  }
+
   /// Peeks ahead N tokens and returns that token without consuming any
   /// tokens.
   ///
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 1f297f228fc1b..6693cfb469f82 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1556,6 +1556,13 @@ void clang::InitializePreprocessor(Preprocessor &PP,
                                    const PCHContainerReader &PCHContainerRdr,
                                    const FrontendOptions &FEOpts,
                                    const CodeGenOptions &CodeGenOpts) {
+
+  if (all_of(FEOpts.Inputs,
+             [](const FrontendInputFile &FI) { return FI.isPreprocessed(); })) {
+    PP.SetDisableMacroExpansion();
+    return;
+  }
+
   const LangOptions &LangOpts = PP.getLangOpts();
   std::string PredefineBuffer;
   PredefineBuffer.reserve(4080);
diff --git a/clang/test/Preprocessor/preprocess-cpp-output.c b/clang/test/Preprocessor/preprocess-cpp-output.c
new file mode 100644
index 0000000000000..2c180601e30ac
--- /dev/null
+++ b/clang/test/Preprocessor/preprocess-cpp-output.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -E -x c %s | FileCheck %s --check-prefixes=EXPANDED
+// RUN: %clang_cc1 -E -x cpp-output %s | FileCheck %s --check-prefixes=NOT-EXPANDED
+
+// EXPANDED: void __attribute__((__attribute__((always_inline)))) foo()
+// NOT-EXPANDED: void __attribute__((always_inline)) foo()
+
+#define always_inline __attribute__((always_inline))
+void __attribute__((always_inline)) foo() {
+    return 4;
+}

@jmmartinez jmmartinez requested a review from yxsamliu April 29, 2025 15:16
@shafik shafik requested review from cor3ntin and tahonermann April 29, 2025 17:19
@Bigcheese
Copy link
Contributor

module maps don't get preprocessed, so I don't think it matters what that is set to. For normal module.modulemap files Preprocessed is false. I think it's fine to remove the true and see if anything breaks, the preprocessor just skips over that section anyway.

@lamb-j
Copy link
Contributor

lamb-j commented May 9, 2025

module maps don't get preprocessed, so I don't think it matters what that is set to. For normal module.modulemap files Preprocessed is false. I think it's fine to remove the true and see if anything breaks, the preprocessor just skips over that section anyway.

Thanks for the pointer. @Bigcheese who should we solicit an approving review from? I'm not familiar enough with the implications of the change to feel confident approving

@jmmartinez
Copy link
Contributor Author

module maps don't get preprocessed, so I don't think it matters what that is set to. For normal module.modulemap files Preprocessed is false. I think it's fine to remove the true and see if anything breaks, the preprocessor just skips over that section anyway.

Currently a single test breaks: Modules/initializers.cpp which has preprocessor directives in the module source.

I guess then that this is an issue with the test. I'll try to propose a fix to the test then.

@jmmartinez jmmartinez force-pushed the draft/do-not-preprocess-cpp-output branch from 4ed49c6 to 09c37ac Compare May 13, 2025 13:50
@llvmbot llvmbot added the clang:modules C++20 modules and Clang Header Modules label May 13, 2025
@jmmartinez
Copy link
Contributor Author

I fixed the Modules/initializers.cpp test by moving the preprocessor directives outside of the module contents (the module contents should be already preprocessed and not contain preproc directives).

@cor3ntin
Copy link
Contributor

This seems reasonable. Can you update the description to explain the motivation for the change, though?
Is it a bug you are trying to fix, or a specific scenario you think should be optimized? Thanks

@jmmartinez
Copy link
Contributor Author

This seems reasonable. Can you update the description to explain the motivation for the change, though? Is it a bug you are trying to fix, or a specific scenario you think should be optimized? Thanks

I've updated the description with an explanation of the situation that triggered the issue for us. But in the wider scheme, I think that no preprocessing the preprocessor's output is the actual desired behavior.

Thanks!

@jmmartinez
Copy link
Contributor Author

Ping !

@cor3ntin
Copy link
Contributor

Ping !

Sorry, I missed that you replied last week

@jmmartinez jmmartinez requested a review from cor3ntin May 23, 2025 06:45
@jmmartinez jmmartinez force-pushed the draft/do-not-preprocess-cpp-output branch from 9099d6f to 1c9b89b Compare May 26, 2025 15:47
@llvmbot llvmbot added the clang:codegen IR generation bugs: mangling, exceptions, etc. label May 26, 2025
@jmmartinez jmmartinez force-pushed the draft/do-not-preprocess-cpp-output branch from 1c9b89b to 89ace07 Compare May 27, 2025 13:08
@jmmartinez jmmartinez requested a review from cor3ntin May 27, 2025 13:10
@jmmartinez jmmartinez force-pushed the draft/do-not-preprocess-cpp-output branch from 89ace07 to 335c604 Compare June 2, 2025 12:58
@jmmartinez
Copy link
Contributor Author

Hello ! I’m still exploring possible alternatives to this PR but I haven't found anything satisfying yet. If you have some suggestions don't hesitate. Thanks !

@cor3ntin cor3ntin requested a review from AaronBallman June 5, 2025 14:30
@jmmartinez jmmartinez force-pushed the draft/do-not-preprocess-cpp-output branch from 335c604 to 2298cdc Compare June 16, 2025 11:35
@jmmartinez jmmartinez force-pushed the draft/do-not-preprocess-cpp-output branch from ba24dc8 to fbe9e06 Compare July 7, 2025 15:04
@lamb-j
Copy link
Contributor

lamb-j commented Jul 22, 2025

@cor3ntin @AaronBallman any thoughts on this PR?

Aiming to land soon if there are no other objections

Copy link
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

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

LGTM. Please wait ~20h in case @AaronBallman @erichkeane have further comments

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

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

A nit and a question for the modules maintainers, but otherwise I think this looks good to me. Please don't land until @Bigcheese or @ChuanqiXu9 have had a chance to weigh in on the modules test question.

@jmmartinez jmmartinez force-pushed the draft/do-not-preprocess-cpp-output branch from 352f3f1 to 00c9355 Compare July 28, 2025 08:19
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

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

LGTM!

@jmmartinez jmmartinez merged commit 8b020d5 into llvm:main Jul 29, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:codegen IR generation bugs: mangling, exceptions, etc. clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants