[llvm] Move target specific constant folding from ConstantFolding.cpp file (PR #180428)

via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 8 10:10:29 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Ivan Shumakov (Zararest)

<details>
<summary>Changes</summary>

There was a [discussion](https://discourse.llvm.org/t/constant-propagation-for-target-specific-intrinsics) about moving target dependent intrinsics to a separate interface. This is an attempt to make an interface that allows developers to add folding code without changing ConstantFolding.cpp

## Idea
Intrinsics are generated in the general part of the LLVM, so target specific handling might be implemented in two ways: target hook and generated functions. The first one doesn't guarantee the same functionality as now, because folding functions are called from contexts where target information (like TTI) could not be accessed. An additional interface that was discussed [here](https://discourse.llvm.org/t/constant-propagation-for-target-specific-intrinsics) also doesn't fit because it would require to change all users of ConstantFolding API in order to support it.
 
The second way doesn't proved full separation of target dependent and target independent code, but makes it easier to add new implementation of folding.

## Implementation
The **IntrinsicFolderEmittaer.inc** file contains functions with a switch case:
```
switch (IntrID) {
case ID:
  return foldIntrinsc();
```
An **Intrinsic** class from Intrinsics.td file now has a new field ConstFolder which is a name of a function to which  IntrinsicFolderEmittaer generate call in the switch case.
Implementations of the functions should be in a file that should be in a lib/Analysis folder.


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


6 Files Affected:

- (modified) llvm/include/llvm/IR/Intrinsics.td (+3-1) 
- (modified) llvm/lib/Analysis/CMakeLists.txt (+7) 
- (modified) llvm/lib/Analysis/ConstantFolding.cpp (+6) 
- (modified) llvm/utils/TableGen/CMakeLists.txt (+1) 
- (added) llvm/utils/TableGen/IntrinsicFolderEmitter.cpp (+57) 
- (modified) llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn (+1) 


``````````diff
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index ea6bd59c5aeca..d70e15a255c80 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -718,7 +718,8 @@ class Intrinsic<list<LLVMType> ret_types,
                 list<IntrinsicProperty> intr_properties = [],
                 string name = "",
                 list<SDNodeProperty> sd_properties = [],
-                bit disable_default_attributes = true> : SDPatternOperator {
+                bit disable_default_attributes = true,
+                string const_folder = ""> : SDPatternOperator {
   string LLVMName = name;
   string TargetPrefix = "";   // Set to a prefix for target-specific intrinsics.
   list<LLVMType> RetTypes = ret_types;
@@ -729,6 +730,7 @@ class Intrinsic<list<LLVMType> ret_types,
   // Disable applying IntrinsicProperties that are marked default with
   // IntrinsicProperty<1>
   bit DisableDefaultAttributes = disable_default_attributes;
+  string ConstFolder = const_folder;
 
   TypeInfoGen TypeInfo = TypeInfoGen<RetTypes, ParamTypes>;
 }
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index 9abdca099d9fe..2910f737c8bd1 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -34,6 +34,12 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
   set_source_files_properties(ConstantFolding.cpp PROPERTIES COMPILE_OPTIONS "-ftrapping-math")
 endif()
 
+
+set(LLVM_TARGET_DEFINITIONS ${LLVM_MAIN_INCLUDE_DIR}/llvm/IR/Intrinsics.td)
+tablegen(LLVM IntrinsicConstantFolding.inc
+         -gen-constant-folding)
+add_public_tablegen_target(ConstFoldingGen)
+
 add_llvm_component_library(LLVMAnalysis
   AliasAnalysis.cpp
   AliasAnalysisEvaluator.cpp
@@ -168,6 +174,7 @@ add_llvm_component_library(LLVMAnalysis
   DEPENDS
   analysis_gen
   intrinsics_gen
+  ConstFoldingGen
   ${MLDeps}
 
   LINK_LIBS
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index c0754d3a41264..7bae47348a2e5 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -71,6 +71,8 @@ static cl::opt<bool> DisableFPCallFolding(
 
 namespace {
 
+#include "IntrinsicConstantFolding.inc"
+
 //===----------------------------------------------------------------------===//
 // Constant Folding internal helper functions
 //===----------------------------------------------------------------------===//
@@ -4536,6 +4538,10 @@ Constant *llvm::ConstantFoldCall(const CallBase *Call, Function *F,
     return nullptr;
 
   StringRef Name = F->getName();
+  // Try to fold intrinsic with funtions from a ConstFolder intrinsic's field
+  if (auto *FoldedIntr = foldIntrinsic(Name, IID, Ty, Operands, F->getDataLayout(), TLI, Call))
+    return FoldedIntr;
+
   if (auto *FVTy = dyn_cast<FixedVectorType>(Ty))
     return ConstantFoldFixedVectorCall(
         Name, IID, FVTy, Operands, F->getDataLayout(), TLI, Call);
diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt
index e18279cffa74c..8c744bb1833c3 100644
--- a/llvm/utils/TableGen/CMakeLists.txt
+++ b/llvm/utils/TableGen/CMakeLists.txt
@@ -56,6 +56,7 @@ add_tablegen(llvm-tblgen LLVM
   GlobalISelEmitter.cpp
   InstrDocsEmitter.cpp
   InstrInfoEmitter.cpp
+  IntrinsicFolderEmitter.cpp
   llvm-tblgen.cpp
   MacroFusionPredicatorEmitter.cpp
   OptionParserEmitter.cpp
diff --git a/llvm/utils/TableGen/IntrinsicFolderEmitter.cpp b/llvm/utils/TableGen/IntrinsicFolderEmitter.cpp
new file mode 100644
index 0000000000000..013cfa736bc63
--- /dev/null
+++ b/llvm/utils/TableGen/IntrinsicFolderEmitter.cpp
@@ -0,0 +1,57 @@
+#include "llvm/ADT/SmallString.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <vector>
+
+using namespace llvm;
+
+namespace {
+class IntrinsicFolderEmitter {
+  const RecordKeeper &Records;
+
+public:
+  IntrinsicFolderEmitter(const RecordKeeper &R) : Records(R) {}
+
+  void run(raw_ostream &OS) {
+    emitSwitchFunction(OS);
+  }
+
+private:
+  void emitSwitchFunction(raw_ostream &OS) {
+    const char *ConstRecordName = "ConstFolder";
+    ArrayRef<const Record*> Intrinsics =
+        Records.getAllDerivedDefinitions("Intrinsic");
+
+    OS << "// Automatically generated file. Do not edit!\n";
+    OS << "// Intrinsic constant folding switch function\n\n";
+
+    OS << "static Constant *foldIntrinsic(StringRef Name, Intrinsic::ID IntrinsicID,\n";
+    OS << "                               Type *Ty, ArrayRef<Constant *> Operands,\n";
+    OS << "                               const DataLayout &DL, const TargetLibraryInfo *TLI,\n";
+    OS << "                               const CallBase *Call) {\n";
+    OS << "  switch (IntrinsicID) {\n";
+    OS << "    default: return nullptr;\n";
+
+    for (const Record *R : Intrinsics) {
+      if (R->isValueUnset(ConstRecordName))
+        continue;
+
+      StringRef FolderName = R->getValueAsString(ConstRecordName);
+      if (FolderName.empty())
+        continue;
+
+      StringRef EnumName = R->getName();
+      OS << "    case Intrinsic::" << EnumName << ":\n";
+      OS << "      return " << FolderName << "(Name, Ty, Operands, DL, TLI, Call);\n";
+    }
+
+    OS << "  }\n";
+    OS << "}\n";
+  }
+};
+} // namespace
+
+static TableGen::Emitter::OptClass<IntrinsicFolderEmitter>
+    X("gen-constant-folding", "Generate functions for constants folding for intrinsics");
\ No newline at end of file
diff --git a/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn b/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn
index 0ad39c3336801..4a6eb0f7ac223 100644
--- a/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn
@@ -42,6 +42,7 @@ executable("llvm-tblgen") {
     "GlobalISelEmitter.cpp",
     "InstrDocsEmitter.cpp",
     "InstrInfoEmitter.cpp",
+    "IntrinsicFolderEmitter.cpp",
     "MacroFusionPredicatorEmitter.cpp",
     "OptionParserEmitter.cpp",
     "OptionRSTEmitter.cpp",

``````````

</details>


https://github.com/llvm/llvm-project/pull/180428


More information about the llvm-commits mailing list