Author: Brandon Wu
Date: 2025-12-17T12:53:58+08:00
New Revision: fe577b1f3a47bf37ca58a924d9c03e35e68dc2ac

URL: 
https://github.com/llvm/llvm-project/commit/fe577b1f3a47bf37ca58a924d9c03e35e68dc2ac
DIFF: 
https://github.com/llvm/llvm-project/commit/fe577b1f3a47bf37ca58a924d9c03e35e68dc2ac.diff

LOG: [AST][RISCV] Preserve RISC-V intrinsic pragma in AST (#171981)

RISC-V vector intrinsic is generated dynamically at runtime, thus it's
note preserved in AST yet when using precompile header, neither do
information in SemaRISCV. We need to write these information to ast
record to be able to use precompile header for RISC-V.

Fixes #109634

Added: 
    clang/test/PCH/riscv-rvv-vectors.c

Modified: 
    clang/include/clang/Sema/Sema.h
    clang/include/clang/Serialization/ASTBitCodes.h
    clang/include/clang/Serialization/ASTReader.h
    clang/include/clang/Serialization/ASTWriter.h
    clang/lib/Serialization/ASTReader.cpp
    clang/lib/Serialization/ASTWriter.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 97a64561e7759..22d7fa4b9c500 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -66,6 +66,7 @@
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/SemaBase.h"
 #include "clang/Sema/SemaConcept.h"
+#include "clang/Sema/SemaRISCV.h"
 #include "clang/Sema/TypoCorrection.h"
 #include "clang/Sema/Weak.h"
 #include "llvm/ADT/APInt.h"

diff  --git a/clang/include/clang/Serialization/ASTBitCodes.h 
b/clang/include/clang/Serialization/ASTBitCodes.h
index b48f02c601889..5a86d540e5d0b 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -745,6 +745,9 @@ enum ASTRecordTypes {
   UPDATE_MODULE_LOCAL_VISIBLE = 76,
 
   UPDATE_TU_LOCAL_VISIBLE = 77,
+
+  /// Record code for #pragma clang riscv intrinsic vector.
+  RISCV_VECTOR_INTRINSICS_PRAGMA = 78,
 };
 
 /// Record types used within a source manager block.

diff  --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index d276f0d21b958..63f0fde60bb16 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -1079,6 +1079,9 @@ class ASTReader
   /// The IDs of all decls with function effects to be checked.
   SmallVector<GlobalDeclID> DeclsWithEffectsToVerify;
 
+  /// The RISC-V intrinsic pragma(including RVV, SiFive and Andes).
+  SmallVector<bool, 3> RISCVVecIntrinsicPragma;
+
 private:
   struct ImportedSubmodule {
     serialization::SubmoduleID ID;

diff  --git a/clang/include/clang/Serialization/ASTWriter.h 
b/clang/include/clang/Serialization/ASTWriter.h
index dbbfc29058f43..d3029373ed2f7 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -640,6 +640,7 @@ class ASTWriter : public ASTDeserializationListener,
   void WriteDeclsWithEffectsToVerify(Sema &SemaRef);
   void WriteModuleFileExtension(Sema &SemaRef,
                                 ModuleFileExtensionWriter &Writer);
+  void WriteRISCVIntrinsicPragmas(Sema &SemaRef);
 
   unsigned DeclParmVarAbbrev = 0;
   unsigned DeclContextLexicalAbbrev = 0;

diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index e8600d1e914cd..bbb9e2f95cac2 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -4465,6 +4465,22 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
       for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
         DeclsToCheckForDeferredDiags.insert(ReadDeclID(F, Record, I));
       break;
+
+    case RISCV_VECTOR_INTRINSICS_PRAGMA: {
+      unsigned NumRecords = Record.front();
+      // Last record which is used to keep number of valid records.
+      if (Record.size() - 1 != NumRecords)
+        return llvm::createStringError(std::errc::illegal_byte_sequence,
+                                       "invalid rvv intrinsic pragma record");
+
+      if (RISCVVecIntrinsicPragma.empty())
+        RISCVVecIntrinsicPragma.append(NumRecords, 0);
+      // There might be multiple precompiled modules imported, we need to union
+      // them all.
+      for (unsigned i = 0; i < NumRecords; ++i)
+        RISCVVecIntrinsicPragma[i] |= Record[i + 1];
+      break;
+    }
     }
   }
 }
@@ -9099,6 +9115,13 @@ void ASTReader::UpdateSema() {
         PointersToMembersPragmaLocation);
   }
   SemaObj->CUDA().ForceHostDeviceDepth = ForceHostDeviceDepth;
+  if (!RISCVVecIntrinsicPragma.empty()) {
+    assert(RISCVVecIntrinsicPragma.size() == 3 &&
+           "Wrong number of RISCVVecIntrinsicPragma");
+    SemaObj->RISCV().DeclareRVVBuiltins = RISCVVecIntrinsicPragma[0];
+    SemaObj->RISCV().DeclareSiFiveVectorBuiltins = RISCVVecIntrinsicPragma[1];
+    SemaObj->RISCV().DeclareAndesVectorBuiltins = RISCVVecIntrinsicPragma[2];
+  }
 
   if (PragmaAlignPackCurrentValue) {
     // The bottom of the stack might have a default value. It must be adjusted

diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 317ba8679db5d..234615522e773 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -972,6 +972,7 @@ void ASTWriter::WriteBlockInfoBlock() {
   RECORD(PP_ASSUME_NONNULL_LOC);
   RECORD(PP_UNSAFE_BUFFER_USAGE);
   RECORD(VTABLES_TO_EMIT);
+  RECORD(RISCV_VECTOR_INTRINSICS_PRAGMA);
 
   // SourceManager Block.
   BLOCK(SOURCE_MANAGER_BLOCK);
@@ -5250,6 +5251,16 @@ void ASTWriter::WriteModuleFileExtension(Sema &SemaRef,
   Stream.ExitBlock();
 }
 
+void ASTWriter::WriteRISCVIntrinsicPragmas(Sema &SemaRef) {
+  RecordData Record;
+  // Need to update this when new intrinsic class is added.
+  Record.push_back(/*size*/ 3);
+  Record.push_back(SemaRef.RISCV().DeclareRVVBuiltins);
+  Record.push_back(SemaRef.RISCV().DeclareSiFiveVectorBuiltins);
+  Record.push_back(SemaRef.RISCV().DeclareAndesVectorBuiltins);
+  Stream.EmitRecord(RISCV_VECTOR_INTRINSICS_PRAGMA, Record);
+}
+
 
//===----------------------------------------------------------------------===//
 // General Serialization Routines
 
//===----------------------------------------------------------------------===//
@@ -6148,6 +6159,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, 
StringRef isysroot,
     WriteFPPragmaOptions(SemaPtr->CurFPFeatureOverrides());
     WriteOpenCLExtensions(*SemaPtr);
     WriteCUDAPragmas(*SemaPtr);
+    WriteRISCVIntrinsicPragmas(*SemaPtr);
   }
 
   // If we're emitting a module, write out the submodule information.

diff  --git a/clang/test/PCH/riscv-rvv-vectors.c 
b/clang/test/PCH/riscv-rvv-vectors.c
new file mode 100644
index 0000000000000..0ffd82b6c4ccc
--- /dev/null
+++ b/clang/test/PCH/riscv-rvv-vectors.c
@@ -0,0 +1,40 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+
+// Test precompiled header
+// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -emit-pch -o 
%t/test_pch.pch %t/test_pch.h
+// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -include-pch 
%t/test_pch.pch \
+// RUN:   -fsyntax-only -verify %t/test_pch_src.c
+//
+// Test precompiled module(only available after C++20)
+// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -std=c++20 
-xc++-user-header -emit-header-unit -o %t/test_module1.pcm %t/test_module1.h
+// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -std=c++20 
-xc++-user-header -emit-header-unit -o %t/test_module2.pcm %t/test_module2.h
+// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -std=c++20 
-fmodule-file=%t/test_module1.pcm -fmodule-file=%t/test_module2.pcm \
+// RUN:   -fsyntax-only %t/test_module_src.cpp
+
+//--- test_pch.h
+// expected-no-diagnostics
+#include <riscv_vector.h>
+
+//--- test_pch_src.c
+// expected-no-diagnostics
+vuint64m4_t v_add(vuint64m4_t a, vuint64m4_t b, size_t vl) {
+    return __riscv_vadd_vv_u64m4(a, b, vl);
+}
+
+//--- test_module1.h
+// expected-no-diagnostics
+#include <riscv_vector.h>
+
+//--- test_module2.h
+// expected-no-diagnostics
+// empty header
+
+//--- test_module_src.cpp
+// expected-no-diagnostics
+import "test_module1.h";
+import "test_module2.h";
+vuint64m4_t v_add(vuint64m4_t a, vuint64m4_t b, size_t vl) {
+    return __riscv_vadd_vv_u64m4(a, b, vl);
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to