morehouse created this revision.
morehouse added a reviewer: kcc.
Herald added a subscriber: hiraditya.

When building with libFuzzer, simplifyCFG reduces the coverage signal
available to libFuzzer when trying to find new inputs.  This patch
provides a way to disable simplifyCFG when building with libFuzzer.


https://reviews.llvm.org/D43423

Files:
  clang/include/clang/Driver/CC1Options.td
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/no-simplify-cfg.cpp
  llvm/lib/Transforms/Utils/SimplifyCFG.cpp
  llvm/test/Transforms/SimplifyCFG/no-simplify-cfg.ll

Index: llvm/test/Transforms/SimplifyCFG/no-simplify-cfg.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/SimplifyCFG/no-simplify-cfg.ll
@@ -0,0 +1,50 @@
+; RUN: opt < %s -simplifycfg -S | FileCheck %s
+
+define i32 @foo(i32 %x) !no_simplify_cfg !{} {
+entry:
+  %x.addr = alloca i32, align 4
+  store i32 %x, i32* %x.addr, align 4
+  %0 = load i32, i32* %x.addr, align 4
+  %cmp = icmp sgt i32 %0, 16
+  br i1 %cmp, label %land.rhs, label %land.end
+
+land.rhs:
+  %1 = load i32, i32* %x.addr, align 4
+  %cmp1 = icmp slt i32 %1, 32
+  br label %land.end
+
+land.end:
+  %2 = phi i1 [ false, %entry ], [ %cmp1, %land.rhs ]
+  %conv = zext i1 %2 to i32
+  ret i32 %conv
+
+; CHECK-LABEL: define i32 @foo(i32 %x) !no_simplify_cfg
+; CHECK-LABEL: entry:
+; CHECK: br i1 %cmp, label %land.rhs, label %land.end
+; CHECK-LABEL: land.rhs:
+; CHECK: br label %land.end
+; CHECK-LABEL: land.end:
+; CHECK: phi {{.*}} %entry {{.*}} %land.rhs
+}
+
+define i32 @bar(i32 %x) {
+entry:
+  %x.addr = alloca i32, align 4
+  store i32 %x, i32* %x.addr, align 4
+  %0 = load i32, i32* %x.addr, align 4
+  %cmp = icmp sgt i32 %0, 16
+  br i1 %cmp, label %land.rhs, label %land.end
+
+land.rhs:
+  %1 = load i32, i32* %x.addr, align 4
+  %cmp1 = icmp slt i32 %1, 32
+  br label %land.end
+
+land.end:
+  %2 = phi i1 [ false, %entry ], [ %cmp1, %land.rhs ]
+  %conv = zext i1 %2 to i32
+  ret i32 %conv
+
+; CHECK-LABEL: define i32 @bar(i32 %x)
+; CHECK-NOT: br
+}
Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp
===================================================================
--- llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6053,6 +6053,9 @@
 bool llvm::simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
                        const SimplifyCFGOptions &Options,
                        SmallPtrSetImpl<BasicBlock *> *LoopHeaders) {
+  const Function *Fn = BB->getParent();
+  if (Fn && Fn->getMetadata("no_simplify_cfg"))
+    return false;
   return SimplifyCFGOpt(TTI, BB->getModule()->getDataLayout(), LoopHeaders,
                         Options)
       .run(BB);
Index: clang/test/CodeGen/no-simplify-cfg.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/no-simplify-cfg.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s --check-prefix=SIMPLIFY
+// RUN: %clang_cc1 -fno-simplify-cfg -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: define i32 @_Z3foov() {{.*}} !no_simplify_cfg
+int foo() {
+  return 42;
+}
+
+// CHECK: define i32 @_Z3barv() {{.*}} !no_simplify_cfg
+int bar() {
+  return foo() * foo() + foo();
+}
+
+// CHECK: define i32 @_Z3bazii(i32 %x, i32 %y) {{.*}} !no_simplify_cfg
+int baz(int x, int y) {
+  int z = x / y;
+  return z + foo() - bar();
+}
+
+// SIMPLIFY-NOT: no_simplify_cfg
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -571,6 +571,7 @@
   Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants);
   Opts.NoCommon = Args.hasArg(OPT_fno_common);
   Opts.NoImplicitFloat = Args.hasArg(OPT_no_implicit_float);
+  Opts.NoSimplifyCFG = Args.hasArg(OPT_fno_simplify_cfg);
   Opts.OptimizeSize = getOptimizationLevelSize(Args);
   Opts.SimplifyLibCalls = !(Args.hasArg(OPT_fno_builtin) ||
                             Args.hasArg(OPT_ffreestanding));
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -862,6 +862,11 @@
   if (SanOpts.has(SanitizerKind::SafeStack))
     Fn->addFnAttr(llvm::Attribute::SafeStack);
 
+  // Apply no-simplify-cfg attribute to the function
+  if (CGM.getCodeGenOpts().NoSimplifyCFG)
+    Fn->setMetadata("no_simplify_cfg",
+                    llvm::MDNode::get(CGM.getLLVMContext(), None));
+
   // Ignore TSan memory acesses from within ObjC/ObjC++ dealloc, initialize,
   // .cxx_destruct, __destroy_helper_block_ and all of their calees at run time.
   if (SanOpts.has(SanitizerKind::Thread)) {
Index: clang/include/clang/Frontend/CodeGenOptions.def
===================================================================
--- clang/include/clang/Frontend/CodeGenOptions.def
+++ clang/include/clang/Frontend/CodeGenOptions.def
@@ -120,6 +120,7 @@
                                      ///< enabled.
 CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled.
 CODEGENOPT(NoImplicitFloat   , 1, 0) ///< Set when -mno-implicit-float is enabled.
+CODEGENOPT(NoSimplifyCFG     , 1, 0) ///< Disable CFG simplification.
 CODEGENOPT(NoInfsFPMath      , 1, 0) ///< Assume FP arguments, results not +-Inf.
 CODEGENOPT(NoSignedZeros     , 1, 0) ///< Allow ignoring the signedness of FP zero
 CODEGENOPT(Reassociate       , 1, 0) ///< Allow reassociation of FP math ops
Index: clang/include/clang/Driver/CC1Options.td
===================================================================
--- clang/include/clang/Driver/CC1Options.td
+++ clang/include/clang/Driver/CC1Options.td
@@ -210,6 +210,8 @@
   HelpText<"Emit an error if a C++ static local initializer would need a guard variable">;
 def no_implicit_float : Flag<["-"], "no-implicit-float">,
   HelpText<"Don't generate implicit floating point instructions">;
+def fno_simplify_cfg : Flag<["-"], "fno-simplify-cfg">,
+  HelpText<"Disable CFG simplification">;
 def fdump_vtable_layouts : Flag<["-"], "fdump-vtable-layouts">,
   HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">;
 def fmerge_functions : Flag<["-"], "fmerge-functions">,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to