[clang] [clang] Add optional pass to remove UBSAN traps using PGO (PR #84214)

Vitaly Buka via cfe-commits cfe-commits at lists.llvm.org
Sat Mar 9 00:41:15 PST 2024


https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/84214

>From feb5bfa786d1660a7fe0b6c48ec9048cdd315800 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Wed, 6 Mar 2024 10:03:46 -0800
Subject: [PATCH 1/7] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4
---
 clang/lib/CodeGen/BackendUtil.cpp   | 17 +++++++++++++++++
 clang/test/CodeGen/remote-traps.cpp | 15 +++++++++++++++
 2 files changed, 32 insertions(+)
 create mode 100644 clang/test/CodeGen/remote-traps.cpp

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 7310e3817c79a1..d89e53f69c4a51 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -76,6 +76,7 @@
 #include "llvm/Transforms/Instrumentation/MemProfiler.h"
 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
 #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
+#include "llvm/Transforms/Instrumentation/RemoveTrapsPass.h"
 #include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h"
 #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
 #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
@@ -83,6 +84,7 @@
 #include "llvm/Transforms/Scalar/EarlyCSE.h"
 #include "llvm/Transforms/Scalar/GVN.h"
 #include "llvm/Transforms/Scalar/JumpThreading.h"
+#include "llvm/Transforms/Scalar/SimplifyCFG.h"
 #include "llvm/Transforms/Utils/Debugify.h"
 #include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -98,6 +100,10 @@ using namespace llvm;
 namespace llvm {
 extern cl::opt<bool> PrintPipelinePasses;
 
+cl::opt<bool> ClRemoveTraps("clang-remove-traps", cl::Optional,
+                            cl::desc("Insert remove-traps pass."),
+                            cl::init(false));
+
 // Experiment to move sanitizers earlier.
 static cl::opt<bool> ClSanitizeOnOptimizerEarlyEP(
     "sanitizer-early-opt-ep", cl::Optional,
@@ -744,6 +750,17 @@ static void addSanitizers(const Triple &TargetTriple,
     // LastEP does not need GlobalsAA.
     PB.registerOptimizerLastEPCallback(SanitizersCallback);
   }
+
+  if (ClRemoveTraps) {
+    PB.registerOptimizerEarlyEPCallback([&](ModulePassManager &MPM,
+                                            OptimizationLevel Level) {
+      FunctionPassManager FPM;
+      FPM.addPass(RemoveTrapsPass());
+      FPM.addPass(
+          SimplifyCFGPass(SimplifyCFGOptions().convertSwitchRangeToICmp(true)));
+      MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+    });
+  }
 }
 
 void EmitAssemblyHelper::RunOptimizationPipeline(
diff --git a/clang/test/CodeGen/remote-traps.cpp b/clang/test/CodeGen/remote-traps.cpp
new file mode 100644
index 00000000000000..7d4eb76a7d81e9
--- /dev/null
+++ b/clang/test/CodeGen/remote-traps.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -O1 -emit-llvm -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow %s -o - | FileCheck %s 
+// RUN: %clang_cc1 -O1 -emit-llvm -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -mllvm -clang-remove-traps -mllvm -remove-traps-random-rate=1 %s -o - | FileCheck %s --implicit-check-not="call void @llvm.ubsantrap" --check-prefixes=REMOVE
+
+int f(int x) {
+  return x + 123;
+}
+
+// CHECK-LABEL: define dso_local noundef i32 @_Z1fi(
+// CHECK: call { i32, i1 } @llvm.sadd.with.overflow.i32(
+// CHECK: trap:
+// CHECK-NEXT: call void @llvm.ubsantrap(i8 0)
+// CHECK-NEXT: unreachable, !nosanitize !2 
+
+// REMOVE-LABEL: define dso_local noundef i32 @_Z1fi(
+// REMOVE: call { i32, i1 } @llvm.sadd.with.overflow.i32(

>From 0b2b44e04b8c900c29f52e340ebdfc6824607773 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Wed, 6 Mar 2024 10:08:47 -0800
Subject: [PATCH 2/7] comment

Created using spr 1.3.4
---
 clang/lib/CodeGen/BackendUtil.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index d89e53f69c4a51..fa49a364cf5600 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -752,6 +752,9 @@ static void addSanitizers(const Triple &TargetTriple,
   }
 
   if (ClRemoveTraps) {
+    // We can optimize after inliner, and PGO profile matching, which are part
+    // of `buildModuleSimplificationPipeline`. The hook below is called after
+    // that, from `buildModuleOptimizationPipeline`.
     PB.registerOptimizerEarlyEPCallback([&](ModulePassManager &MPM,
                                             OptimizationLevel Level) {
       FunctionPassManager FPM;

>From 000854eb9d18cd9cfd6eaf7d29e5954fb18d454c Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Wed, 6 Mar 2024 10:22:16 -0800
Subject: [PATCH 3/7] comment

Created using spr 1.3.4
---
 clang/lib/CodeGen/BackendUtil.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index fa49a364cf5600..55a45022c7cb17 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -752,9 +752,10 @@ static void addSanitizers(const Triple &TargetTriple,
   }
 
   if (ClRemoveTraps) {
-    // We can optimize after inliner, and PGO profile matching, which are part
-    // of `buildModuleSimplificationPipeline`. The hook below is called after
-    // that, from `buildModuleOptimizationPipeline`.
+    // We can optimize after inliner, and PGO profile matching. The hook below
+    // is called from `buildModuleOptimizationPipeline` just after profile use,
+    // and inliner is a part of `buildModuleSimplificationPipeline`, which is
+    // before `buildModuleOptimizationPipeline`.
     PB.registerOptimizerEarlyEPCallback([&](ModulePassManager &MPM,
                                             OptimizationLevel Level) {
       FunctionPassManager FPM;

>From d1b8488dd73d39ddc5124c9ecd72e72f128af1f8 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Fri, 8 Mar 2024 21:57:19 -0800
Subject: [PATCH 4/7] Use ScalarOptimizerLateEPCallback

Created using spr 1.3.4
---
 clang/lib/CodeGen/BackendUtil.cpp | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index a8c374c89b0936..e0c4b3b12b9b46 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -753,17 +753,15 @@ static void addSanitizers(const Triple &TargetTriple,
 
   if (ClRemoveTraps) {
     // We can optimize after inliner, and PGO profile matching. The hook below
-    // is called from `buildModuleOptimizationPipeline` just after profile use,
-    // and inliner is a part of `buildModuleSimplificationPipeline`, which is
-    // before `buildModuleOptimizationPipeline`.
-    PB.registerOptimizerEarlyEPCallback([](ModulePassManager &MPM,
-                                           OptimizationLevel Level) {
-      FunctionPassManager FPM;
-      FPM.addPass(RemoveTrapsPass());
-      FPM.addPass(
-          SimplifyCFGPass(SimplifyCFGOptions().convertSwitchRangeToICmp(true)));
-      MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
-    });
+    // is called at the end `buildFunctionSimplificationPipeline`, which called
+    // from `buildInlinerPipeline`, which called after profile matching.
+    PB.registerScalarOptimizerLateEPCallback(
+        [](FunctionPassManager &FPM, OptimizationLevel Level) {
+          // RemoveTrapsPass expects trap blocks precedded by conditional
+          // branches, which often is not the case without SimplifyCFG.
+          FPM.addPass(SimplifyCFGPass());
+          FPM.addPass(RemoveTrapsPass());
+        });
   }
 }
 

>From d0366aaa5414612cb9b380555e60658b0a731a46 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Fri, 8 Mar 2024 22:03:02 -0800
Subject: [PATCH 5/7] typo

Created using spr 1.3.4
---
 clang/lib/CodeGen/BackendUtil.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index e0c4b3b12b9b46..5203c0f8065ccc 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -757,8 +757,8 @@ static void addSanitizers(const Triple &TargetTriple,
     // from `buildInlinerPipeline`, which called after profile matching.
     PB.registerScalarOptimizerLateEPCallback(
         [](FunctionPassManager &FPM, OptimizationLevel Level) {
-          // RemoveTrapsPass expects trap blocks precedded by conditional
-          // branches, which often is not the case without SimplifyCFG.
+          // RemoveTrapsPass expects trap blocks preceded by conditional
+          // branches, which usually is not the case without SimplifyCFG.
           FPM.addPass(SimplifyCFGPass());
           FPM.addPass(RemoveTrapsPass());
         });

>From 3f70036dffb8ddd23fb954559f8552cb0c485cd6 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Fri, 8 Mar 2024 23:37:06 -0800
Subject: [PATCH 6/7] fix windows test

Created using spr 1.3.4
---
 clang/test/CodeGen/remote-traps.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/CodeGen/remote-traps.c b/clang/test/CodeGen/remote-traps.c
index 7d4eb76a7d81e9..366f022de1bb24 100644
--- a/clang/test/CodeGen/remote-traps.c
+++ b/clang/test/CodeGen/remote-traps.c
@@ -5,11 +5,11 @@ int f(int x) {
   return x + 123;
 }
 
-// CHECK-LABEL: define dso_local noundef i32 @_Z1fi(
+// CHECK-LABEL: define dso_local noundef i32 @f(
 // CHECK: call { i32, i1 } @llvm.sadd.with.overflow.i32(
 // CHECK: trap:
 // CHECK-NEXT: call void @llvm.ubsantrap(i8 0)
 // CHECK-NEXT: unreachable, !nosanitize !2 
 
-// REMOVE-LABEL: define dso_local noundef i32 @_Z1fi(
+// REMOVE-LABEL: define dso_local noundef i32 @f(
 // REMOVE: call { i32, i1 } @llvm.sadd.with.overflow.i32(

>From 7eed242d6042c5521a107212a374b6cf926a5eb2 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sat, 9 Mar 2024 00:01:31 -0800
Subject: [PATCH 7/7] remove unneded nosanitize

Created using spr 1.3.4
---
 clang/test/CodeGen/remote-traps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CodeGen/remote-traps.c b/clang/test/CodeGen/remote-traps.c
index 366f022de1bb24..f053d1bd157f80 100644
--- a/clang/test/CodeGen/remote-traps.c
+++ b/clang/test/CodeGen/remote-traps.c
@@ -9,7 +9,7 @@ int f(int x) {
 // CHECK: call { i32, i1 } @llvm.sadd.with.overflow.i32(
 // CHECK: trap:
 // CHECK-NEXT: call void @llvm.ubsantrap(i8 0)
-// CHECK-NEXT: unreachable, !nosanitize !2 
+// CHECK-NEXT: unreachable
 
 // REMOVE-LABEL: define dso_local noundef i32 @f(
 // REMOVE: call { i32, i1 } @llvm.sadd.with.overflow.i32(



More information about the cfe-commits mailing list