[polly] [Polly] Disable IO sandbox for PassBuilder (PR #188657)

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 27 01:35:55 PDT 2026


https://github.com/Meinersbur updated https://github.com/llvm/llvm-project/pull/188657

>From c487c172b57bdc1af2404cdd396787002ae32daa Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Thu, 26 Mar 2026 00:48:03 +0100
Subject: [PATCH 1/6] IOSandbox

---
 polly/lib/Support/RegisterPasses.cpp          |  2 ++
 polly/test/CMakeLists.txt                     |  5 ++++
 .../combine_different_values.c                | 23 -------------------
 polly/test/lit.cfg                            | 12 ++++++++++
 polly/test/lit.site.cfg.in                    |  1 +
 polly/test/polly.c                            |  9 ++++++++
 6 files changed, 29 insertions(+), 23 deletions(-)
 delete mode 100644 polly/test/CodeGen/RuntimeDebugBuilder/combine_different_values.c
 create mode 100644 polly/test/polly.c

diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index ca96feec9bcf5..44961973eda90 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -49,6 +49,7 @@
 #include "llvm/Plugins/PassPlugin.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/IOSandbox.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Transforms/IPO.h"
 
@@ -460,6 +461,7 @@ parsePollyCustomOptions(StringRef Params) {
 static void buildCommonPollyPipeline(FunctionPassManager &PM,
                                      OptimizationLevel Level,
                                      bool EnableForOpt) {
+  auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
   PassBuilder PB;
 
   ExitOnError Err("Inconsistent Polly configuration: ");
diff --git a/polly/test/CMakeLists.txt b/polly/test/CMakeLists.txt
index 4548f01d925a8..1ad6c31a22e04 100644
--- a/polly/test/CMakeLists.txt
+++ b/polly/test/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LLVM_SHLIBEXT "${CMAKE_SHARED_MODULE_SUFFIX}")
 add_custom_target(check-polly)
 set_target_properties(check-polly PROPERTIES FOLDER "Polly/Meta")
 
+set(POLLY_TEST_C_COMPILER "")
 if(NOT LLVM_MAIN_SRC_DIR)
   find_program(LLVM_OPT NAMES opt HINTS ${LLVM_TOOLS_BINARY_DIR})
   find_program(LLVM_FILECHECK NAMES FileCheck HINTS ${LLVM_TOOLS_BINARY_DIR})
@@ -35,6 +36,10 @@ else ()
   set(LLVM_NOT "${LLVM_TOOLS_BINARY_DIR}/not")
   set(POLLY_TEST_EXTRA_PATHS "")
   set(POLLY_TEST_DEPS llvm-config opt LLVMPolly FileCheck not count)
+
+  if (LLVM_POLLY_LINK_INTO_TOOLS AND TARGET clang)
+    set(POLLY_TEST_C_COMPILER "${LLVM_TOOLS_BINARY_DIR}/clang${CMAKE_EXECUTABLE_SUFFIX}")
+  endif ()
 endif()
 
 if (POLLY_BUNDLED_ISL)
diff --git a/polly/test/CodeGen/RuntimeDebugBuilder/combine_different_values.c b/polly/test/CodeGen/RuntimeDebugBuilder/combine_different_values.c
deleted file mode 100644
index c91098706d5ca..0000000000000
--- a/polly/test/CodeGen/RuntimeDebugBuilder/combine_different_values.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#define N 10
-void foo(float A[restrict], double B[restrict], char C[restrict],
-         int D[restrict], long E[restrict]) {
-  for (long i = 0; i < N; i++)
-    A[i] += B[i] + C[i] + D[i] + E[i];
-}
-
-int main() {
-  float A[N];
-  double B[N];
-  char C[N];
-  int D[N];
-  long E[N];
-
-  for (long i = 0; i < N; i++) {
-    __sync_synchronize();
-    A[i] = B[i] = C[i] = D[i] = E[i] = 42;
-  }
-
-  foo(A, B, C, D, E);
-
-  return A[8];
-}
diff --git a/polly/test/lit.cfg b/polly/test/lit.cfg
index 075ebdacbdc94..0e9725fe06c6e 100644
--- a/polly/test/lit.cfg
+++ b/polly/test/lit.cfg
@@ -9,6 +9,7 @@ import lit.formats
 import lit.util
 
 from lit.llvm import llvm_config
+from lit.llvm.subst import ToolSubst
 
 # Configuration file for the 'lit' test runner.
 
@@ -81,3 +82,14 @@ except OSError:
     exit(42)
 
 llvm_config_cmd.wait()
+
+if config.polly_test_c_compiler:
+  config.suffixes += ['.c']
+  llvm_config.add_tool_substitutions([ToolSubst(
+        "%clang",
+        command=config.polly_test_c_compiler,
+        unresolved="fatal",
+    )])
+  lit_config.note(f"Using test compiler: {config.polly_test_c_compiler}")
+else:
+  lit_config.note("Clang tests disabled: No compatible Clang found")
diff --git a/polly/test/lit.site.cfg.in b/polly/test/lit.site.cfg.in
index ca901b8825ced..3657683443a8d 100644
--- a/polly/test/lit.site.cfg.in
+++ b/polly/test/lit.site.cfg.in
@@ -10,6 +10,7 @@ config.target_triple = "@LLVM_TARGET_TRIPLE@"
 config.llvm_polly_link_into_tools = "@LLVM_POLLY_LINK_INTO_TOOLS@"
 config.targets_to_build = "@TARGETS_TO_BUILD@"
 config.extra_paths = "@POLLY_TEST_EXTRA_PATHS@".split(";")
+config.polly_test_c_compiler = "@POLLY_TEST_C_COMPILER@"
 
 ## Check the current platform with regex
 import re
diff --git a/polly/test/polly.c b/polly/test/polly.c
new file mode 100644
index 0000000000000..6990f92440e1f
--- /dev/null
+++ b/polly/test/polly.c
@@ -0,0 +1,9 @@
+// Sanity test for Polly in Clang
+// RUN: %clang %s -O2 -c -mllvm -polly -mllvm -polly-process-unprofitable -mllvm -print-pipeline-passes -o %t.o | FileCheck %s
+
+// CHECK: ,polly,
+
+void foo(int *A, int *B, int n) {
+  for (int i = 0; i < n; ++i)
+    A[i] += B[i];
+}

>From 0ed0c286501a88c016514b36f56497a381d20736 Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Thu, 26 Mar 2026 01:15:14 +0100
Subject: [PATCH 2/6] Add clang integration test

---
 polly/ci/polly-x86_64-linux-plugin.py | 2 +-
 polly/ci/polly-x86_64-linux.py        | 2 +-
 polly/test/CMakeLists.txt             | 3 ++-
 polly/test/lit.cfg                    | 7 ++++++-
 polly/test/lit.site.cfg.in            | 1 +
 5 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/polly/ci/polly-x86_64-linux-plugin.py b/polly/ci/polly-x86_64-linux-plugin.py
index 8933d25fa7196..1e992027649ba 100755
--- a/polly/ci/polly-x86_64-linux-plugin.py
+++ b/polly/ci/polly-x86_64-linux-plugin.py
@@ -29,7 +29,7 @@
             "-DCMAKE_BUILD_TYPE=Release",
             "-DCMAKE_C_COMPILER_LAUNCHER=ccache",
             "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
-            "-DLLVM_ENABLE_PROJECTS=polly",
+            "-DLLVM_ENABLE_PROJECTS=polly;clang",
             "-DLLVM_TARGETS_TO_BUILD=X86",
             "-DLLVM_ENABLE_LLD=ON",
             "-DLLVM_ENABLE_ASSERTIONS=ON",
diff --git a/polly/ci/polly-x86_64-linux.py b/polly/ci/polly-x86_64-linux.py
index 169f303f39566..024cc758668ac 100755
--- a/polly/ci/polly-x86_64-linux.py
+++ b/polly/ci/polly-x86_64-linux.py
@@ -30,7 +30,7 @@
             "-DCMAKE_BUILD_TYPE=Release",
             "-DCMAKE_C_COMPILER_LAUNCHER=ccache",
             "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
-            "-DLLVM_ENABLE_PROJECTS=polly",
+            "-DLLVM_ENABLE_PROJECTS=clang;polly",
             "-DLLVM_TARGETS_TO_BUILD=X86",
             "-DLLVM_ENABLE_LLD=ON",
             "-DLLVM_ENABLE_ASSERTIONS=ON",
diff --git a/polly/test/CMakeLists.txt b/polly/test/CMakeLists.txt
index 1ad6c31a22e04..b2a34164ee6c5 100644
--- a/polly/test/CMakeLists.txt
+++ b/polly/test/CMakeLists.txt
@@ -37,8 +37,9 @@ else ()
   set(POLLY_TEST_EXTRA_PATHS "")
   set(POLLY_TEST_DEPS llvm-config opt LLVMPolly FileCheck not count)
 
-  if (LLVM_POLLY_LINK_INTO_TOOLS AND TARGET clang)
+  if (TARGET clang)
     set(POLLY_TEST_C_COMPILER "${LLVM_TOOLS_BINARY_DIR}/clang${CMAKE_EXECUTABLE_SUFFIX}")
+    list(APPEND POLLY_TEST_DEPS clang)
   endif ()
 endif()
 
diff --git a/polly/test/lit.cfg b/polly/test/lit.cfg
index 0e9725fe06c6e..5eff726c0360a 100644
--- a/polly/test/lit.cfg
+++ b/polly/test/lit.cfg
@@ -85,11 +85,16 @@ llvm_config_cmd.wait()
 
 if config.polly_test_c_compiler:
   config.suffixes += ['.c']
+  llvm_polly_link_into_tools = lit.util.pythonize_bool(config.llvm_polly_link_into_tools )
+  clang_args = []
+  if not llvm_polly_link_into_tools:
+        clang_args += [f'-fpass-plugin={config.polly_lib_dir}/LLVMPolly{config.llvm_shlibext}']
   llvm_config.add_tool_substitutions([ToolSubst(
         "%clang",
         command=config.polly_test_c_compiler,
+        extra_args = clang_args,
         unresolved="fatal",
     )])
-  lit_config.note(f"Using test compiler: {config.polly_test_c_compiler}")
+  lit_config.note(f"Using Clang: {config.polly_test_c_compiler} {" ".join(clang_args)}")
 else:
   lit_config.note("Clang tests disabled: No compatible Clang found")
diff --git a/polly/test/lit.site.cfg.in b/polly/test/lit.site.cfg.in
index 3657683443a8d..56448f27ba6dc 100644
--- a/polly/test/lit.site.cfg.in
+++ b/polly/test/lit.site.cfg.in
@@ -4,6 +4,7 @@ config.llvm_src_root = "@LLVM_SOURCE_DIR@"
 config.llvm_obj_root = "@LLVM_BINARY_DIR@"
 config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@")
 config.llvm_libs_dir = lit_config.substitute("@LLVM_LIBS_DIR@")
+config.llvm_shlibext = "@LLVM_SHLIBEXT@"
 config.polly_obj_root = "@POLLY_BINARY_DIR@"
 config.polly_lib_dir = "@POLLY_LIB_DIR@"
 config.target_triple = "@LLVM_TARGET_TRIPLE@"

>From efcecfcbd3afaaf9e5f8179ab7460c1a31adc3b7 Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Thu, 26 Mar 2026 01:57:27 +0100
Subject: [PATCH 3/6] python format

---
 polly/test/lit.cfg | 36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/polly/test/lit.cfg b/polly/test/lit.cfg
index 5eff726c0360a..fce67be3d6f9e 100644
--- a/polly/test/lit.cfg
+++ b/polly/test/lit.cfg
@@ -4,6 +4,7 @@ import os
 import platform
 import re
 import subprocess
+import shlex
 
 import lit.formats
 import lit.util
@@ -56,6 +57,25 @@ llvm_config.use_default_substitutions()
 tool_patterns = ['opt', 'polly-isl-test']
 llvm_config.add_tool_substitutions(tool_patterns)
 
+
+if config.polly_test_c_compiler:
+  config.suffixes += ['.c']
+  llvm_polly_link_into_tools = lit.util.pythonize_bool(config.llvm_polly_link_into_tools)
+  clang_args = []
+  if not llvm_polly_link_into_tools:
+    clang_args += [f'-fpass-plugin={config.polly_lib_dir}/LLVMPolly{config.llvm_shlibext}']
+  llvm_config.add_tool_substitutions([
+    ToolSubst("%clang",
+      command = config.polly_test_c_compiler,
+      extra_args = clang_args,
+      unresolved = "fatal"
+    )
+  ])
+  lit_config.note(f"Using Clang: {config.polly_test_c_compiler} {shlex.join(clang_args)}")
+else:
+  lit_config.note("Clang tests disabled: No compatible Clang found")
+
+
 # opt knows whether it is compiled with -DNDEBUG.
 import subprocess
 try:
@@ -82,19 +102,3 @@ except OSError:
     exit(42)
 
 llvm_config_cmd.wait()
-
-if config.polly_test_c_compiler:
-  config.suffixes += ['.c']
-  llvm_polly_link_into_tools = lit.util.pythonize_bool(config.llvm_polly_link_into_tools )
-  clang_args = []
-  if not llvm_polly_link_into_tools:
-        clang_args += [f'-fpass-plugin={config.polly_lib_dir}/LLVMPolly{config.llvm_shlibext}']
-  llvm_config.add_tool_substitutions([ToolSubst(
-        "%clang",
-        command=config.polly_test_c_compiler,
-        extra_args = clang_args,
-        unresolved="fatal",
-    )])
-  lit_config.note(f"Using Clang: {config.polly_test_c_compiler} {" ".join(clang_args)}")
-else:
-  lit_config.note("Clang tests disabled: No compatible Clang found")

>From 643381db629517ab5e7bae1fdcb2ed72a775d85a Mon Sep 17 00:00:00 2001
From: Michael Kruse <github at meinersbur.de>
Date: Thu, 26 Mar 2026 02:16:30 +0100
Subject: [PATCH 4/6] Reorder LLVM_ENABLE_PROJECTS in build configuration

---
 polly/ci/polly-x86_64-linux.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/polly/ci/polly-x86_64-linux.py b/polly/ci/polly-x86_64-linux.py
index 024cc758668ac..dfa04c2922ff9 100755
--- a/polly/ci/polly-x86_64-linux.py
+++ b/polly/ci/polly-x86_64-linux.py
@@ -30,7 +30,7 @@
             "-DCMAKE_BUILD_TYPE=Release",
             "-DCMAKE_C_COMPILER_LAUNCHER=ccache",
             "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
-            "-DLLVM_ENABLE_PROJECTS=clang;polly",
+            "-DLLVM_ENABLE_PROJECTS=polly;clang",
             "-DLLVM_TARGETS_TO_BUILD=X86",
             "-DLLVM_ENABLE_LLD=ON",
             "-DLLVM_ENABLE_ASSERTIONS=ON",

>From 429291067785c3777830c2a66a7f92bac9a37052 Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Thu, 26 Mar 2026 02:23:59 +0100
Subject: [PATCH 5/6] Don't wrap lines in tests

---
 polly/test/.clang-format | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 polly/test/.clang-format

diff --git a/polly/test/.clang-format b/polly/test/.clang-format
new file mode 100644
index 0000000000000..594a340e6afec
--- /dev/null
+++ b/polly/test/.clang-format
@@ -0,0 +1 @@
+ColumnLimit: 0

>From 568429b197193d57963a5cca55c44841b7892074 Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Fri, 27 Mar 2026 09:34:27 +0100
Subject: [PATCH 6/6] Use PassBuilder::getVirtualFileSystemPtr()

---
 polly/lib/Support/RegisterPasses.cpp | 30 +++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index 44961973eda90..18eb5de38841c 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -49,7 +49,6 @@
 #include "llvm/Plugins/PassPlugin.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/IOSandbox.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Transforms/IPO.h"
 
@@ -460,9 +459,13 @@ parsePollyCustomOptions(StringRef Params) {
 ///                     The IR may still be modified.
 static void buildCommonPollyPipeline(FunctionPassManager &PM,
                                      OptimizationLevel Level,
+                                     IntrusiveRefCntPtr<vfs::FileSystem> FS,
                                      bool EnableForOpt) {
-  auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
-  PassBuilder PB;
+  PassBuilder PB(
+      /*TM=*/nullptr,
+      /*PipelineTuningOptions=*/{},
+      /*PGOOpt=*/{},
+      /*PIC=*/nullptr, std::move(FS));
 
   ExitOnError Err("Inconsistent Polly configuration: ");
   PollyPassOptions &&Opts =
@@ -477,7 +480,8 @@ static void buildCommonPollyPipeline(FunctionPassManager &PM,
 }
 
 static void buildEarlyPollyPipeline(llvm::ModulePassManager &MPM,
-                                    llvm::OptimizationLevel Level) {
+                                    llvm::OptimizationLevel Level,
+                                    IntrusiveRefCntPtr<vfs::FileSystem> FS) {
   bool EnableForOpt =
       shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();
   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
@@ -496,7 +500,7 @@ static void buildEarlyPollyPipeline(llvm::ModulePassManager &MPM,
     FPM = FunctionPassManager();
   }
 
-  buildCommonPollyPipeline(FPM, Level, EnableForOpt);
+  buildCommonPollyPipeline(FPM, Level, std::move(FS), EnableForOpt);
   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
 
   if (DumpAfter)
@@ -506,7 +510,8 @@ static void buildEarlyPollyPipeline(llvm::ModulePassManager &MPM,
 }
 
 static void buildLatePollyPipeline(FunctionPassManager &PM,
-                                   llvm::OptimizationLevel Level) {
+                                   llvm::OptimizationLevel Level,
+                                   IntrusiveRefCntPtr<vfs::FileSystem> FS) {
   bool EnableForOpt =
       shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();
   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
@@ -520,7 +525,7 @@ static void buildLatePollyPipeline(FunctionPassManager &PM,
         "not supported with NPM",
         false);
 
-  buildCommonPollyPipeline(PM, Level, EnableForOpt);
+  buildCommonPollyPipeline(PM, Level, std::move(FS), EnableForOpt);
 
   if (DumpAfter)
     PM.addPass(DumpFunctionPass("-after"));
@@ -626,6 +631,7 @@ parseModulePipeline(StringRef Name, llvm::ModulePassManager &MPM,
 /// handle LICMed code to make it useful.
 void registerPollyPasses(PassBuilder &PB) {
   PassInstrumentationCallbacks *PIC = PB.getPassInstrumentationCallbacks();
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = PB.getVirtualFileSystemPtr();
 
 #define MODULE_PASS(NAME, CREATE_PASS, PARSER)                                 \
   {                                                                            \
@@ -668,10 +674,16 @@ void registerPollyPasses(PassBuilder &PB) {
 
   switch (PassPosition) {
   case POSITION_EARLY:
-    PB.registerPipelineStartEPCallback(buildEarlyPollyPipeline);
+    PB.registerPipelineStartEPCallback(
+        [FS](ModulePassManager &MPM, OptimizationLevel Level) {
+          buildEarlyPollyPipeline(MPM, Level, FS);
+        });
     break;
   case POSITION_BEFORE_VECTORIZER:
-    PB.registerVectorizerStartEPCallback(buildLatePollyPipeline);
+    PB.registerVectorizerStartEPCallback(
+        [FS](FunctionPassManager &FPM, OptimizationLevel Level) {
+          buildLatePollyPipeline(FPM, Level, FS);
+        });
     break;
   }
 }



More information about the llvm-commits mailing list