about summary refs log tree commit diff
path: root/llvm_mode
diff options
context:
space:
mode:
Diffstat (limited to 'llvm_mode')
-rw-r--r--llvm_mode/GNUmakefile36
-rw-r--r--llvm_mode/LLVMInsTrim.so.cc2
-rw-r--r--llvm_mode/README.instrument_file.md2
-rw-r--r--llvm_mode/README.laf-intel.md4
-rw-r--r--llvm_mode/README.lto.md62
-rw-r--r--llvm_mode/README.md4
-rw-r--r--llvm_mode/README.persistent_mode.md15
-rw-r--r--llvm_mode/afl-clang-fast.c76
-rw-r--r--llvm_mode/afl-llvm-common.cc20
-rw-r--r--llvm_mode/afl-llvm-common.h9
-rw-r--r--llvm_mode/afl-llvm-lto-instrim.so.cc10
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentation.so.cc54
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentlist.so.cc52
-rw-r--r--llvm_mode/afl-llvm-pass.so.cc2
-rw-r--r--llvm_mode/afl-llvm-rt.o.c46
-rw-r--r--llvm_mode/cmplog-instructions-pass.cc3
-rw-r--r--llvm_mode/cmplog-routines-pass.cc3
-rw-r--r--llvm_mode/compare-transform-pass.so.cc9
-rw-r--r--llvm_mode/split-compares-pass.so.cc426
-rw-r--r--llvm_mode/split-switches-pass.so.cc3
20 files changed, 593 insertions, 245 deletions
diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile
index b5d026ef..0813af34 100644
--- a/llvm_mode/GNUmakefile
+++ b/llvm_mode/GNUmakefile
@@ -32,15 +32,16 @@ ifeq "$(shell uname)" "OpenBSD"
   LLVM_CONFIG ?= $(BIN_PATH)/llvm-config
   HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1)
   ifeq "$(HAS_OPT)" "1"
-    $(error llvm_mode needs a complete llvm installation (versions 3.4 up to 11) -> e.g. "pkg_add llvm-7.0.1p9")
+    $(error llvm_mode needs a complete llvm installation (versions 3.4 up to 12) -> e.g. "pkg_add llvm-7.0.1p9")
   endif
 else
   LLVM_CONFIG ?= llvm-config
 endif
 
 LLVMVER  = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' )
-LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-3]|^1[2-9]' && echo 1 || echo 0 )
+LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-3]|^19' && echo 1 || echo 0 )
 LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 )
+LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[1-9]' && echo 1 || echo 0 )
 LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//')
 LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
 LLVM_LIBDIR = $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
@@ -53,20 +54,29 @@ ifeq "$(LLVMVER)" ""
 endif
 
 ifeq "$(LLVM_UNSUPPORTED)" "1"
-  $(warning llvm_mode only supports llvm versions 3.4 up to 11)
+  $(warning llvm_mode only supports llvm versions 3.4 up to 12)
 endif
 
+LLVM_TOO_OLD=1
+
 ifeq "$(LLVM_MAJOR)" "9"
   $(info [+] llvm_mode detected llvm 9, enabling neverZero implementation)
+  LLVM_TOO_OLD=0
 endif
 
 ifeq "$(LLVM_NEW_API)" "1"
   $(info [+] llvm_mode detected llvm 10+, enabling neverZero implementation and c++14)
   LLVM_STDCXX = c++14
+  LLVM_TOO_OLD=0
+endif
+
+ifeq "$(LLVM_TOO_OLD)" "1"
+  $(info [!] llvm_mode detected an old version of llvm, upgrade to at least 9 or preferable 11!)
+  $(shell sleep 1)
 endif
 
-ifeq "$(LLVM_MAJOR)" "11"
-  $(info [+] llvm_mode detected llvm 11, enabling afl-clang-lto LTO implementation)
+ifeq "$(LLVM_HAVE_LTO)" "1"
+  $(info [+] llvm_mode detected llvm 11+, enabling afl-clang-lto LTO implementation)
   LLVM_LTO = 1
   #TEST_MMAP = 1
 endif
@@ -182,18 +192,24 @@ ifeq "$(LLVM_LTO)" "1"
       ifneq "$(shell readlink $(LLVM_BINDIR)/ld.lld 2>&1)" ""
         AFL_REAL_LD = $(LLVM_BINDIR)/ld.lld
       else
-        $(warn ld.lld not found, can not enable LTO mode)
+        $(warn ld.lld not found, cannot enable LTO mode)
         LLVM_LTO = 0
       endif
     endif
+  else
+    $(warn -flto is not working (LLVMgold.so not found?), cannot enable LTO mode)
+    LLVM_LTO = 0
   endif
 endif
 
 AFL_CLANG_FUSELD=
-ifneq "$(AFL_CLANG_FLTO)" ""
-ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
-  AFL_CLANG_FUSELD=1
-endif
+ifeq "$(LLVM_LTO)" "1"
+  ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
+    AFL_CLANG_FUSELD=1
+  else
+    $(warn -fuse-ld is not working, cannot enable LTO mode)
+    LLVM_LTO = 0
+  endif
 endif
 
 CFLAGS          ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc
index 75548266..4d8c4719 100644
--- a/llvm_mode/LLVMInsTrim.so.cc
+++ b/llvm_mode/LLVMInsTrim.so.cc
@@ -56,7 +56,6 @@ struct InsTrim : public ModulePass {
 
  protected:
   uint32_t function_minimum_size = 1;
-  uint32_t debug = 0;
   char *   skip_nozero = NULL;
 
  private:
@@ -102,7 +101,6 @@ struct InsTrim : public ModulePass {
 
   bool runOnModule(Module &M) override {
 
-    char be_quiet = 0;
     setvbuf(stdout, NULL, _IONBF, 0);
 
     if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
diff --git a/llvm_mode/README.instrument_file.md b/llvm_mode/README.instrument_file.md
index 29c40eec..46e45ba2 100644
--- a/llvm_mode/README.instrument_file.md
+++ b/llvm_mode/README.instrument_file.md
@@ -18,6 +18,8 @@ For this purpose, I have added a "partial instrumentation" support to the LLVM
 mode of AFLFuzz that allows you to specify on a source file level which files
 should be compiled with or without instrumentation.
 
+Note: When using PCGUARD mode - and have llvm 12+ - you can use this instead:
+https://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation
 
 ## 2) Building the LLVM module
 
diff --git a/llvm_mode/README.laf-intel.md b/llvm_mode/README.laf-intel.md
index 2fa4bc26..f63ab2bb 100644
--- a/llvm_mode/README.laf-intel.md
+++ b/llvm_mode/README.laf-intel.md
@@ -35,8 +35,8 @@ bit_width may be 64, 32 or 16.
 A new experimental feature is splitting floating point comparisons into a
 series of sign, exponent and mantissa comparisons followed by splitting each
 of them into 8 bit comparisons when necessary.
-It is activated with the `AFL_LLVM_LAF_SPLIT_FLOATS` setting, available only
-when `AFL_LLVM_LAF_SPLIT_COMPARES` is set.
+It is activated with the `AFL_LLVM_LAF_SPLIT_FLOATS` setting.
+Note that setting this automatically activates `AFL_LLVM_LAF_SPLIT_COMPARES`
 
 You can also set `AFL_LLVM_LAF_ALL` and have all of the above enabled :-)
 
diff --git a/llvm_mode/README.lto.md b/llvm_mode/README.lto.md
index 4641fa89..e521ac82 100644
--- a/llvm_mode/README.lto.md
+++ b/llvm_mode/README.lto.md
@@ -2,7 +2,7 @@
 
 ## TLDR;
 
-This version requires a current llvm 11 compiled from the github master.
+This version requires a current llvm 11+ compiled from the github master.
 
 1. Use afl-clang-lto/afl-clang-lto++ because it is faster and gives better
    coverage than anything else that is out there in the AFL world
@@ -10,7 +10,7 @@ This version requires a current llvm 11 compiled from the github master.
 2. You can use it together with llvm_mode: laf-intel and the instrument file listing
    features and can be combined with cmplog/Redqueen
 
-3. It only works with llvm 11 (current github master state)
+3. It only works with llvm 11+
 
 4. AUTODICTIONARY feature! see below
 
@@ -61,9 +61,9 @@ AUTODICTIONARY: 11 strings found
 [+] Instrumented 12071 locations with no collisions (on average 1046 collisions would be in afl-gcc/afl-clang-fast) (non-hardened mode).
 ```
 
-## Getting llvm 11
+## Getting llvm 11+
 
-### Installing llvm 11 from the llvm repository
+### Installing llvm from the llvm repository (version 11)
 
 Installing the llvm snapshot builds is easy and mostly painless:
 
@@ -83,7 +83,7 @@ apt-get install -y clang-11 clang-tools-11 libc++1-11 libc++-11-dev \
     libomp5-11 lld-11 lldb-11 llvm-11 llvm-11-dev llvm-11-runtime llvm-11-tools
 ```
 
-### Building llvm 11 yourself
+### Building llvm yourself (version 12)
 
 Building llvm from github takes quite some long time and is not painless:
 ```
@@ -125,10 +125,9 @@ NOTE: some targets also need to set the linker, try both `afl-clang-lto` and
 
 ## AUTODICTIONARY feature
 
-Setting `AFL_LLVM_LTO_AUTODICTIONARY` will generate a dictionary in the
-target binary based on string compare and memory compare functions.
-afl-fuzz will automatically get these transmitted when starting to fuzz.
-This improves coverage on a lot of targets.
+While compiling, automatically a dictionary based on string comparisons is
+generated put into the target binary. This dictionary is transfered to afl-fuzz
+on start. This improves coverage statistically by 5-10% :)
 
 ## Fixed memory map
 
@@ -141,12 +140,20 @@ to be dynamic - the original afl way, which is slower).
 AFL_LLVM_MAP_DYNAMIC can be set so the shared memory address is dynamic (which
 is safer but also slower).
 
+## Document edge IDs
+
+Setting `export AFL_LLVM_DOCUMENT_IDS=file` will document to a file which edge
+ID was given to which function. This helps to identify functions with variable
+bytes or which functions were touched by an input.
+
 ## Solving difficult targets
 
 Some targets are difficult because the configure script does unusual stuff that
 is unexpected for afl. See the next chapter `Potential issues` how to solve
 these.
 
+### Example: ffmpeg
+
 An example of a hard to solve target is ffmpeg. Here is how to successfully
 instrument it:
 
@@ -156,7 +163,7 @@ instrument it:
    when compiling, so we have to trick configure:
 
 ```
-./configure --enable-lto --disable-shared
+./configure --enable-lto --disable-shared --disable-inline-asm
 ```
 
 3. Now the configuration is done - and we edit the settings in `./ffbuild/config.mak`
@@ -186,6 +193,31 @@ instrument it:
 
 4. Then type make, wait for a long time and you are done :)
 
+### Example: WebKit jsc
+
+Building jsc is difficult as the build script has bugs.
+
+1. checkout Webkit: 
+```
+svn checkout https://svn.webkit.org/repository/webkit/trunk WebKit
+cd WebKit
+```
+
+2. Fix the build environment:
+```
+mkdir -p WebKitBuild/Release
+cd WebKitBuild/Release
+ln -s ../../../../../usr/bin/llvm-ar-12 llvm-ar-12
+ln -s ../../../../../usr/bin/llvm-ranlib-12 llvm-ranlib-12
+cd ../..
+```
+
+3. Build :)
+
+```
+Tools/Scripts/build-jsc --jsc-only --cli --cmakeargs="-DCMAKE_AR='llvm-ar-12' -DCMAKE_RANLIB='llvm-ranlib-12' -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCMAKE_CC_FLAGS='-O3 -lrt' -DCMAKE_CXX_FLAGS='-O3 -lrt' -DIMPORTED_LOCATION='/lib/x86_64-linux-gnu/' -DCMAKE_CC=afl-clang-lto -DCMAKE_CXX=afl-clang-lto++ -DENABLE_STATIC_JSC=ON"
+```
+
 ## Potential issues
 
 ### compiling libraries fails
@@ -220,17 +252,17 @@ AS=llvm-as  ...
 afl-clang-lto is still work in progress.
 
 Known issues:
-  * Anything that llvm 11 cannot compile, afl-clang-lto can not compile either - obviously
+  * Anything that llvm 11+ cannot compile, afl-clang-lto can not compile either - obviously
   * Anything that does not compile with LTO, afl-clang-lto can not compile either - obviously
 
-Hence if building a target with afl-clang-lto fails try to build it with llvm11
-and LTO enabled (`CC=clang-11` `CXX=clang++-11` `CFLAGS=-flto=full` and
+Hence if building a target with afl-clang-lto fails try to build it with llvm12
+and LTO enabled (`CC=clang-12` `CXX=clang++-12` `CFLAGS=-flto=full` and
 `CXXFLAGS=-flto=full`).
 
 If this succeeeds then there is an issue with afl-clang-lto. Please report at
 [https://github.com/AFLplusplus/AFLplusplus/issues/226](https://github.com/AFLplusplus/AFLplusplus/issues/226)
 
-Even some targets where clang-11 fails can be build if the fail is just in
+Even some targets where clang-12 fails can be build if the fail is just in
 `./configure`, see `Solving difficult targets` above.
 
 ### Target crashes immediately
@@ -270,7 +302,7 @@ Still more problems came up though as this only works without bugs from
 llvm 9 onwards, and with high optimization the link optimization ruins
 the instrumented control flow graph.
 
-This is all now fixed with llvm 11. The llvm's own linker is now able to
+This is all now fixed with llvm 11+. The llvm's own linker is now able to
 load passes and this bypasses all problems we had.
 
 Happy end :)
diff --git a/llvm_mode/README.md b/llvm_mode/README.md
index e2e22751..22088dfd 100644
--- a/llvm_mode/README.md
+++ b/llvm_mode/README.md
@@ -6,7 +6,7 @@
 
 ## 1) Introduction
 
-! llvm_mode works with llvm versions 3.4 up to 11 !
+! llvm_mode works with llvm versions 3.4 up to 12 !
 
 The code in this directory allows you to instrument programs for AFL using
 true compiler-level instrumentation, instead of the more crude
@@ -183,4 +183,4 @@ AFL_LLVM_INSTRUMENT=PCGUARD  make
 ```
 
 Note that this us currently the default, as it is the best mode.
-If you have llvm 11 and compiled afl-clang-lto - this is the only better mode.
+If you have llvm 11+ and compiled afl-clang-lto - this is the only better mode.
diff --git a/llvm_mode/README.persistent_mode.md b/llvm_mode/README.persistent_mode.md
index 83cc7f4d..4f0bcb2e 100644
--- a/llvm_mode/README.persistent_mode.md
+++ b/llvm_mode/README.persistent_mode.md
@@ -52,6 +52,21 @@ afl-clang-fast -o fuzz_target fuzz_target.c -lwhat_you_need_for_your_target
 And that is it!
 The speed increase is usually x10 to x20.
 
+If you want to be able to compile the target without afl-clang-fast/lto then
+add this just after the includes:
+
+```
+#ifndef __AFL_FUZZ_TESTCASE_LEN
+  ssize_t fuzz_len;
+  #define __AFL_FUZZ_TESTCASE_LEN fuzz_len
+  unsigned char fuzz_buf[1024000];
+  #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf
+  #define __AFL_FUZZ_INIT() void sync(void);
+  #define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ?
+  #define __AFL_INIT() sync() 
+#endif
+```
+
 ## 3) deferred initialization
 
 AFL tries to optimize performance by executing the targeted binary just once,
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
index f1b03682..738433ac 100644
--- a/llvm_mode/afl-clang-fast.c
+++ b/llvm_mode/afl-clang-fast.c
@@ -162,6 +162,7 @@ static void find_obj(u8 *argv0) {
 static void edit_params(u32 argc, char **argv, char **envp) {
 
   u8  fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0;
+  u8  have_pic = 0;
   u8 *name;
 
   cc_params = ck_alloc((argc + 128) * sizeof(u8 *));
@@ -268,7 +269,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   }
 
-  if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES")) {
+  if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES") ||
+      getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) {
 
     cc_params[cc_par_cnt++] = "-Xclang";
     cc_params[cc_par_cnt++] = "-load";
@@ -311,12 +313,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
     cc_params[cc_par_cnt++] = alloc_printf("-fuse-ld=%s", AFL_REAL_LD);
     cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
-    if (instrument_mode == INSTRUMENT_CFG)
-      cc_params[cc_par_cnt++] =
-          alloc_printf("-Wl,-mllvm=-load=%s/afl-llvm-lto-instrim.so", obj_path);
-    else
-      cc_params[cc_par_cnt++] = alloc_printf(
-          "-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path);
+    /*
+        The current LTO instrim mode is not good, so we disable it
+        if (instrument_mode == INSTRUMENT_CFG)
+          cc_params[cc_par_cnt++] =
+              alloc_printf("-Wl,-mllvm=-load=%s/afl-llvm-lto-instrim.so",
+       obj_path); else
+    */
+    cc_params[cc_par_cnt++] = alloc_printf(
+        "-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path);
     cc_params[cc_par_cnt++] = lto_flag;
 
   } else {
@@ -359,6 +364,19 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   }
 
+  u32 idx;
+  if (lto_mode && argc > 1) {
+
+    for (idx = 1; idx < argc; idx++) {
+
+      if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1;
+
+    }
+
+    if (!have_pic) cc_params[cc_par_cnt++] = "-fPIC";
+
+  }
+
   /* Detect stray -v calls from ./configure scripts. */
 
   while (--argc) {
@@ -379,6 +397,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined"))
       continue;
 
+    if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
+
     cc_params[cc_par_cnt++] = cur;
 
   }
@@ -500,13 +520,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
       "int __afl_sharedmem_fuzzing = 1;"
       "extern unsigned int *__afl_fuzz_len;"
       "extern unsigned char *__afl_fuzz_ptr;"
-      "unsigned char *__afl_fuzz_alt_ptr;";
+      "unsigned char __afl_fuzz_alt[1024000];"
+      "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;";
   cc_params[cc_par_cnt++] =
       "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : "
-      "(__afl_fuzz_alt_ptr = (unsigned char *) malloc(1 * 1024 * 1024)))";
+      "__afl_fuzz_alt_ptr)";
   cc_params[cc_par_cnt++] =
-      "-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : read(0, "
-      "__afl_fuzz_alt_ptr, 1 * 1024 * 1024))";
+      "-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : "
+      "(*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1024000)) == 0xffffffff "
+      "? 0 : *__afl_fuzz_len)";
 
   cc_params[cc_par_cnt++] =
       "-D__AFL_LOOP(_A)="
@@ -617,6 +639,10 @@ int main(int argc, char **argv, char **envp) {
 
   }
 
+  if ((getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")) &&
+      getenv("AFL_DONT_OPTIMIZE"))
+    FATAL("AFL_LLVM_INSTRUMENT_FILE and AFL_DONT_OPTIMIZE cannot be combined");
+
   if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") ||
       getenv("INSTRIM_LIB")) {
 
@@ -660,7 +686,7 @@ int main(int argc, char **argv, char **envp) {
       }
 
       if (strncasecmp(ptr, "pc-guard", strlen("pc-guard")) == 0 ||
-          strncasecmp(ptr, "pcguard", strlen("pcgard")) == 0) {
+          strncasecmp(ptr, "pcguard", strlen("pcguard")) == 0) {
 
         if (!instrument_mode || instrument_mode == INSTRUMENT_PCGUARD)
           instrument_mode = INSTRUMENT_PCGUARD;
@@ -763,9 +789,19 @@ int main(int argc, char **argv, char **envp) {
 #if LLVM_VERSION_MAJOR <= 6
     instrument_mode = INSTRUMENT_AFL;
 #else
-    if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST"))
+    if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")) {
+
       instrument_mode = INSTRUMENT_AFL;
-    else
+      WARNF(
+          "switching to classic instrumentation because "
+          "AFL_LLVM_INSTRUMENT_FILE does not work with PCGUARD. Use "
+          "-fsanitize-coverage-allowlist=allowlist.txt if you want to use "
+          "PCGUARD. Requires llvm 12+. See "
+          "https://clang.llvm.org/docs/"
+          "SanitizerCoverage.html#partially-disabling-instrumentation");
+
+    } else
+
       instrument_mode = INSTRUMENT_PCGUARD;
 #endif
 
@@ -813,9 +849,13 @@ int main(int argc, char **argv, char **envp) {
 
   if (instrument_mode == INSTRUMENT_PCGUARD &&
       (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")))
-    WARNF(
+    FATAL(
         "Instrumentation type PCGUARD does not support "
-        "AFL_LLVM_INSTRUMENT_FILE!");
+        "AFL_LLVM_INSTRUMENT_FILE! Use "
+        "-fsanitize-coverage-allowlist=allowlist.txt instead (requires llvm "
+        "12+), see "
+        "https://clang.llvm.org/docs/"
+        "SanitizerCoverage.html#partially-disabling-instrumentation");
 
   if (argc < 2 || strcmp(argv[1], "-h") == 0) {
 
@@ -871,6 +911,8 @@ int main(int argc, char **argv, char **envp) {
         "AFL_NO_BUILTIN: compile for use with libtokencap.so\n"
         "AFL_PATH: path to instrumenting pass and runtime "
         "(afl-llvm-rt.*o)\n"
+        "AFL_LLVM_DOCUMENT_IDS: document edge IDs given to which function (LTO "
+        "only)\n"
         "AFL_QUIET: suppress verbose output\n"
         "AFL_USE_ASAN: activate address sanitizer\n"
         "AFL_USE_CFISAN: activate control flow sanitizer\n"
@@ -939,7 +981,7 @@ int main(int argc, char **argv, char **envp) {
 
     u32 map_size = atoi(ptr2);
     if (map_size != MAP_SIZE)
-      FATAL("AFL_MAP_SIZE is not supported by afl-clang-fast");
+      WARNF("AFL_MAP_SIZE is not supported by afl-clang-fast");
 
   }
 
diff --git a/llvm_mode/afl-llvm-common.cc b/llvm_mode/afl-llvm-common.cc
index 47b49358..9a884ded 100644
--- a/llvm_mode/afl-llvm-common.cc
+++ b/llvm_mode/afl-llvm-common.cc
@@ -14,6 +14,8 @@
 #include <fstream>
 
 #include <llvm/Support/raw_ostream.h>
+
+#define IS_EXTERN extern
 #include "afl-llvm-common.h"
 
 using namespace llvm;
@@ -88,6 +90,7 @@ void initInstrumentList() {
   char *instrumentListFilename = getenv("AFL_LLVM_INSTRUMENT_FILE");
   if (!instrumentListFilename)
     instrumentListFilename = getenv("AFL_LLVM_WHITELIST");
+
   if (instrumentListFilename) {
 
     std::string   line;
@@ -105,6 +108,10 @@ void initInstrumentList() {
 
   }
 
+  if (debug)
+    SAYF(cMGN "[D] " cRST "loaded instrument list with %zu entries\n",
+         myInstrumentList.size());
+
 }
 
 bool isInInstrumentList(llvm::Function *F) {
@@ -145,8 +152,6 @@ bool isInInstrumentList(llvm::Function *F) {
 
     }
 
-    (void)instLine;
-
     /* Continue only if we know where we actually are */
     if (!instFilename.str().empty()) {
 
@@ -164,6 +169,10 @@ bool isInInstrumentList(llvm::Function *F) {
           if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) ==
               0) {
 
+            if (debug)
+              SAYF(cMGN "[D] " cRST
+                        "Function %s is in the list (%s), instrumenting ... \n",
+                   F->getName().str().c_str(), instFilename.str().c_str());
             return true;
 
           }
@@ -219,12 +228,15 @@ bool isInInstrumentList(llvm::Function *F) {
 
     // we could not find out the location. in this case we say it is not
     // in the the instrument file list
-
+    if (!be_quiet)
+      WARNF(
+          "No debug information found for function %s, will not be "
+          "instrumented (recompile with -g -O[1-3]).",
+          F->getName().str().c_str());
     return false;
 
   }
 
-  //
   return false;
 
 }
diff --git a/llvm_mode/afl-llvm-common.h b/llvm_mode/afl-llvm-common.h
index 38e0c830..5b96be43 100644
--- a/llvm_mode/afl-llvm-common.h
+++ b/llvm_mode/afl-llvm-common.h
@@ -38,5 +38,14 @@ void                   initInstrumentList();
 bool                   isInInstrumentList(llvm::Function *F);
 unsigned long long int calculateCollisions(uint32_t edges);
 
+#ifndef IS_EXTERN
+  #define IS_EXTERN
+#endif
+
+IS_EXTERN int debug;
+IS_EXTERN int be_quiet;
+
+#undef IS_EXTERN
+
 #endif
 
diff --git a/llvm_mode/afl-llvm-lto-instrim.so.cc b/llvm_mode/afl-llvm-lto-instrim.so.cc
index ca2b5886..98e9ff9a 100644
--- a/llvm_mode/afl-llvm-lto-instrim.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrim.so.cc
@@ -73,8 +73,8 @@ struct InsTrimLTO : public ModulePass {
  protected:
   uint32_t function_minimum_size = 1;
   char *   skip_nozero = NULL;
-  int      afl_global_id = 1, debug = 0, autodictionary = 0;
-  uint32_t be_quiet = 0, inst_blocks = 0, inst_funcs = 0;
+  int      afl_global_id = 1, autodictionary = 1;
+  uint32_t inst_blocks = 0, inst_funcs = 0;
   uint64_t map_addr = 0x10000;
 
  public:
@@ -127,10 +127,6 @@ struct InsTrimLTO : public ModulePass {
 
     /* Process environment variables */
 
-    if (getenv("AFL_LLVM_AUTODICTIONARY") ||
-        getenv("AFL_LLVM_LTO_AUTODICTIONARY"))
-      autodictionary = 1;
-
     if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0;
 
     if ((ptr = getenv("AFL_LLVM_MAP_ADDR"))) {
@@ -705,7 +701,7 @@ struct InsTrimLTO : public ModulePass {
 
         Value *Incr = IRB.CreateAdd(Counter, One);
 
-        if (skip_nozero) {
+        if (skip_nozero == NULL) {
 
           auto cf = IRB.CreateICmpEQ(Incr, Zero);
           auto carry = IRB.CreateZExt(cf, Int8Ty);
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
index af2db3ff..5686eb56 100644
--- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
@@ -86,9 +86,9 @@ class AFLLTOPass : public ModulePass {
   bool runOnModule(Module &M) override;
 
  protected:
-  int      afl_global_id = 1, debug = 0, autodictionary = 0;
+  int      afl_global_id = 1, autodictionary = 1;
   uint32_t function_minimum_size = 1;
-  uint32_t be_quiet = 0, inst_blocks = 0, inst_funcs = 0, total_instr = 0;
+  uint32_t inst_blocks = 0, inst_funcs = 0, total_instr = 0;
   uint64_t map_addr = 0x10000;
   char *   skip_nozero = NULL;
 
@@ -103,6 +103,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
   std::vector<CallInst *>          calls;
   DenseMap<Value *, std::string *> valueMap;
   char *                           ptr;
+  FILE *                           documentFile = NULL;
 
   IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
   IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
@@ -120,15 +121,16 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
     be_quiet = 1;
 
-  if (getenv("AFL_LLVM_AUTODICTIONARY") ||
-      getenv("AFL_LLVM_LTO_AUTODICTIONARY"))
-    autodictionary = 1;
+  if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
+
+    if ((documentFile = fopen(ptr, "a")) == NULL)
+      WARNF("Cannot access document file %s", ptr);
+
+  }
 
   if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0;
 
-  if (getenv("AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK") ||
-      getenv("AFL_LLVM_SKIPSINGLEBLOCK"))
-    function_minimum_size = 2;
+  if (getenv("AFL_LLVM_SKIPSINGLEBLOCK")) function_minimum_size = 2;
 
   if ((ptr = getenv("AFL_LLVM_MAP_ADDR"))) {
 
@@ -204,7 +206,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
       if (debug)
         fprintf(stderr,
-                "DEBUG: Function %s is not the instrument file listed\n",
+                "DEBUG: Function %s is not in a source file that was specified "
+                "in the instrument file list\n",
                 F.getName().str().c_str());
       continue;
 
@@ -536,6 +539,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
       uint32_t succ = 0;
 
+      if (F.size() == 1) InsBlocks.push_back(&BB);
+
       for (succ_iterator SI = succ_begin(&BB), SE = succ_end(&BB); SI != SE;
            ++SI)
         if ((*SI)->size() > 0) succ++;
@@ -554,9 +559,12 @@ bool AFLLTOPass::runOnModule(Module &M) {
       do {
 
         --i;
+        BasicBlock *              newBB;
         BasicBlock *              origBB = &(*InsBlocks[i]);
         std::vector<BasicBlock *> Successors;
         Instruction *             TI = origBB->getTerminator();
+        uint32_t                  fs = origBB->getParent()->size();
+        uint32_t                  countto;
 
         for (succ_iterator SI = succ_begin(origBB), SE = succ_end(origBB);
              SI != SE; ++SI) {
@@ -566,15 +574,25 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
         }
 
-        if (TI == NULL || TI->getNumSuccessors() < 2) continue;
+        if (fs == 1) {
+
+          newBB = origBB;
+          countto = 1;
+
+        } else {
+
+          if (TI == NULL || TI->getNumSuccessors() < 2) continue;
+          countto = Successors.size();
+
+        }
 
         // if (Successors.size() != TI->getNumSuccessors())
         //  FATAL("Different successor numbers %lu <-> %u\n", Successors.size(),
         //        TI->getNumSuccessors());
 
-        for (uint32_t j = 0; j < Successors.size(); j++) {
+        for (uint32_t j = 0; j < countto; j++) {
 
-          BasicBlock *newBB = llvm::SplitEdge(origBB, Successors[j]);
+          if (fs != 1) newBB = llvm::SplitEdge(origBB, Successors[j]);
 
           if (!newBB) {
 
@@ -583,6 +601,13 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
           }
 
+          if (documentFile) {
+
+            fprintf(documentFile, "%s %u\n", F.getName().str().c_str(),
+                    afl_global_id);
+
+          }
+
           BasicBlock::iterator IP = newBB->getFirstInsertionPt();
           IRBuilder<>          IRB(&(*IP));
 
@@ -615,7 +640,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
           Value *Incr = IRB.CreateAdd(Counter, One);
 
-          if (skip_nozero) {
+          if (skip_nozero == NULL) {
 
             auto cf = IRB.CreateICmpEQ(Incr, Zero);
             auto carry = IRB.CreateZExt(cf, Int8Ty);
@@ -638,6 +663,9 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   }
 
+  if (documentFile) fclose(documentFile);
+  documentFile = NULL;
+
   // save highest location ID to global variable
   // do this after each function to fail faster
   if (!be_quiet && afl_global_id > MAP_SIZE &&
diff --git a/llvm_mode/afl-llvm-lto-instrumentlist.so.cc b/llvm_mode/afl-llvm-lto-instrumentlist.so.cc
index 6e6199e9..ab7c0c58 100644
--- a/llvm_mode/afl-llvm-lto-instrumentlist.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrumentlist.so.cc
@@ -104,7 +104,6 @@ class AFLcheckIfInstrument : public ModulePass {
 
  protected:
   std::list<std::string> myInstrumentList;
-  int                    debug = 0;
 
 };
 
@@ -116,7 +115,6 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) {
 
   /* Show a banner */
 
-  char be_quiet = 0;
   setvbuf(stdout, NULL, _IONBF, 0);
 
   if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
@@ -164,32 +162,41 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) {
 
           }
 
+          if (instFilename.str().empty()) {
+
+            if (!be_quiet)
+              WARNF(
+                  "Function %s has no source file name information and will "
+                  "not be instrumented.",
+                  F.getName().str().c_str());
+            continue;
+
+          }
+
         }
 
-        (void)instLine;
+        //(void)instLine;
 
+        fprintf(stderr, "xxx %s %s\n", F.getName().str().c_str(),
+                instFilename.str().c_str());
         if (debug)
           SAYF(cMGN "[D] " cRST "function %s is in file %s\n",
                F.getName().str().c_str(), instFilename.str().c_str());
-        /* Continue only if we know where we actually are */
-        if (!instFilename.str().empty()) {
 
-          for (std::list<std::string>::iterator it = myInstrumentList.begin();
-               it != myInstrumentList.end(); ++it) {
+        for (std::list<std::string>::iterator it = myInstrumentList.begin();
+             it != myInstrumentList.end(); ++it) {
 
-            /* We don't check for filename equality here because
-             * filenames might actually be full paths. Instead we
-             * check that the actual filename ends in the filename
-             * specified in the list. */
-            if (instFilename.str().length() >= it->length()) {
+          /* We don't check for filename equality here because
+           * filenames might actually be full paths. Instead we
+           * check that the actual filename ends in the filename
+           * specified in the list. */
+          if (instFilename.str().length() >= it->length()) {
 
-              if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) ==
-                  0) {
+            if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) ==
+                0) {
 
-                instrumentFunction = true;
-                break;
-
-              }
+              instrumentFunction = true;
+              break;
 
             }
 
@@ -197,6 +204,15 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) {
 
         }
 
+      } else {
+
+        if (!be_quiet)
+          WARNF(
+              "No debug information found for function %s, recompile with -g "
+              "-O[1-3]",
+              F.getName().str().c_str());
+        continue;
+
       }
 
       /* Either we couldn't figure out our location or the location is
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
index 90cf3eb4..618abe48 100644
--- a/llvm_mode/afl-llvm-pass.so.cc
+++ b/llvm_mode/afl-llvm-pass.so.cc
@@ -82,7 +82,6 @@ class AFLCoverage : public ModulePass {
 
  protected:
   uint32_t ngram_size = 0;
-  uint32_t debug = 0;
   uint32_t map_size = MAP_SIZE;
   uint32_t function_minimum_size = 1;
   char *   ctx_str = NULL, *skip_nozero = NULL;
@@ -139,7 +138,6 @@ bool AFLCoverage::runOnModule(Module &M) {
 
   /* Show a banner */
 
-  char be_quiet = 0;
   setvbuf(stdout, NULL, _IONBF, 0);
 
   if (getenv("AFL_DEBUG")) debug = 1;
diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c
index f81d13ee..88abcbe0 100644
--- a/llvm_mode/afl-llvm-rt.o.c
+++ b/llvm_mode/afl-llvm-rt.o.c
@@ -53,7 +53,11 @@
 #define CONST_PRIO 5
 
 #ifndef MAP_FIXED_NOREPLACE
-  #define MAP_FIXED_NOREPLACE MAP_FIXED
+  #ifdef MAP_EXCL
+    #define MAP_FIXED_NOREPLACE MAP_EXCL | MAP_FIXED
+  #else
+    #define MAP_FIXED_NOREPLACE MAP_FIXED
+  #endif
 #endif
 
 #include <sys/mman.h>
@@ -510,12 +514,19 @@ static void __afl_start_snapshots(void) {
 
       if (!child_pid) {
 
+        //(void)nice(-20);  // does not seem to improve
+
         signal(SIGCHLD, old_sigchld_handler);
 
         close(FORKSRV_FD);
         close(FORKSRV_FD + 1);
 
-        if (!afl_snapshot_do()) { raise(SIGSTOP); }
+        if (!afl_snapshot_take(AFL_SNAPSHOT_MMAP | AFL_SNAPSHOT_FDS |
+                               AFL_SNAPSHOT_REGS | AFL_SNAPSHOT_EXIT)) {
+
+          raise(SIGSTOP);
+
+        }
 
         __afl_area_ptr[0] = 1;
         memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T));
@@ -713,6 +724,8 @@ static void __afl_start_forkserver(void) {
 
       if (!child_pid) {
 
+        //(void)nice(-20);
+
         signal(SIGCHLD, old_sigchld_handler);
 
         close(FORKSRV_FD);
@@ -846,6 +859,35 @@ __attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) {
 
 void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
 
+  // For stability analysis, if you want to know to which function unstable
+  // edge IDs belong to - uncomment, recompile+install llvm_mode, recompile
+  // the target. libunwind and libbacktrace are better solutions.
+  // Set AFL_DEBUG_CHILD_OUTPUT=1 and run afl-fuzz with 2>file to capture
+  // the backtrace output
+  /*
+  uint32_t unstable[] = { ... unstable edge IDs };
+  uint32_t idx;
+  char bt[1024];
+  for (idx = 0; i < sizeof(unstable)/sizeof(uint32_t); i++) {
+
+    if (unstable[idx] == __afl_area_ptr[*guard]) {
+
+      int bt_size = backtrace(bt, 256);
+      if (bt_size > 0) {
+
+        char **bt_syms = backtrace_symbols(bt, bt_size);
+        if (bt_syms)
+          fprintf(stderr, "DEBUG: edge=%u caller=%s\n", unstable[idx],
+  bt_syms[0]);
+
+      }
+
+    }
+
+  }
+
+  */
+
   __afl_area_ptr[*guard]++;
 
 }
diff --git a/llvm_mode/cmplog-instructions-pass.cc b/llvm_mode/cmplog-instructions-pass.cc
index f929361a..7c48d906 100644
--- a/llvm_mode/cmplog-instructions-pass.cc
+++ b/llvm_mode/cmplog-instructions-pass.cc
@@ -76,9 +76,6 @@ class CmpLogInstructions : public ModulePass {
 
   }
 
- protected:
-  int be_quiet = 0;
-
  private:
   bool hookInstrs(Module &M);
 
diff --git a/llvm_mode/cmplog-routines-pass.cc b/llvm_mode/cmplog-routines-pass.cc
index 318193a4..a0f8f64f 100644
--- a/llvm_mode/cmplog-routines-pass.cc
+++ b/llvm_mode/cmplog-routines-pass.cc
@@ -76,9 +76,6 @@ class CmpLogRoutines : public ModulePass {
 
   }
 
- protected:
-  int be_quiet = 0;
-
  private:
   bool hookRtns(Module &M);
 
diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc
index 2d1ab1cc..bed3597a 100644
--- a/llvm_mode/compare-transform-pass.so.cc
+++ b/llvm_mode/compare-transform-pass.so.cc
@@ -75,9 +75,6 @@ class CompareTransform : public ModulePass {
 
   }
 
- protected:
-  int be_quiet = 0;
-
  private:
   bool transformCmps(Module &M, const bool processStrcmp,
                      const bool processMemcmp, const bool processStrncmp,
@@ -358,7 +355,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
     Value *     VarStr;
     bool        HasStr1 = getConstantStringInfo(Str1P, Str1);
     bool        HasStr2 = getConstantStringInfo(Str2P, Str2);
-    uint64_t    constStrLen, constSizedLen, unrollLen;
+    uint64_t    constStrLen, unrollLen, constSizedLen = 0;
     bool        isMemcmp =
         !callInst->getCalledFunction()->getName().compare(StringRef("memcmp"));
     bool isSizedcmp = isMemcmp ||
@@ -474,8 +471,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
       if (cur_lenchk_bb) {
 
         IRBuilder<> cur_lenchk_IRB(&*(cur_lenchk_bb->getFirstInsertionPt()));
-        Value *     icmp = cur_lenchk_IRB.CreateICmpEQ(sizedValue,
-                                                  ConstantInt::get(Int64Ty, i));
+        Value *     icmp = cur_lenchk_IRB.CreateICmpEQ(
+            sizedValue, ConstantInt::get(sizedValue->getType(), i));
         cur_lenchk_IRB.CreateCondBr(icmp, end_bb, cur_cmp_bb);
         cur_lenchk_bb->getTerminator()->eraseFromParent();
 
diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc
index 651fa5b4..3630bd8c 100644
--- a/llvm_mode/split-compares-pass.so.cc
+++ b/llvm_mode/split-compares-pass.so.cc
@@ -71,15 +71,13 @@ class SplitComparesTransform : public ModulePass {
 
   }
 
- protected:
-  int be_quiet = 0;
-
  private:
   int enableFPSplit;
 
   size_t splitIntCompares(Module &M, unsigned bitw);
   size_t splitFPCompares(Module &M);
   bool   simplifyCompares(Module &M);
+  bool   simplifyFPCompares(Module &M);
   bool   simplifyIntSignedness(Module &M);
   size_t nextPowerOfTwo(size_t in);
 
@@ -89,12 +87,11 @@ class SplitComparesTransform : public ModulePass {
 
 char SplitComparesTransform::ID = 0;
 
-/* This function splits ICMP instructions with xGE or xLE predicates into two
- * ICMP instructions with predicate xGT or xLT and EQ */
-bool SplitComparesTransform::simplifyCompares(Module &M) {
+/* This function splits FCMP instructions with xGE or xLE predicates into two
+ * FCMP instructions with predicate xGT or xLT and EQ */
+bool SplitComparesTransform::simplifyFPCompares(Module &M) {
 
   LLVMContext &              C = M.getContext();
-  std::vector<Instruction *> icomps;
   std::vector<Instruction *> fcomps;
   IntegerType *              Int1Ty = IntegerType::getInt1Ty(C);
 
@@ -112,24 +109,6 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
 
         if ((selectcmpInst = dyn_cast<CmpInst>(&IN))) {
 
-          if (selectcmpInst->getPredicate() == CmpInst::ICMP_UGE ||
-              selectcmpInst->getPredicate() == CmpInst::ICMP_SGE ||
-              selectcmpInst->getPredicate() == CmpInst::ICMP_ULE ||
-              selectcmpInst->getPredicate() == CmpInst::ICMP_SLE) {
-
-            auto op0 = selectcmpInst->getOperand(0);
-            auto op1 = selectcmpInst->getOperand(1);
-
-            IntegerType *intTyOp0 = dyn_cast<IntegerType>(op0->getType());
-            IntegerType *intTyOp1 = dyn_cast<IntegerType>(op1->getType());
-
-            /* this is probably not needed but we do it anyway */
-            if (!intTyOp0 || !intTyOp1) { continue; }
-
-            icomps.push_back(selectcmpInst);
-
-          }
-
           if (enableFPSplit &&
               (selectcmpInst->getPredicate() == CmpInst::FCMP_OGE ||
                selectcmpInst->getPredicate() == CmpInst::FCMP_UGE ||
@@ -159,105 +138,159 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
 
   }
 
-  if (!icomps.size() && !fcomps.size()) { return false; }
+  if (!fcomps.size()) { return false; }
 
-  for (auto &IcmpInst : icomps) {
+  /* transform for floating point */
+  for (auto &FcmpInst : fcomps) {
 
-    BasicBlock *bb = IcmpInst->getParent();
+    BasicBlock *bb = FcmpInst->getParent();
 
-    auto op0 = IcmpInst->getOperand(0);
-    auto op1 = IcmpInst->getOperand(1);
+    auto op0 = FcmpInst->getOperand(0);
+    auto op1 = FcmpInst->getOperand(1);
 
     /* find out what the new predicate is going to be */
-    auto               pred = dyn_cast<CmpInst>(IcmpInst)->getPredicate();
+    auto               pred = dyn_cast<CmpInst>(FcmpInst)->getPredicate();
     CmpInst::Predicate new_pred;
     switch (pred) {
 
-      case CmpInst::ICMP_UGE:
-        new_pred = CmpInst::ICMP_UGT;
+      case CmpInst::FCMP_UGE:
+        new_pred = CmpInst::FCMP_UGT;
         break;
-      case CmpInst::ICMP_SGE:
-        new_pred = CmpInst::ICMP_SGT;
+      case CmpInst::FCMP_OGE:
+        new_pred = CmpInst::FCMP_OGT;
         break;
-      case CmpInst::ICMP_ULE:
-        new_pred = CmpInst::ICMP_ULT;
+      case CmpInst::FCMP_ULE:
+        new_pred = CmpInst::FCMP_ULT;
         break;
-      case CmpInst::ICMP_SLE:
-        new_pred = CmpInst::ICMP_SLT;
+      case CmpInst::FCMP_OLE:
+        new_pred = CmpInst::FCMP_OLT;
         break;
       default:  // keep the compiler happy
         continue;
 
     }
 
-    /* split before the icmp instruction */
-    BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(IcmpInst));
+    /* split before the fcmp instruction */
+    BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(FcmpInst));
 
     /* the old bb now contains a unconditional jump to the new one (end_bb)
      * we need to delete it later */
 
-    /* create the ICMP instruction with new_pred and add it to the old basic
-     * block bb it is now at the position where the old IcmpInst was */
-    Instruction *icmp_np;
-    icmp_np = CmpInst::Create(Instruction::ICmp, new_pred, op0, op1);
+    /* create the FCMP instruction with new_pred and add it to the old basic
+     * block bb it is now at the position where the old FcmpInst was */
+    Instruction *fcmp_np;
+    fcmp_np = CmpInst::Create(Instruction::FCmp, new_pred, op0, op1);
     bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()),
-                             icmp_np);
+                             fcmp_np);
 
-    /* create a new basic block which holds the new EQ icmp */
-    Instruction *icmp_eq;
+    /* create a new basic block which holds the new EQ fcmp */
+    Instruction *fcmp_eq;
     /* insert middle_bb before end_bb */
     BasicBlock *middle_bb =
         BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb);
-    icmp_eq = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, op0, op1);
-    middle_bb->getInstList().push_back(icmp_eq);
+    fcmp_eq = CmpInst::Create(Instruction::FCmp, CmpInst::FCMP_OEQ, op0, op1);
+    middle_bb->getInstList().push_back(fcmp_eq);
     /* add an unconditional branch to the end of middle_bb with destination
      * end_bb */
     BranchInst::Create(end_bb, middle_bb);
 
     /* replace the uncond branch with a conditional one, which depends on the
-     * new_pred icmp. True goes to end, false to the middle (injected) bb */
+     * new_pred fcmp. True goes to end, false to the middle (injected) bb */
     auto term = bb->getTerminator();
-    BranchInst::Create(end_bb, middle_bb, icmp_np, bb);
+    BranchInst::Create(end_bb, middle_bb, fcmp_np, bb);
     term->eraseFromParent();
 
-    /* replace the old IcmpInst (which is the first inst in end_bb) with a PHI
+    /* replace the old FcmpInst (which is the first inst in end_bb) with a PHI
      * inst to wire up the loose ends */
     PHINode *PN = PHINode::Create(Int1Ty, 2, "");
-    /* the first result depends on the outcome of icmp_eq */
-    PN->addIncoming(icmp_eq, middle_bb);
-    /* if the source was the original bb we know that the icmp_np yielded true
+    /* the first result depends on the outcome of fcmp_eq */
+    PN->addIncoming(fcmp_eq, middle_bb);
+    /* if the source was the original bb we know that the fcmp_np yielded true
      * hence we can hardcode this value */
     PN->addIncoming(ConstantInt::get(Int1Ty, 1), bb);
-    /* replace the old IcmpInst with our new and shiny PHI inst */
-    BasicBlock::iterator ii(IcmpInst);
-    ReplaceInstWithInst(IcmpInst->getParent()->getInstList(), ii, PN);
+    /* replace the old FcmpInst with our new and shiny PHI inst */
+    BasicBlock::iterator ii(FcmpInst);
+    ReplaceInstWithInst(FcmpInst->getParent()->getInstList(), ii, PN);
 
   }
 
-  /* now for floating point */
-  for (auto &FcmpInst : fcomps) {
+  return true;
 
-    BasicBlock *bb = FcmpInst->getParent();
+}
 
-    auto op0 = FcmpInst->getOperand(0);
-    auto op1 = FcmpInst->getOperand(1);
+/* This function splits ICMP instructions with xGE or xLE predicates into two
+ * ICMP instructions with predicate xGT or xLT and EQ */
+bool SplitComparesTransform::simplifyCompares(Module &M) {
+
+  LLVMContext &              C = M.getContext();
+  std::vector<Instruction *> icomps;
+  IntegerType *              Int1Ty = IntegerType::getInt1Ty(C);
+
+  /* iterate over all functions, bbs and instruction and add
+   * all integer comparisons with >= and <= predicates to the icomps vector */
+  for (auto &F : M) {
+
+    if (!isInInstrumentList(&F)) continue;
+
+    for (auto &BB : F) {
+
+      for (auto &IN : BB) {
+
+        CmpInst *selectcmpInst = nullptr;
+
+        if ((selectcmpInst = dyn_cast<CmpInst>(&IN))) {
+
+          if (selectcmpInst->getPredicate() == CmpInst::ICMP_UGE ||
+              selectcmpInst->getPredicate() == CmpInst::ICMP_SGE ||
+              selectcmpInst->getPredicate() == CmpInst::ICMP_ULE ||
+              selectcmpInst->getPredicate() == CmpInst::ICMP_SLE) {
+
+            auto op0 = selectcmpInst->getOperand(0);
+            auto op1 = selectcmpInst->getOperand(1);
+
+            IntegerType *intTyOp0 = dyn_cast<IntegerType>(op0->getType());
+            IntegerType *intTyOp1 = dyn_cast<IntegerType>(op1->getType());
+
+            /* this is probably not needed but we do it anyway */
+            if (!intTyOp0 || !intTyOp1) { continue; }
+
+            icomps.push_back(selectcmpInst);
+
+          }
+
+        }
+
+      }
+
+    }
+
+  }
+
+  if (!icomps.size()) { return false; }
+
+  for (auto &IcmpInst : icomps) {
+
+    BasicBlock *bb = IcmpInst->getParent();
+
+    auto op0 = IcmpInst->getOperand(0);
+    auto op1 = IcmpInst->getOperand(1);
 
     /* find out what the new predicate is going to be */
-    auto               pred = dyn_cast<CmpInst>(FcmpInst)->getPredicate();
+    auto               pred = dyn_cast<CmpInst>(IcmpInst)->getPredicate();
     CmpInst::Predicate new_pred;
     switch (pred) {
 
-      case CmpInst::FCMP_UGE:
-        new_pred = CmpInst::FCMP_UGT;
+      case CmpInst::ICMP_UGE:
+        new_pred = CmpInst::ICMP_UGT;
         break;
-      case CmpInst::FCMP_OGE:
-        new_pred = CmpInst::FCMP_OGT;
+      case CmpInst::ICMP_SGE:
+        new_pred = CmpInst::ICMP_SGT;
         break;
-      case CmpInst::FCMP_ULE:
-        new_pred = CmpInst::FCMP_ULT;
+      case CmpInst::ICMP_ULE:
+        new_pred = CmpInst::ICMP_ULT;
         break;
-      case CmpInst::FCMP_OLE:
-        new_pred = CmpInst::FCMP_OLT;
+      case CmpInst::ICMP_SLE:
+        new_pred = CmpInst::ICMP_SLT;
         break;
       default:  // keep the compiler happy
         continue;
@@ -265,25 +298,25 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
     }
 
     /* split before the icmp instruction */
-    BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(FcmpInst));
+    BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(IcmpInst));
 
     /* the old bb now contains a unconditional jump to the new one (end_bb)
      * we need to delete it later */
 
     /* create the ICMP instruction with new_pred and add it to the old basic
      * block bb it is now at the position where the old IcmpInst was */
-    Instruction *fcmp_np;
-    fcmp_np = CmpInst::Create(Instruction::FCmp, new_pred, op0, op1);
+    Instruction *icmp_np;
+    icmp_np = CmpInst::Create(Instruction::ICmp, new_pred, op0, op1);
     bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()),
-                             fcmp_np);
+                             icmp_np);
 
-    /* create a new basic block which holds the new EQ fcmp */
-    Instruction *fcmp_eq;
+    /* create a new basic block which holds the new EQ icmp */
+    Instruction *icmp_eq;
     /* insert middle_bb before end_bb */
     BasicBlock *middle_bb =
         BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb);
-    fcmp_eq = CmpInst::Create(Instruction::FCmp, CmpInst::FCMP_OEQ, op0, op1);
-    middle_bb->getInstList().push_back(fcmp_eq);
+    icmp_eq = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, op0, op1);
+    middle_bb->getInstList().push_back(icmp_eq);
     /* add an unconditional branch to the end of middle_bb with destination
      * end_bb */
     BranchInst::Create(end_bb, middle_bb);
@@ -291,20 +324,20 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
     /* replace the uncond branch with a conditional one, which depends on the
      * new_pred icmp. True goes to end, false to the middle (injected) bb */
     auto term = bb->getTerminator();
-    BranchInst::Create(end_bb, middle_bb, fcmp_np, bb);
+    BranchInst::Create(end_bb, middle_bb, icmp_np, bb);
     term->eraseFromParent();
 
     /* replace the old IcmpInst (which is the first inst in end_bb) with a PHI
      * inst to wire up the loose ends */
     PHINode *PN = PHINode::Create(Int1Ty, 2, "");
     /* the first result depends on the outcome of icmp_eq */
-    PN->addIncoming(fcmp_eq, middle_bb);
+    PN->addIncoming(icmp_eq, middle_bb);
     /* if the source was the original bb we know that the icmp_np yielded true
      * hence we can hardcode this value */
     PN->addIncoming(ConstantInt::get(Int1Ty, 1), bb);
     /* replace the old IcmpInst with our new and shiny PHI inst */
-    BasicBlock::iterator ii(FcmpInst);
-    ReplaceInstWithInst(FcmpInst->getParent()->getInstList(), ii, PN);
+    BasicBlock::iterator ii(IcmpInst);
+    ReplaceInstWithInst(IcmpInst->getParent()->getInstList(), ii, PN);
 
   }
 
@@ -640,7 +673,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
 
     BranchInst::Create(end_bb, signequal_bb);
 
-    /* create a new bb which is executed if exponents are equal */
+    /* create a new bb which is executed if exponents are satisfying the compare
+     */
     BasicBlock *middle_bb =
         BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb);
 
@@ -695,7 +729,9 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
     }
 
     /* compare the exponents of the operands */
+    Instruction *icmp_exponents_equal;
     Instruction *icmp_exponent_result;
+    BasicBlock * signequal2_bb = signequal_bb;
     switch (FcmpInst->getPredicate()) {
 
       case CmpInst::FCMP_OEQ:
@@ -707,22 +743,60 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
         icmp_exponent_result =
             CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, m_e0, m_e1);
         break;
+      /* compare the exponents of the operands (signs are equal)
+       * if exponents are equal -> proceed to mantissa comparison
+       * else get result depending on sign
+       */
       case CmpInst::FCMP_OGT:
       case CmpInst::FCMP_UGT:
         Instruction *icmp_exponent;
+        icmp_exponents_equal =
+            CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
+        signequal_bb->getInstList().insert(
+            BasicBlock::iterator(signequal_bb->getTerminator()),
+            icmp_exponents_equal);
+
+        // shortcut for unequal exponents
+        signequal2_bb = signequal_bb->splitBasicBlock(
+            BasicBlock::iterator(signequal_bb->getTerminator()));
+
+        /* if the exponents are equal goto middle_bb else to signequal2_bb */
+        term = signequal_bb->getTerminator();
+        BranchInst::Create(middle_bb, signequal2_bb, icmp_exponents_equal,
+                           signequal_bb);
+        term->eraseFromParent();
+
         icmp_exponent =
             CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, m_e0, m_e1);
-        signequal_bb->getInstList().insert(
-            BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponent);
+        signequal2_bb->getInstList().insert(
+            BasicBlock::iterator(signequal2_bb->getTerminator()),
+            icmp_exponent);
         icmp_exponent_result =
             BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0);
         break;
       case CmpInst::FCMP_OLT:
       case CmpInst::FCMP_ULT:
+        icmp_exponents_equal =
+            CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
+        signequal_bb->getInstList().insert(
+            BasicBlock::iterator(signequal_bb->getTerminator()),
+            icmp_exponents_equal);
+
+        // shortcut for unequal exponents
+        signequal2_bb = signequal_bb->splitBasicBlock(
+            BasicBlock::iterator(signequal_bb->getTerminator()));
+
+        /* if the exponents are equal goto middle_bb else to signequal2_bb */
+        term = signequal_bb->getTerminator();
+        BranchInst::Create(middle_bb, signequal2_bb, icmp_exponents_equal,
+                           signequal_bb);
+        term->eraseFromParent();
+
         icmp_exponent =
             CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, m_e0, m_e1);
-        signequal_bb->getInstList().insert(
-            BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponent);
+        signequal2_bb->getInstList().insert(
+            BasicBlock::iterator(signequal2_bb->getTerminator()),
+            icmp_exponent);
         icmp_exponent_result =
             BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0);
         break;
@@ -731,15 +805,40 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
 
     }
 
-    signequal_bb->getInstList().insert(
-        BasicBlock::iterator(signequal_bb->getTerminator()),
+    signequal2_bb->getInstList().insert(
+        BasicBlock::iterator(signequal2_bb->getTerminator()),
         icmp_exponent_result);
 
     {
 
-      auto term = signequal_bb->getTerminator();
-      /* if the exponents are different do a fraction cmp */
-      BranchInst::Create(middle_bb, end_bb, icmp_exponent_result, signequal_bb);
+      term = signequal2_bb->getTerminator();
+
+      switch (FcmpInst->getPredicate()) {
+
+        case CmpInst::FCMP_OEQ:
+          /* if the exponents are satifying the compare do a fraction cmp in
+           * middle_bb */
+          BranchInst::Create(middle_bb, end_bb, icmp_exponent_result,
+                             signequal2_bb);
+          break;
+        case CmpInst::FCMP_ONE:
+        case CmpInst::FCMP_UNE:
+          /* if the exponents are satifying the compare do a fraction cmp in
+           * middle_bb */
+          BranchInst::Create(end_bb, middle_bb, icmp_exponent_result,
+                             signequal2_bb);
+          break;
+        case CmpInst::FCMP_OGT:
+        case CmpInst::FCMP_UGT:
+        case CmpInst::FCMP_OLT:
+        case CmpInst::FCMP_ULT:
+          BranchInst::Create(end_bb, signequal2_bb);
+          break;
+        default:
+          continue;
+
+      }
+
       term->eraseFromParent();
 
     }
@@ -800,44 +899,82 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
 
     /* compare the fractions of the operands */
     Instruction *icmp_fraction_result;
+    Instruction *icmp_fraction_result2;
+    BasicBlock * middle2_bb = middle_bb;
+    PHINode *    PN2 = nullptr;
     switch (FcmpInst->getPredicate()) {
 
       case CmpInst::FCMP_OEQ:
         icmp_fraction_result =
             CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_f0, t_f1);
+        middle2_bb->getInstList().insert(
+            BasicBlock::iterator(middle2_bb->getTerminator()),
+            icmp_fraction_result);
+
         break;
       case CmpInst::FCMP_UNE:
       case CmpInst::FCMP_ONE:
         icmp_fraction_result =
             CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, t_f0, t_f1);
+        middle2_bb->getInstList().insert(
+            BasicBlock::iterator(middle2_bb->getTerminator()),
+            icmp_fraction_result);
+
         break;
       case CmpInst::FCMP_OGT:
       case CmpInst::FCMP_UGT:
-        Instruction *icmp_fraction;
-        icmp_fraction =
-            CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
-        middle_bb->getInstList().insert(
-            BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction);
-        icmp_fraction_result =
-            BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0);
-        break;
       case CmpInst::FCMP_OLT:
-      case CmpInst::FCMP_ULT:
-        icmp_fraction =
-            CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
-        middle_bb->getInstList().insert(
-            BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction);
-        icmp_fraction_result =
-            BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0);
-        break;
+      case CmpInst::FCMP_ULT: {
+
+        middle2_bb = middle_bb->splitBasicBlock(
+            BasicBlock::iterator(middle_bb->getTerminator()));
+
+        BasicBlock *negative_bb = BasicBlock::Create(
+            C, "negative_value", middle2_bb->getParent(), middle2_bb);
+        BasicBlock *positive_bb = BasicBlock::Create(
+            C, "positive_value", negative_bb->getParent(), negative_bb);
+
+        if (FcmpInst->getPredicate() == CmpInst::FCMP_OGT ||
+            FcmpInst->getPredicate() == CmpInst::FCMP_UGT) {
+
+          negative_bb->getInstList().push_back(
+              icmp_fraction_result = CmpInst::Create(
+                  Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1));
+          positive_bb->getInstList().push_back(
+              icmp_fraction_result2 = CmpInst::Create(
+                  Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1));
+
+        } else {
+
+          negative_bb->getInstList().push_back(
+              icmp_fraction_result = CmpInst::Create(
+                  Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1));
+          positive_bb->getInstList().push_back(
+              icmp_fraction_result2 = CmpInst::Create(
+                  Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1));
+
+        }
+
+        BranchInst::Create(middle2_bb, negative_bb);
+        BranchInst::Create(middle2_bb, positive_bb);
+
+        term = middle_bb->getTerminator();
+        BranchInst::Create(negative_bb, positive_bb, t_s0, middle_bb);
+        term->eraseFromParent();
+
+        PN2 = PHINode::Create(Int1Ty, 2, "");
+        PN2->addIncoming(icmp_fraction_result, negative_bb);
+        PN2->addIncoming(icmp_fraction_result2, positive_bb);
+        middle2_bb->getInstList().insert(
+            BasicBlock::iterator(middle2_bb->getTerminator()), PN2);
+
+      } break;
+
       default:
         continue;
 
     }
 
-    middle_bb->getInstList().insert(
-        BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction_result);
-
     PHINode *PN = PHINode::Create(Int1Ty, 3, "");
 
     switch (FcmpInst->getPredicate()) {
@@ -849,7 +986,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
         /* unequal exponents cannot be equal values, too */
         PN->addIncoming(ConstantInt::get(Int1Ty, 0), signequal_bb);
         /* fractions comparison */
-        PN->addIncoming(icmp_fraction_result, middle_bb);
+        PN->addIncoming(icmp_fraction_result, middle2_bb);
         break;
       case CmpInst::FCMP_ONE:
       case CmpInst::FCMP_UNE:
@@ -857,25 +994,25 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
         /* goto true branch */
         PN->addIncoming(ConstantInt::get(Int1Ty, 1), bb);
         /* unequal exponents are unequal values, too */
-        PN->addIncoming(ConstantInt::get(Int1Ty, 1), signequal_bb);
+        PN->addIncoming(icmp_exponent_result, signequal_bb);
         /* fractions comparison */
-        PN->addIncoming(icmp_fraction_result, middle_bb);
+        PN->addIncoming(icmp_fraction_result, middle2_bb);
         break;
       case CmpInst::FCMP_OGT:
       case CmpInst::FCMP_UGT:
         /* if op1 is negative goto true branch,
            else go on comparing */
         PN->addIncoming(t_s1, bb);
-        PN->addIncoming(icmp_exponent_result, signequal_bb);
-        PN->addIncoming(icmp_fraction_result, middle_bb);
+        PN->addIncoming(icmp_exponent_result, signequal2_bb);
+        PN->addIncoming(PN2, middle2_bb);
         break;
       case CmpInst::FCMP_OLT:
       case CmpInst::FCMP_ULT:
         /* if op0 is negative goto true branch,
            else go on comparing */
         PN->addIncoming(t_s0, bb);
-        PN->addIncoming(icmp_exponent_result, signequal_bb);
-        PN->addIncoming(icmp_fraction_result, middle_bb);
+        PN->addIncoming(icmp_exponent_result, signequal2_bb);
+        PN->addIncoming(PN2, middle2_bb);
         break;
       default:
         continue;
@@ -1107,7 +1244,8 @@ size_t SplitComparesTransform::splitIntCompares(Module &M, unsigned bitw) {
 
 bool SplitComparesTransform::runOnModule(Module &M) {
 
-  int bitw = 64;
+  int    bitw = 64;
+  size_t count;
 
   char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW");
   if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW");
@@ -1115,30 +1253,44 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
   enableFPSplit = getenv("AFL_LLVM_LAF_SPLIT_FLOATS") != NULL;
 
-  simplifyCompares(M);
-
-  simplifyIntSignedness(M);
-
   if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
       getenv("AFL_DEBUG") != NULL) {
 
     errs() << "Split-compare-pass by laf.intel@gmail.com, extended by "
               "heiko@hexco.de\n";
 
-    if (enableFPSplit)
-      errs() << "Split-floatingpoint-compare-pass: " << splitFPCompares(M)
+  } else {
+
+    be_quiet = 1;
+
+  }
+
+  if (enableFPSplit) {
+
+    count = splitFPCompares(M);
+
+    if (!be_quiet) {
+
+      errs() << "Split-floatingpoint-compare-pass: " << count
              << " FP comparisons splitted\n";
 
-  } else
+    }
 
-    be_quiet = 1;
+    simplifyFPCompares(M);
+
+  }
+
+  simplifyCompares(M);
+
+  simplifyIntSignedness(M);
 
   switch (bitw) {
 
     case 64:
+      count = splitIntCompares(M, bitw);
       if (!be_quiet)
-        errs() << "Split-integer-compare-pass " << bitw
-               << "bit: " << splitIntCompares(M, bitw) << " splitted\n";
+        errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
+               << " splitted\n";
 
       bitw >>= 1;
 #if LLVM_VERSION_MAJOR > 3 || \
@@ -1146,9 +1298,10 @@ bool SplitComparesTransform::runOnModule(Module &M) {
       [[clang::fallthrough]]; /*FALLTHRU*/                   /* FALLTHROUGH */
 #endif
     case 32:
+      count = splitIntCompares(M, bitw);
       if (!be_quiet)
-        errs() << "Split-integer-compare-pass " << bitw
-               << "bit: " << splitIntCompares(M, bitw) << " splitted\n";
+        errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
+               << " splitted\n";
 
       bitw >>= 1;
 #if LLVM_VERSION_MAJOR > 3 || \
@@ -1156,9 +1309,10 @@ bool SplitComparesTransform::runOnModule(Module &M) {
       [[clang::fallthrough]]; /*FALLTHRU*/                   /* FALLTHROUGH */
 #endif
     case 16:
+      count = splitIntCompares(M, bitw);
       if (!be_quiet)
-        errs() << "Split-integer-compare-pass " << bitw
-               << "bit: " << splitIntCompares(M, bitw) << " splitted\n";
+        errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
+               << " splitted\n";
 
       bitw >>= 1;
       break;
diff --git a/llvm_mode/split-switches-pass.so.cc b/llvm_mode/split-switches-pass.so.cc
index 44075c94..f025df77 100644
--- a/llvm_mode/split-switches-pass.so.cc
+++ b/llvm_mode/split-switches-pass.so.cc
@@ -91,9 +91,6 @@ class SplitSwitchesTransform : public ModulePass {
 
   typedef std::vector<CaseExpr> CaseVector;
 
- protected:
-  int be_quiet = 0;
-
  private:
   bool        splitSwitches(Module &M);
   bool        transformCmps(Module &M, const bool processStrcmp,