about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorJulian Büning <julian.buening@rwth-aachen.de>2019-03-20 22:01:00 +0100
committerMartinNowack <martin.nowack@gmail.com>2019-03-21 12:46:01 +0000
commit9767a37f9e8a743fa81629510346cb0a5a3a7900 (patch)
treebc49e16925582e41ee51cacc35c4f7bcafd8860f
parenteee440835b857a7cb68b72f4af4d22eaf19e1d76 (diff)
downloadklee-9767a37f9e8a743fa81629510346cb0a5a3a7900.tar.gz
drop support for LLVM <= 3.7
-rw-r--r--.travis.yml6
-rw-r--r--cmake/find_llvm.cmake21
-rw-r--r--include/klee/Internal/Support/FloatEvaluation.h5
-rw-r--r--include/klee/Internal/Support/ModuleUtil.h7
-rw-r--r--lib/Basic/CmdLineOptions.cpp10
-rw-r--r--lib/Core/CMakeLists.txt11
-rw-r--r--lib/Core/Executor.cpp26
-rw-r--r--lib/Core/ExecutorUtil.cpp6
-rw-r--r--lib/Core/ExternalDispatcher.cpp42
-rw-r--r--lib/Core/Searcher.cpp7
-rw-r--r--lib/Core/StatsTracker.cpp23
-rw-r--r--lib/Module/InstructionInfoTable.cpp91
-rw-r--r--lib/Module/InstructionOperandTypeCheckPass.cpp1
-rw-r--r--lib/Module/IntrinsicCleaner.cpp4
-rw-r--r--lib/Module/KModule.cpp28
-rw-r--r--lib/Module/LowerSwitch.cpp12
-rw-r--r--lib/Module/ModuleUtil.cpp134
-rw-r--r--lib/Module/OptNone.cpp8
-rw-r--r--lib/Module/Optimize.cpp34
-rw-r--r--lib/Module/RaiseAsm.cpp13
-rw-r--r--lib/Support/CompressionStream.cpp11
-rw-r--r--lib/Support/FileHandling.cpp8
-rw-r--r--scripts/build/p-clang-linux-ubuntu-16.04.inc4
-rw-r--r--scripts/build/p-llvm-linux-ubuntu-16.04.inc7
-rw-r--r--scripts/build/p-llvm.inc170
-rw-r--r--scripts/build/patches/llvm35.patch14
-rw-r--r--scripts/build/patches/llvm36.patch39
-rw-r--r--scripts/build/v-libcxx.inc8
-rw-r--r--scripts/build/v-uclibc.inc9
-rw-r--r--test/lit.cfg2
-rw-r--r--tools/kleaver/main.cpp14
-rw-r--r--tools/klee/main.cpp18
32 files changed, 110 insertions, 683 deletions
diff --git a/.travis.yml b/.travis.yml
index 789ef4e6..8b9cdf4b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,7 +12,7 @@ env:
     ###########################################################################
 
     # Check a subset of the matrix of:
-    #   LLVM  : {3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 5.0, 6.0, 7}
+    #   LLVM  : {3.8, 3.9, 4.0, 5.0, 6.0, 7}
     #   SOLVERS : {Z3, STP, STP:Z3, metaSMT}
     #   STP_VERSION   : {2.1.2, master}
     #   METASMT_VERSION : {v4.rc1}
@@ -62,10 +62,6 @@ env:
     - LLVM_VERSION=4.0
     - LLVM_VERSION=3.9
     - LLVM_VERSION=3.8
-    - LLVM_VERSION=3.7
-    - LLVM_VERSION=3.6 USE_LIBCXX=0
-    - LLVM_VERSION=3.5 USE_LIBCXX=0
-    - LLVM_VERSION=3.4 USE_LIBCXX=0
 
     # *Sanitizer builds. Do unoptimized build otherwise the optimizer might remove problematic code
     - SANITIZER_BUILD=address ENABLE_OPTIMIZED=0 USE_TCMALLOC=0
diff --git a/cmake/find_llvm.cmake b/cmake/find_llvm.cmake
index 8ceed19f..02c99960 100644
--- a/cmake/find_llvm.cmake
+++ b/cmake/find_llvm.cmake
@@ -12,10 +12,8 @@
 # * llvm-config executable. This method is portable across LLVM build systems
 # (i.e. works if LLVM was built with autoconf/Makefile or with CMake).
 #
-# * find_package(LLVM CONFIG). This method only works if LLVM was built with
-# CMake or with LLVM >= 3.5 when built with the autoconf/Makefile build system
-# This method relies on the `LLVMConfig.cmake` file generated to be generated
-# by LLVM's build system.
+# * find_package(LLVM CONFIG). This method relies on the `LLVMConfig.cmake` file
+# generated by LLVM's build system.
 #
 #===------------------------------------------------------------------------===#
 
@@ -26,11 +24,7 @@ if (USE_CMAKE_FIND_PACKAGE_LLVM)
 
   # Provide function to map LLVM components to libraries.
   function(klee_get_llvm_libs output_var)
-    if (${LLVM_PACKAGE_VERSION} VERSION_LESS "3.5")
-      llvm_map_components_to_libraries(${output_var} ${ARGN})
-    else()
-      llvm_map_components_to_libnames(${output_var} ${ARGN})
-    endif()
+    llvm_map_components_to_libnames(${output_var} ${ARGN})
     set(${output_var} ${${output_var}} PARENT_SCOPE)
   endfunction()
   # HACK: This information is not exported so just pretend its OFF for now.
@@ -154,14 +148,7 @@ else()
     string_to_list("${_llvm_libs}" _llvm_libs_list)
 
     # Now find the system libs that are needed.
-    if (${LLVM_PACKAGE_VERSION} VERSION_LESS "3.5")
-      # For LLVM 3.4 and older system libraries
-      # appeared in the output of `--ldflags`.
-      _run_llvm_config(_system_libs "--ldflags")
-      # TODO: Filter out `-L<path>` flag.
-    else()
-      _run_llvm_config(_system_libs "--system-libs")
-    endif()
+    _run_llvm_config(_system_libs "--system-libs")
     string_to_list("${_system_libs}" _system_libs_list)
 
     # Create an imported target for each LLVM library
diff --git a/include/klee/Internal/Support/FloatEvaluation.h b/include/klee/Internal/Support/FloatEvaluation.h
index 436e0dc8..62a5c0e7 100644
--- a/include/klee/Internal/Support/FloatEvaluation.h
+++ b/include/klee/Internal/Support/FloatEvaluation.h
@@ -132,15 +132,10 @@ inline uint64_t mod(uint64_t l, uint64_t r, unsigned inWidth) {
 // determine if l represents NaN
 inline bool isNaN(uint64_t l, unsigned inWidth) {
   switch( inWidth ) {
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7)
   case FLT_BITS:
     return std::isnan(UInt64AsFloat(l));
   case DBL_BITS:
     return std::isnan(UInt64AsDouble(l));
-#else
-  case FLT_BITS: return llvm::IsNAN( UInt64AsFloat(l) );
-  case DBL_BITS: return llvm::IsNAN( UInt64AsDouble(l) );
-#endif
   default: llvm::report_fatal_error("unsupported floating point width");
   }
 }
diff --git a/include/klee/Internal/Support/ModuleUtil.h b/include/klee/Internal/Support/ModuleUtil.h
index 6180225c..5fbfdb76 100644
--- a/include/klee/Internal/Support/ModuleUtil.h
+++ b/include/klee/Internal/Support/ModuleUtil.h
@@ -12,13 +12,8 @@
 
 #include "klee/Config/Version.h"
 
-#include "llvm/IR/Module.h"
-
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
 #include "llvm/IR/CallSite.h"
-#else
-#include "llvm/Support/CallSite.h"
-#endif
+#include "llvm/IR/Module.h"
 
 #include <memory>
 #include <string>
diff --git a/lib/Basic/CmdLineOptions.cpp b/lib/Basic/CmdLineOptions.cpp
index 2a58141e..9e190840 100644
--- a/lib/Basic/CmdLineOptions.cpp
+++ b/lib/Basic/CmdLineOptions.cpp
@@ -114,12 +114,7 @@ cl::opt<bool> UseAssignmentValidatingSolver(
 
 
 void KCommandLine::HideOptions(llvm::cl::OptionCategory &Category) {
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7)
   StringMap<cl::Option *> &map = cl::getRegisteredOptions();
-#else
-  StringMap<cl::Option *> map;
-  cl::getRegisteredOptions(map);
-#endif
 
   for (auto &elem : map) {
     if (elem.second->Category == &Category) {
@@ -129,12 +124,7 @@ void KCommandLine::HideOptions(llvm::cl::OptionCategory &Category) {
 }
 
 void KCommandLine::HideUnrelatedOptions(cl::OptionCategory &Category) {
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7)
   StringMap<cl::Option *> &map = cl::getRegisteredOptions();
-#else
-  StringMap<cl::Option *> map;
-  cl::getRegisteredOptions(map);
-#endif
   for (StringMap<cl::Option *>::iterator i = map.begin(), e = map.end(); i != e;
        i++) {
     if (i->second->Category != &Category) {
diff --git a/lib/Core/CMakeLists.txt b/lib/Core/CMakeLists.txt
index 4b14df36..83a6e001 100644
--- a/lib/Core/CMakeLists.txt
+++ b/lib/Core/CMakeLists.txt
@@ -33,17 +33,12 @@ klee_add_component(kleeCore
 # kleeCore.
 set(LLVM_COMPONENTS
   core
+  executionengine
+  mcjit
+  native
   support
 )
 
-if ("${LLVM_PACKAGE_VERSION}" VERSION_EQUAL "3.6" OR
-    "${LLVM_PACKAGE_VERSION}" VERSION_GREATER "3.6")
-  list(APPEND LLVM_COMPONENTS mcjit executionengine native)
-else()
-  list(APPEND LLVM_COMPONENTS jit engine)
-endif()
-
-
 klee_get_llvm_libs(LLVM_LIBS ${LLVM_COMPONENTS})
 target_link_libraries(kleeCore PUBLIC ${LLVM_LIBS})
 target_link_libraries(kleeCore PRIVATE
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index 7a676cc3..d14fae21 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -56,6 +56,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Function.h"
@@ -70,12 +71,6 @@
 #include "llvm/Support/Process.h"
 #include "llvm/Support/raw_ostream.h"
 
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-#include "llvm/Support/CallSite.h"
-#else
-#include "llvm/IR/CallSite.h"
-#endif
-
 #include <algorithm>
 #include <cassert>
 #include <cerrno>
@@ -597,11 +592,7 @@ void Executor::initializeGlobalObject(ExecutionState &state, ObjectState *os,
     for (unsigned i=0, e=cds->getNumElements(); i != e; ++i)
       initializeGlobalObject(state, os, cds->getElementAsConstant(i),
                              offset + i*elementSize);
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
   } else if (!isa<UndefValue>(c) && !isa<MetadataAsValue>(c)) {
-#else
-  } else if (!isa<UndefValue>(c)) {
-#endif
     unsigned StoreBits = targetData->getTypeStoreSizeInBits(c->getType());
     ref<ConstantExpr> C = evalConstant(c);
 
@@ -1560,13 +1551,8 @@ Function* Executor::getTargetFunction(Value *calledVal, ExecutionState &state) {
 
   while (true) {
     if (GlobalValue *gv = dyn_cast<GlobalValue>(c)) {
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
       if (!Visited.insert(gv).second)
         return 0;
-#else
-      if (!Visited.insert(gv))
-        return 0;
-#endif
       std::string alias = state.getFnAlias(gv->getName());
       if (alias != "") {
         GlobalValue *old_gv = gv;
@@ -1814,12 +1800,7 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
       std::map<ref<Expr>, BasicBlock *> expressionOrder;
 
       // Iterate through all non-default cases and order them by expressions
-#if LLVM_VERSION_CODE > LLVM_VERSION(3, 4)
       for (auto i : si->cases()) {
-#else
-      for (SwitchInst::CaseIt i = si->case_begin(), e = si->case_end(); i != e;
-           ++i) {
-#endif
         ref<Expr> value = evalConstant(i.getCaseValue());
 
         BasicBlock *caseSuccessor = i.getCaseSuccessor();
@@ -2402,13 +2383,8 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
         !fpWidthToSemantics(right->getWidth()))
       return terminateStateOnExecError(state, "Unsupported FRem operation");
     llvm::APFloat Res(*fpWidthToSemantics(left->getWidth()), left->getAPValue());
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
     Res.mod(
         APFloat(*fpWidthToSemantics(right->getWidth()), right->getAPValue()));
-#else
-    Res.mod(APFloat(*fpWidthToSemantics(right->getWidth()),right->getAPValue()),
-            APFloat::rmNearestTiesToEven);
-#endif
     bindLocal(ki, state, ConstantExpr::alloc(Res.bitcastToAPInt()));
     break;
   }
diff --git a/lib/Core/ExecutorUtil.cpp b/lib/Core/ExecutorUtil.cpp
index c80354e2..7b227eba 100644
--- a/lib/Core/ExecutorUtil.cpp
+++ b/lib/Core/ExecutorUtil.cpp
@@ -23,14 +23,10 @@
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-#include "llvm/Support/GetElementPtrTypeIterator.h"
-#else
-#include "llvm/IR/GetElementPtrTypeIterator.h"
-#endif
 #include "llvm/Support/raw_ostream.h"
 
 #include <cassert>
diff --git a/lib/Core/ExternalDispatcher.cpp b/lib/Core/ExternalDispatcher.cpp
index 28bc1898..2b537b7d 100644
--- a/lib/Core/ExternalDispatcher.cpp
+++ b/lib/Core/ExternalDispatcher.cpp
@@ -10,30 +10,19 @@
 #include "ExternalDispatcher.h"
 #include "klee/Config/Version.h"
 
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
-#include "llvm/ExecutionEngine/MCJIT.h"
-#else
-#include "llvm/ExecutionEngine/JIT.h"
-#endif
-
 #include "llvm/ExecutionEngine/GenericValue.h"
+#include "llvm/ExecutionEngine/MCJIT.h"
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/raw_ostream.h"
-
 #include "llvm/Support/TargetSelect.h"
 
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-#include "llvm/Support/CallSite.h"
-#else
-#include "llvm/IR/CallSite.h"
-#endif
-
 #include <csetjmp>
 #include <csignal>
 
@@ -122,11 +111,6 @@ ExternalDispatcherImpl::ExternalDispatcherImpl(LLVMContext &ctx)
     : ctx(ctx), lastErrno(0) {
   std::string error;
   singleDispatchModule = new Module(getFreshModuleID(), ctx);
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 6)
-  // Use old JIT
-  executionEngine = ExecutionEngine::createJIT(singleDispatchModule, &error);
-#else
-  // Use MCJIT.
   // The MCJIT JITs whole modules at a time rather than individual functions
   // so we will let it manage the modules.
   // Note that we don't do anything with `singleDispatchModule`. This is just
@@ -136,7 +120,6 @@ ExternalDispatcherImpl::ExternalDispatcherImpl(LLVMContext &ctx)
                         .setErrorStr(&error)
                         .setEngineKind(EngineKind::JIT)
                         .create();
-#endif
 
   if (!executionEngine) {
     llvm::errs() << "unable to make jit: " << error << "\n";
@@ -146,10 +129,8 @@ ExternalDispatcherImpl::ExternalDispatcherImpl(LLVMContext &ctx)
   // If we have a native target, initialize it to ensure it is linked in and
   // usable by the JIT.
   llvm::InitializeNativeTarget();
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
   llvm::InitializeNativeTargetAsmParser();
   llvm::InitializeNativeTargetAsmPrinter();
-#endif
 
   // from ExecutionEngine::create
   if (executionEngine) {
@@ -197,21 +178,16 @@ bool ExternalDispatcherImpl::executeCall(Function *f, Instruction *i,
 #endif
 
   Module *dispatchModule = NULL;
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
   // The MCJIT generates whole modules at a time so for every call that we
   // haven't made before we need to create a new Module.
   dispatchModule = new Module(getFreshModuleID(), ctx);
-#else
-  dispatchModule = this->singleDispatchModule;
-#endif
   dispatcher = createDispatcher(f, i, dispatchModule);
   dispatchers.insert(std::make_pair(i, dispatcher));
 
-// Force the JIT execution engine to go ahead and build the function. This
-// ensures that any errors or assertions in the compilation process will
-// trigger crashes instead of being caught as aborts in the external
-// function.
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+  // Force the JIT execution engine to go ahead and build the function. This
+  // ensures that any errors or assertions in the compilation process will
+  // trigger crashes instead of being caught as aborts in the external
+  // function.
   if (dispatcher) {
     // The dispatchModule is now ready so tell MCJIT to generate the code for
     // it.
@@ -228,12 +204,6 @@ bool ExternalDispatcherImpl::executeCall(Function *f, Instruction *i,
     // MCJIT didn't take ownership of the module so delete it.
     delete dispatchModule;
   }
-#else
-  if (dispatcher) {
-    // Old JIT works on a function at a time so compile the function.
-    executionEngine->recompileAndRelinkFunction(dispatcher);
-  }
-#endif
   return runProtectedCall(dispatcher, args);
 }
 
diff --git a/lib/Core/Searcher.cpp b/lib/Core/Searcher.cpp
index 47457a91..49f6e52b 100644
--- a/lib/Core/Searcher.cpp
+++ b/lib/Core/Searcher.cpp
@@ -25,17 +25,12 @@
 #include "klee/Internal/Support/ModuleUtil.h"
 #include "klee/Internal/System/Time.h"
 #include "klee/Internal/Support/ErrorHandling.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/CommandLine.h"
 
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-#include "llvm/Support/CallSite.h"
-#else
-#include "llvm/IR/CallSite.h"
-#endif
-
 #include <cassert>
 #include <fstream>
 #include <climits>
diff --git a/lib/Core/StatsTracker.cpp b/lib/Core/StatsTracker.cpp
index c0e3264d..dac18370 100644
--- a/lib/Core/StatsTracker.cpp
+++ b/lib/Core/StatsTracker.cpp
@@ -27,6 +27,8 @@
 #include "UserSearcher.h"
 
 #include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/CFG.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
@@ -38,14 +40,6 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/FileSystem.h"
 
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-#include "llvm/Support/CallSite.h"
-#include "llvm/Support/CFG.h"
-#else
-#include "llvm/IR/CallSite.h"
-#include "llvm/IR/CFG.h"
-#endif
-
 #include <fstream>
 #include <unistd.h>
 
@@ -207,17 +201,8 @@ StatsTracker::StatsTracker(Executor &_executor, std::string _objectFilename,
   if (!sys::path::is_absolute(objectFilename)) {
     SmallString<128> current(objectFilename);
     if(sys::fs::make_absolute(current)) {
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
       Twine current_twine(current.str()); // requires a twine for this
       if (!sys::fs::exists(current_twine)) {
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
-      bool exists = false;
-      if (!sys::fs::exists(current.str(), exists)) {
-#else
-      bool exists = false;
-      error_code ec = sys::fs::exists(current.str(), exists);
-      if (ec == errc::success && exists) {
-#endif
         objectFilename = current.c_str();
       }
     }
@@ -643,11 +628,7 @@ static std::vector<Instruction*> getSuccs(Instruction *i) {
     for (succ_iterator it = succ_begin(bb), ie = succ_end(bb); it != ie; ++it)
       res.push_back(&*(it->begin()));
   } else {
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
     res.push_back(&*(++(i->getIterator())));
-#else
-    res.push_back(&*(++BasicBlock::iterator(i)));
-#endif
   }
 
   return res;
diff --git a/lib/Module/InstructionInfoTable.cpp b/lib/Module/InstructionInfoTable.cpp
index 6ff49669..48575c82 100644
--- a/lib/Module/InstructionInfoTable.cpp
+++ b/lib/Module/InstructionInfoTable.cpp
@@ -10,41 +10,21 @@
 #include "klee/Internal/Module/InstructionInfoTable.h"
 #include "klee/Config/Version.h"
 
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/AssemblyAnnotationWriter.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/InstIterator.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
-
-# if LLVM_VERSION_CODE < LLVM_VERSION(3,5)
-#include "llvm/Assembly/AssemblyAnnotationWriter.h"
-#include "llvm/Support/InstIterator.h"
-#include "llvm/Linker.h"
-#else
-#include "llvm/IR/AssemblyAnnotationWriter.h"
-#include "llvm/IR/InstIterator.h"
 #include "llvm/Linker/Linker.h"
-#endif
-
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/raw_ostream.h"
-
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3,5)
-#include "llvm/IR/DebugInfo.h"
-#else
-#include "llvm/DebugInfo.h"
-#endif
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7)
-#include "llvm/IR/DebugInfoMetadata.h"
-#endif
-
-#if LLVM_VERSION_CODE == LLVM_VERSION(3, 6)
-#include "llvm/Support/Debug.h"
-#endif
-
-#include "llvm/Analysis/ValueTracking.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormattedStream.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
 
 #include <cstdint>
 #include <map>
@@ -112,9 +92,6 @@ static std::string getFullPath(llvm::StringRef Directory,
 class DebugInfoExtractor {
   std::vector<std::unique_ptr<std::string>> &internedStrings;
   std::map<uintptr_t, uint64_t> lineTable;
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 8)
-  llvm::DebugInfoFinder DIF;
-#endif
 
   const llvm::Module &module;
 
@@ -123,9 +100,6 @@ public:
       std::vector<std::unique_ptr<std::string>> &_internedStrings,
       const llvm::Module &_module)
       : internedStrings(_internedStrings), module(_module) {
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 8)
-    DIF.processModule(module);
-#endif
     lineTable = buildInstructionToLineMap(module);
   }
 
@@ -146,8 +120,6 @@ public:
 
   std::unique_ptr<FunctionInfo> getFunctionInfo(const llvm::Function &Func) {
     auto asmLine = lineTable.at(reinterpret_cast<std::uintptr_t>(&Func));
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
-
 #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 9)
     auto dsub = Func.getSubprogram();
 #else
@@ -159,33 +131,6 @@ public:
           0, getInternedString(path), dsub->getLine(), asmLine));
     }
 
-#elif LLVM_VERSION_CODE == LLVM_VERSION(3, 7)
-    for (const auto SP : DIF.subprograms()) {
-      auto &SubProgram = *SP;
-      if (SubProgram.getFunction() != &Func)
-        continue;
-      auto path =
-          getFullPath(SubProgram.getDirectory(), SubProgram.getFilename());
-      return std::unique_ptr<FunctionInfo>(new FunctionInfo(
-          0, getInternedString(path), SubProgram.getLine(), asmLine));
-    }
-#endif
-
-#if LLVM_VERSION_CODE <= LLVM_VERSION(3, 6)
-    // Workaround missing debug information for older LLVM versions
-    // Search for any instructions inside this function with debug information
-    // and assume it's part of this function in the source code as well.
-    for (auto it = llvm::inst_begin(&Func), ie = llvm::inst_end(&Func);
-         it != ie; ++it) {
-      auto iInfo = getInstructionInfo(*it, nullptr);
-      if (iInfo->file.empty())
-        continue;
-      // Found an instruction
-      return std::unique_ptr<FunctionInfo>(new FunctionInfo(
-          0, getInternedString(iInfo->file), iInfo->line, asmLine));
-    }
-
-#endif
     // Fallback: Mark as unknown
     return std::unique_ptr<FunctionInfo>(
         new FunctionInfo(0, getInternedString(""), 0, asmLine));
@@ -195,7 +140,6 @@ public:
   getInstructionInfo(const llvm::Instruction &Inst, const FunctionInfo *f) {
     auto asmLine = lineTable.at(reinterpret_cast<std::uintptr_t>(&Inst));
 
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
     // Retrieve debug information associated with instruction
     auto dl = Inst.getDebugLoc();
 
@@ -217,27 +161,6 @@ public:
       return std::unique_ptr<InstructionInfo>(new InstructionInfo(
           0, getInternedString(full_path), line, column, asmLine));
     }
-#elif LLVM_VERSION_CODE == LLVM_VERSION(3, 7)
-    // Retrieve debug information
-    llvm::DebugLoc Loc(Inst.getDebugLoc());
-    // Check if valid
-    if (Loc.get() != nullptr) {
-      auto subProg = getDISubprogram(Loc.getScope());
-      auto full_path =
-          getFullPath(subProg->getDirectory(), subProg->getFilename());
-      return std::unique_ptr<InstructionInfo>(
-          new InstructionInfo(0, getInternedString(full_path), Loc.getLine(),
-                              Loc.getCol(), asmLine));
-    }
-#elif LLVM_VERSION_CODE <= LLVM_VERSION(3, 6)
-    if (llvm::MDNode *N = Inst.getMetadata("dbg")) {
-      llvm::DILocation Loc(N);
-      auto path = getFullPath(Loc.getDirectory(), Loc.getFilename());
-      auto Line = Loc.getLineNumber();
-      return std::unique_ptr<InstructionInfo>(
-          new InstructionInfo(0, getInternedString(path), Line, 0, asmLine));
-    }
-#endif
 
     if (f != nullptr)
       // If nothing found, use the surrounding function
diff --git a/lib/Module/InstructionOperandTypeCheckPass.cpp b/lib/Module/InstructionOperandTypeCheckPass.cpp
index 1a1422ec..39222d0f 100644
--- a/lib/Module/InstructionOperandTypeCheckPass.cpp
+++ b/lib/Module/InstructionOperandTypeCheckPass.cpp
@@ -98,7 +98,6 @@ bool checkInstruction(const Instruction *i) {
            checkOperandsHaveSameType(i, 1, 2);
   }
   // Integer arithmetic, logical and shifting
-  // TODO: When we upgrade to newer LLVM use LLVM_FALLTHROUGH
   case Instruction::Add:
   case Instruction::Sub:
   case Instruction::Mul:
diff --git a/lib/Module/IntrinsicCleaner.cpp b/lib/Module/IntrinsicCleaner.cpp
index 4c0920b3..dde97036 100644
--- a/lib/Module/IntrinsicCleaner.cpp
+++ b/lib/Module/IntrinsicCleaner.cpp
@@ -109,11 +109,7 @@ bool IntrinsicCleanerPass::runOnBasicBlock(BasicBlock &b, Module &M) {
       case Intrinsic::uadd_with_overflow:
       case Intrinsic::usub_with_overflow:
       case Intrinsic::umul_with_overflow: {
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
         IRBuilder<> builder(ii->getParent(), ii->getIterator());
-#else
-        IRBuilder<> builder(ii->getParent(), ii);
-#endif
 
         Value *op1 = ii->getArgOperand(0);
         Value *op2 = ii->getArgOperand(1);
diff --git a/lib/Module/KModule.cpp b/lib/Module/KModule.cpp
index 207d4bd4..2ee49f23 100644
--- a/lib/Module/KModule.cpp
+++ b/lib/Module/KModule.cpp
@@ -27,6 +27,7 @@
 #else
 #include "llvm/Bitcode/ReaderWriter.h"
 #endif
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Instructions.h"
@@ -34,28 +35,17 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/ValueSymbolTable.h"
-
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/Linker.h"
-#include "llvm/Support/CallSite.h"
-#else
-#include "llvm/IR/CallSite.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/Linker/Linker.h"
-#endif
-
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/raw_os_ostream.h"
-#include "llvm/Support/Path.h"
 #include "llvm/Transforms/Scalar.h"
 #if LLVM_VERSION_CODE >= LLVM_VERSION(8, 0)
 #include "llvm/Transforms/Scalar/Scalarizer.h"
 #endif
-
 #include "llvm/Transforms/Utils/Cloning.h"
-
 #if LLVM_VERSION_CODE >= LLVM_VERSION(7, 0)
 #include "llvm/Transforms/Utils.h"
 #endif
@@ -150,14 +140,10 @@ static Function *getStubFunctionForCtorList(Module *m,
   if (arr) {
     for (unsigned i=0; i<arr->getNumOperands(); i++) {
       auto cs = cast<ConstantStruct>(arr->getOperand(i));
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
       // There is a third *optional* element in global_ctor elements (``i8
       // @data``).
       assert((cs->getNumOperands() == 2 || cs->getNumOperands() == 3) &&
              "unexpected element in ctor initializer list");
-#else
-      assert(cs->getNumOperands()==2 && "unexpected element in ctor initializer list");
-#endif
       auto fp = cs->getOperand(1);
       if (!fp->isNullValue()) {
         if (auto ce = dyn_cast<llvm::ConstantExpr>(fp))
@@ -192,11 +178,7 @@ injectStaticConstructorsAndDestructors(Module *m,
                entryFunction.str().c_str());
 
   if (ctors) {
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
     llvm::IRBuilder<> Builder(&*mainFn->begin()->begin());
-#else
-    llvm::IRBuilder<> Builder(mainFn->begin()->begin());
-#endif
     Builder.CreateCall(getStubFunctionForCtorList(m, ctors, "klee.ctor_stub"));
   }
 
@@ -425,14 +407,8 @@ static int getOperandNum(Value *v,
     return registerMap[inst];
   } else if (Argument *a = dyn_cast<Argument>(v)) {
     return a->getArgNo();
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
-    // Metadata is no longer a Value
   } else if (isa<BasicBlock>(v) || isa<InlineAsm>(v) ||
              isa<MetadataAsValue>(v)) {
-#else
-  } else if (isa<BasicBlock>(v) || isa<InlineAsm>(v) ||
-             isa<MDNode>(v)) {
-#endif
     return -1;
   } else {
     assert(isa<Constant>(v));
diff --git a/lib/Module/LowerSwitch.cpp b/lib/Module/LowerSwitch.cpp
index 4d80ddd8..b23278f7 100644
--- a/lib/Module/LowerSwitch.cpp
+++ b/lib/Module/LowerSwitch.cpp
@@ -66,11 +66,7 @@ void LowerSwitchPass::switchConvert(CaseItr begin, CaseItr end,
   // iterate through all the cases, creating a new BasicBlock for each
   for (CaseItr it = begin; it < end; ++it) {
     BasicBlock *newBlock = BasicBlock::Create(F->getContext(), "NodeBlock");
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
     Function::iterator FI = origBlock->getIterator();
-#else
-    Function::iterator FI = origBlock;
-#endif
     F->getBasicBlockList().insert(++FI, newBlock);
     Builder.SetInsertPoint(newBlock);
     auto cmpValue = Builder.CreateICmpEQ(value, it->value, "case.cmp");
@@ -108,11 +104,7 @@ void LowerSwitchPass::processSwitchInst(SwitchInst *SI) {
   BasicBlock* newDefault = BasicBlock::Create(F->getContext(), "newDefault");
   llvm::IRBuilder<> Builder(newDefault);
 
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
   F->getBasicBlockList().insert(defaultBlock->getIterator(), newDefault);
-#else
-  F->getBasicBlockList().insert(defaultBlock, newDefault);
-#endif
   Builder.CreateBr(defaultBlock);
 
   // If there is an entry in any PHI nodes for the default edge, make sure
@@ -126,11 +118,7 @@ void LowerSwitchPass::processSwitchInst(SwitchInst *SI) {
   
   CaseVector cases;
 
-#if LLVM_VERSION_CODE > LLVM_VERSION(3, 4)
   for (auto i : SI->cases())
-#else
-  for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end(); i != e; ++i)
-#endif
     cases.push_back(SwitchCase(i.getCaseValue(),
                                i.getCaseSuccessor()));
   
diff --git a/lib/Module/ModuleUtil.cpp b/lib/Module/ModuleUtil.cpp
index 6152c1df..6adaee6d 100644
--- a/lib/Module/ModuleUtil.cpp
+++ b/lib/Module/ModuleUtil.cpp
@@ -13,9 +13,13 @@
 #include "klee/Internal/Support/Debug.h"
 #include "klee/Internal/Support/ErrorHandling.h"
 
+#include "llvm/Analysis/ValueTracking.h"
 #if LLVM_VERSION_CODE >= LLVM_VERSION(5, 0)
 #include "llvm/BinaryFormat/Magic.h"
 #endif
+#include "llvm/IR/AssemblyAnnotationWriter.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
@@ -23,6 +27,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/IR/ValueSymbolTable.h"
 #include "llvm/IRReader/IRReader.h"
+#include "llvm/Linker/Linker.h"
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/Error.h"
 #include "llvm/Object/ObjectFile.h"
@@ -30,32 +35,17 @@
 #include "llvm/Support/DataStream.h"
 #endif
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/SourceMgr.h"
 
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-#include "llvm/Assembly/AssemblyAnnotationWriter.h"
-#include "llvm/Linker.h"
-#else
-#include "llvm/IR/AssemblyAnnotationWriter.h"
-#include "llvm/Linker/Linker.h"
-#endif
-
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
-#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/IR/DiagnosticPrinter.h"
-#endif
-
 #if LLVM_VERSION_CODE >= LLVM_VERSION(4, 0)
 #include <llvm/Bitcode/BitcodeReader.h>
 #else
 #include <llvm/Bitcode/ReaderWriter.h>
 #endif
 
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Path.h"
-
 #include <algorithm>
 #include <fstream>
 #include <map>
@@ -94,13 +84,8 @@ GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) {
       if (Function.isDeclaration())
         UndefinedSymbols.insert(Function.getName());
       else if (!Function.hasLocalLinkage()) {
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-        assert(!Function.hasDLLImportLinkage() &&
-               "Found dllimported non-external symbol!");
-#else
         assert(!Function.hasDLLImportStorageClass() &&
                "Found dllimported non-external symbol!");
-#endif
         DefinedSymbols.insert(Function.getName());
       }
     }
@@ -112,11 +97,7 @@ GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) {
       if (I->isDeclaration())
         UndefinedSymbols.insert(I->getName());
       else if (!I->hasLocalLinkage()) {
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-            assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!");
-#else
-            assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!");
-#endif
+        assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!");
         DefinedSymbols.insert(I->getName());
       }
     }
@@ -164,20 +145,9 @@ GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) {
 static bool linkTwoModules(llvm::Module *Dest,
                            std::unique_ptr<llvm::Module> Src,
                            std::string &errorMsg) {
-
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
   // Get the potential error message (Src is moved and won't be available later)
   errorMsg = "Linking module " + Src->getModuleIdentifier() + " failed";
   auto linkResult = Linker::linkModules(*Dest, std::move(Src));
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
-  raw_string_ostream Stream(errorMsg);
-  DiagnosticPrinterRawOStream DP(Stream);
-  auto linkResult = Linker::LinkModules(
-      Dest, Src.release(), [&](const DiagnosticInfo &DI) { DI.print(DP); });
-#else
-  auto linkResult = Linker::LinkModules(Dest, Src.release(),
-                                        Linker::DestroySource, &errorMsg);
-#endif
 
   return !linkResult;
 }
@@ -316,12 +286,7 @@ Function *klee::getDirectCallTarget(CallSite cs, bool moduleIsFullyLinked) {
 }
 
 static bool valueIsOnlyCalled(const Value *v) {
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-  for (auto it = v->use_begin(), ie = v->use_end(); it != ie; ++it) {
-    auto user = *it;
-#else
   for (auto user : v->users()) {
-#endif
     if (const auto *instr = dyn_cast<Instruction>(user)) {
       // Make sure the instruction is a call or invoke.
       CallSite cs(const_cast<Instruction *>(instr));
@@ -360,31 +325,20 @@ bool klee::loadFile(const std::string &fileName, LLVMContext &context,
   KLEE_DEBUG_WITH_TYPE("klee_loader", dbgs()
                                           << "Load file " << fileName << "\n");
 
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
   ErrorOr<std::unique_ptr<MemoryBuffer>> bufferErr =
       MemoryBuffer::getFileOrSTDIN(fileName);
   std::error_code ec = bufferErr.getError();
-#else
-  OwningPtr<MemoryBuffer> Buffer;
-  error_code ec = MemoryBuffer::getFileOrSTDIN(fileName, Buffer);
-#endif
   if (ec) {
     klee_error("Loading file %s failed: %s", fileName.c_str(),
                ec.message().c_str());
   }
 
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
   MemoryBufferRef Buffer = bufferErr.get()->getMemBufferRef();
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
-  MemoryBuffer *Buffer = bufferErr->get();
-#endif
 
 #if LLVM_VERSION_CODE >= LLVM_VERSION(5, 0)
   file_magic magic = identify_magic(Buffer.getBuffer());
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
-  sys::fs::file_magic magic = sys::fs::identify_magic(Buffer.getBuffer());
 #else
-  sys::fs::file_magic magic = sys::fs::identify_magic(Buffer->getBuffer());
+  sys::fs::file_magic magic = sys::fs::identify_magic(Buffer.getBuffer());
 #endif
 
 #if LLVM_VERSION_CODE >= LLVM_VERSION(5, 0)
@@ -393,13 +347,7 @@ bool klee::loadFile(const std::string &fileName, LLVMContext &context,
   if (magic == sys::fs::file_magic::bitcode) {
 #endif
     SMDiagnostic Err;
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
     std::unique_ptr<llvm::Module> module(parseIR(Buffer, Err, context));
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
-    std::unique_ptr<llvm::Module> module(ParseIR(Buffer, Err, context));
-#else
-    std::unique_ptr<llvm::Module> module(ParseIR(Buffer.take(), Err, context));
-#endif
     if (!module) {
       klee_error("Loading file %s failed: %s", fileName.c_str(),
                  Err.getMessage().str().c_str());
@@ -419,20 +367,11 @@ bool klee::loadFile(const std::string &fileName, LLVMContext &context,
     if (!archOwner)
       ec = errorToErrorCode(archOwner.takeError());
     llvm::object::Binary *arch = archOwner.get().get();
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+#else
     ErrorOr<std::unique_ptr<object::Binary>> archOwner =
         object::createBinary(Buffer, &context);
     ec = archOwner.getError();
     llvm::object::Binary *arch = archOwner.get().get();
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
-    ErrorOr<object::Binary *> archOwner =
-        object::createBinary(std::move(bufferErr.get()), &context);
-    ec = archOwner.getError();
-    llvm::object::Binary *arch = archOwner.get();
-#else
-    OwningPtr<object::Binary> archOwner;
-    ec = object::createBinary(Buffer.take(), archOwner);
-    llvm::object::Binary *arch = archOwner.get();
 #endif
     if (ec)
       klee_error("Loading file %s failed: %s", fileName.c_str(),
@@ -442,33 +381,22 @@ bool klee::loadFile(const std::string &fileName, LLVMContext &context,
 // Load all bitcode files into memory
 #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 9)
       auto Err = Error::success();
-      for (object::Archive::child_iterator AI = archive->child_begin(Err),
-                                           AE = archive->child_end();
-           AI != AE; ++AI)
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
-      for (object::Archive::child_iterator AI = archive->child_begin(),
-                                           AE = archive->child_end();
+      for (auto AI = archive->child_begin(Err), AE = archive->child_end();
            AI != AE; ++AI)
 #else
-      for (object::Archive::child_iterator AI = archive->begin_children(),
-                                           AE = archive->end_children();
+      for (auto AI = archive->child_begin(), AE = archive->child_end();
            AI != AE; ++AI)
 #endif
       {
 
         StringRef memberName;
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
         std::error_code ec;
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
         ErrorOr<object::Archive::Child> childOrErr = *AI;
         ec = childOrErr.getError();
         if (ec) {
                 errorMsg = ec.message();
                 return false;
         }
-#else
-	object::Archive::child_iterator childOrErr = AI;
-#endif
         auto memberNameErr = childOrErr->getName();
 #if LLVM_VERSION_CODE >= LLVM_VERSION(4, 0)
         ec = memberNameErr ? std::error_code() :
@@ -478,11 +406,6 @@ bool klee::loadFile(const std::string &fileName, LLVMContext &context,
 #endif
         if (!ec) {
           memberName = memberNameErr.get();
-#else
-        error_code ec = AI->getName(memberName);
-
-        if (ec == errc::success) {
-#endif
           KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs()
                                                   << "Loading archive member "
                                                   << memberName << "\n");
@@ -496,34 +419,19 @@ bool klee::loadFile(const std::string &fileName, LLVMContext &context,
             childOrErr->getAsBinary();
         if (!child)
           ec = errorToErrorCode(child.takeError());
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+#else
         ErrorOr<std::unique_ptr<llvm::object::Binary>> child =
             childOrErr->getAsBinary();
         ec = child.getError();
-#else
-        OwningPtr<object::Binary> child;
-        ec = AI->getAsBinary(child);
 #endif
         if (ec) {
 // If we can't open as a binary object file its hopefully a bitcode file
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
           auto buff = childOrErr->getMemoryBufferRef();
 #if LLVM_VERSION_CODE >= LLVM_VERSION(4, 0)
           ec = buff ? std::error_code() : errorToErrorCode(buff.takeError());
 #else
           ec = buff.getError();
 #endif
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
-          ErrorOr<std::unique_ptr<MemoryBuffer>> buffErr =
-              AI->getMemoryBuffer();
-          std::unique_ptr<MemoryBuffer> buff = nullptr;
-          ec = buffErr.getError();
-          if (!ec)
-            buff = std::move(buffErr.get());
-#else
-        OwningPtr<MemoryBuffer> buff;
-        ec = AI->getMemoryBuffer(buff);
-#endif
           if (ec) {
             errorMsg = "Failed to get MemoryBuffer: " + ec.message();
             return false;
@@ -534,16 +442,8 @@ bool klee::loadFile(const std::string &fileName, LLVMContext &context,
             // materialise
             // the module
             SMDiagnostic Err;
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
             std::unique_ptr<llvm::Module> module =
                 parseIR(buff.get(), Err, context);
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
-            std::unique_ptr<llvm::Module> module(
-                ParseIR(buff.get(), Err, context));
-#else
-          std::unique_ptr<llvm::Module> module(
-              ParseIR(buff.take(), Err, context));
-#endif
             if (!module) {
               klee_error("Loading file %s failed: %s", fileName.c_str(),
                          Err.getMessage().str().c_str());
@@ -581,13 +481,7 @@ bool klee::loadFile(const std::string &fileName, LLVMContext &context,
   }
   // This might still be an assembly file. Let's try to parse it.
   SMDiagnostic Err;
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
   std::unique_ptr<llvm::Module> module(parseIR(Buffer, Err, context));
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
-  std::unique_ptr<llvm::Module> module(ParseIR(Buffer, Err, context));
-#else
-std::unique_ptr<llvm::Module> module(ParseIR(Buffer.take(), Err, context));
-#endif
   if (!module) {
     klee_error("Loading file %s failed: Unrecognized file type.",
                fileName.c_str());
diff --git a/lib/Module/OptNone.cpp b/lib/Module/OptNone.cpp
index 08837488..285fac5c 100644
--- a/lib/Module/OptNone.cpp
+++ b/lib/Module/OptNone.cpp
@@ -27,7 +27,6 @@ bool OptNonePass::runOnModule(llvm::Module &M) {
   for (auto &F : M) {
     if (!F.hasName() || !F.getName().startswith("klee_"))
       continue;
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
     for (auto *U : F.users()) {
       // skip non-calls and non-invokes
       if (!llvm::isa<llvm::CallInst>(U) && !llvm::isa<llvm::InvokeInst>(U))
@@ -35,13 +34,6 @@ bool OptNonePass::runOnModule(llvm::Module &M) {
       auto *Inst = llvm::cast<llvm::Instruction>(U);
       CallingFunctions.insert(Inst->getParent()->getParent());
     }
-#else
-    for (auto i = F.use_begin(), e = F.use_end(); i != e; ++i) {
-      if (auto Inst = llvm::dyn_cast<llvm::Instruction>(*i)) {
-        CallingFunctions.insert(Inst->getParent()->getParent());
-      }
-    }
-#endif
   }
 
   bool changed = false;
diff --git a/lib/Module/Optimize.cpp b/lib/Module/Optimize.cpp
index 0980c060..44708b11 100644
--- a/lib/Module/Optimize.cpp
+++ b/lib/Module/Optimize.cpp
@@ -22,11 +22,13 @@
 #include "Passes.h"
 #endif
 
+#include "llvm/Analysis/GlobalsModRef.h"
 #include "llvm/Analysis/Passes.h"
 #include "llvm/Analysis/LoopPass.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Verifier.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/PluginLoader.h"
@@ -34,16 +36,6 @@
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/Scalar.h"
 
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
-#include "llvm/IR/Verifier.h"
-#else
-#include "llvm/Analysis/Verifier.h"
-#endif
-
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
-#include "llvm/Analysis/GlobalsModRef.h"
-#endif
-
 #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 9)
 #include "llvm/Transforms/IPO/FunctionAttrs.h"
 #include "llvm/Transforms/Scalar/GVN.h"
@@ -122,16 +114,12 @@ static void AddStandardCompilePasses(legacy::PassManager &PM) {
   addPass(PM, createCFGSimplificationPass());    // Clean up after IPCP & DAE
 
   addPass(PM, createPruneEHPass());              // Remove dead EH info
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
 #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 9)
   addPass(PM, createPostOrderFunctionAttrsLegacyPass());
 #else
   addPass(PM, createPostOrderFunctionAttrsPass());
 #endif
   addPass(PM, createReversePostOrderFunctionAttrsPass()); // Deduce function attrs
-#else
-  addPass(PM, createFunctionAttrsPass());        // Deduce function attrs
-#endif
 
   if (!DisableInline)
     addPass(PM, createFunctionInliningPass());   // Inline small functions
@@ -190,19 +178,6 @@ void Optimize(Module *M, llvm::ArrayRef<const char *> preservedFunctions) {
   addPass(Passes, new klee::WorkaroundLLVMPR39177Pass());
 #endif
 
-  // Add an appropriate DataLayout instance for this module...
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7)
-  // LLVM 3.7+ doesn't have DataLayoutPass anymore.
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
-  DataLayoutPass *dlpass = new DataLayoutPass();
-  dlpass->doInitialization(*M);
-  addPass(Passes, dlpass);
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
-  addPass(Passes, new DataLayoutPass(M));
-#else
-  addPass(Passes, new DataLayout(M));
-#endif
-
   // DWD - Run the opt standard pass list as well.
   AddStandardCompilePasses(Passes);
 
@@ -269,7 +244,6 @@ void Optimize(Module *M, llvm::ArrayRef<const char *> preservedFunctions) {
 #endif
 
   // Run a few AA driven optimizations here and now, to cleanup the code.
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8)
 #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 9)
   addPass(Passes, createPostOrderFunctionAttrsLegacyPass());
 #else
@@ -277,10 +251,6 @@ void Optimize(Module *M, llvm::ArrayRef<const char *> preservedFunctions) {
 #endif
   addPass(Passes, createReversePostOrderFunctionAttrsPass()); // Add nocapture
   addPass(Passes, createGlobalsAAWrapperPass()); // IP alias analysis
-#else
-  addPass(Passes, createFunctionAttrsPass());        // Add nocapture
-  addPass(Passes, createGlobalsModRefPass());        // IP alias analysis
-#endif
 
   addPass(Passes, createLICMPass());                 // Hoist loop invariants
   addPass(Passes, createGVNPass());                  // Remove redundancies
diff --git a/lib/Module/RaiseAsm.cpp b/lib/Module/RaiseAsm.cpp
index eef22fb8..5d86bfd1 100644
--- a/lib/Module/RaiseAsm.cpp
+++ b/lib/Module/RaiseAsm.cpp
@@ -22,12 +22,10 @@
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/Target/TargetMachine.h"
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+#else
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetSubtargetInfo.h"
-#else
-#include "llvm/Target/TargetLowering.h"
 #endif
 
 using namespace llvm;
@@ -95,16 +93,9 @@ bool RaiseAsmPass::runOnModule(Module &M) {
     TM = NativeTarget->createTargetMachine(HostTriple, "", "", TargetOptions(),
         None);
     TLI = TM->getSubtargetImpl(*(M.begin()))->getTargetLowering();
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 7)
+#else
     TM = NativeTarget->createTargetMachine(HostTriple, "", "", TargetOptions());
     TLI = TM->getSubtargetImpl(*(M.begin()))->getTargetLowering();
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
-    TM = NativeTarget->createTargetMachine(HostTriple, "", "", TargetOptions());
-    TLI = TM->getSubtargetImpl()->getTargetLowering();
-#else
-    TM = NativeTarget->createTargetMachine(HostTriple, "", "",
-                                                          TargetOptions());
-    TLI = TM->getTargetLowering();
 #endif
 
     triple = llvm::Triple(HostTriple);
diff --git a/lib/Support/CompressionStream.cpp b/lib/Support/CompressionStream.cpp
index ff2d290f..4f818897 100644
--- a/lib/Support/CompressionStream.cpp
+++ b/lib/Support/CompressionStream.cpp
@@ -10,15 +10,13 @@
 #include "klee/Config/Version.h"
 #ifdef HAVE_ZLIB_H
 #include "klee/Internal/Support/CompressionStream.h"
-#if (LLVM_VERSION_CODE == LLVM_VERSION(3, 4))
-#include "llvm/Support/system_error.h"
-#else
+
 #include "llvm/Support/FileSystem.h"
+
 #include <fcntl.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#endif
 #include <unistd.h>
 
 namespace klee {
@@ -31,12 +29,9 @@ compressed_fd_ostream::compressed_fd_ostream(const std::string &Filename,
 #if LLVM_VERSION_CODE >= LLVM_VERSION(7, 0)
   std::error_code EC =
       llvm::sys::fs::openFileForWrite(Filename, FD);
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+#else
   std::error_code EC =
       llvm::sys::fs::openFileForWrite(Filename, FD, llvm::sys::fs::F_None);
-#else
-  llvm::error_code EC =
-      llvm::sys::fs::openFileForWrite(Filename, FD, llvm::sys::fs::F_Binary);
 #endif
   if (EC) {
     ErrorInfo = EC.message();
diff --git a/lib/Support/FileHandling.cpp b/lib/Support/FileHandling.cpp
index 068ce44b..af532a0e 100644
--- a/lib/Support/FileHandling.cpp
+++ b/lib/Support/FileHandling.cpp
@@ -12,9 +12,7 @@
 #include "klee/Config/config.h"
 #include "klee/Internal/Support/ErrorHandling.h"
 
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
 #include "llvm/Support/FileSystem.h"
-#endif
 
 #ifdef HAVE_ZLIB_H
 #include "klee/Internal/Support/CompressionStream.h"
@@ -26,16 +24,10 @@ std::unique_ptr<llvm::raw_fd_ostream>
 klee_open_output_file(const std::string &path, std::string &error) {
   error = "";
   std::unique_ptr<llvm::raw_fd_ostream> f;
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
   std::error_code ec;
   f = std::unique_ptr<llvm::raw_fd_ostream>(new llvm::raw_fd_ostream(path.c_str(), ec, llvm::sys::fs::F_None)); // FIXME C++14
   if (ec)
     error = ec.message();
-#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
-  f = std::unique_ptr<llvm::raw_fd_ostream>(new llvm::raw_fd_ostream(path.c_str(), error, llvm::sys::fs::F_None)); // FIXME C++14
-#else
-  f = std::unique_ptr<llvm::raw_fd_ostream>(new llvm::raw_fd_ostream(path.c_str(), error, llvm::sys::fs::F_Binary)); // FIXME C++14
-#endif
   if (!error.empty()) {
     f.reset(nullptr);
   }
diff --git a/scripts/build/p-clang-linux-ubuntu-16.04.inc b/scripts/build/p-clang-linux-ubuntu-16.04.inc
index 5e140f5d..0fb30e52 100644
--- a/scripts/build/p-clang-linux-ubuntu-16.04.inc
+++ b/scripts/build/p-clang-linux-ubuntu-16.04.inc
@@ -2,10 +2,6 @@ install_binary_artifact_clang() {
   local LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
   local LLVM_VERSION_MINOR="${LLVM_VERSION/*./}"
 
-  # Check versions: no support for LLVM < 3.5
-  [[ "${LLVM_VERSION_MAJOR}" -eq 3 ]] && [[ "${LLVM_VERSION_MINOR}" -lt 5 ]] && return 1
-
-
   local version=""
   [[ "${LLVM_VERSION_MAJOR}" -le 6 ]] && version="-${LLVM_VERSION}"
   [[ "${LLVM_VERSION_MAJOR}" -ge 7 ]] && version="-${LLVM_VERSION_MAJOR}"
diff --git a/scripts/build/p-llvm-linux-ubuntu-16.04.inc b/scripts/build/p-llvm-linux-ubuntu-16.04.inc
index 6bfc3105..bab32d45 100644
--- a/scripts/build/p-llvm-linux-ubuntu-16.04.inc
+++ b/scripts/build/p-llvm-linux-ubuntu-16.04.inc
@@ -44,11 +44,6 @@ install_binary_artifact_llvm() {
 
   # Enable/Disable optimized does not matter
   
-  # Check versions: no support for LLVM < 3.8
-  if [[ "${LLVM_VERSION_MAJOR}" -eq 3 ]]; then
-    [[ "${LLVM_VERSION_MINOR}" -lt 8 ]] && return 1
-  fi
-  
   # Add certificate
   apt update -y
   dependencies=(
@@ -95,4 +90,4 @@ is_installed_llvm() {
     # Check requested mode with mode of the found item  
     [[ $(to_bool "${REQUIRES_RTTI}") -eq $(to_bool "${rtti}") ]] || return 1
     [[ $(to_bool "${DISABLE_ASSERTIONS}") -ne $(to_bool "${assertion}") ]] || return 1
-}
\ No newline at end of file
+}
diff --git a/scripts/build/p-llvm.inc b/scripts/build/p-llvm.inc
index 4e0740a2..43be3399 100644
--- a/scripts/build/p-llvm.inc
+++ b/scripts/build/p-llvm.inc
@@ -46,12 +46,7 @@ setup_build_variables_llvm() {
     LLVM_BUILD="${LLVM_SRC_BASE}-build${LLVM_SUFFIX}"
     LLVM_INSTALL="${LLVM_SRC_BASE}-install${LLVM_SUFFIX}"
     LLVM_BIN="${LLVM_INSTALL}/bin"
-    if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
-      LLVM_BUILDMODE="$BuildMode"
-      LLVM_BUILD_BIN="${LLVM_BUILD}/${LLVM_BUILDMODE}/bin"
-    else
-      LLVM_BUILD_BIN="${LLVM_BUILD}/bin"
-    fi
+    LLVM_BUILD_BIN="${LLVM_BUILD}/bin"
 
     LLVM_CONFIG="${LLVM_BIN}/llvm-config"
     BITCODE_CC="${LLVM_BIN}/clang"
@@ -104,13 +99,10 @@ download_llvm() {
   svn co "http://llvm.org/svn/llvm-project/cfe/branches/release_${LLVM_VERSION_SHORT}" clang
   cd "${LLVM_SRC_BASE}/projects" || (echo "Directory does not exist"; exit 1)
   svn co "http://llvm.org/svn/llvm-project/compiler-rt/branches/release_${LLVM_VERSION_SHORT}" compiler-rt
-
-  if [[ ${LLVM_VERSION_SHORT} -gt 37 ]]; then
-    cd "${LLVM_SRC_BASE}/projects" || (echo "Directory does not exist"; exit 1)
-    svn co "http://llvm.org/svn/llvm-project/libcxx/branches/release_${LLVM_VERSION_SHORT}" libcxx
-    cd "${LLVM_SRC_BASE}/projects" || (echo "Directory does not exist"; exit 1)
-    svn co "http://llvm.org/svn/llvm-project/libcxxabi/branches/release_${LLVM_VERSION_SHORT}" libcxxabi
-  fi
+  cd "${LLVM_SRC_BASE}/projects" || (echo "Directory does not exist"; exit 1)
+  svn co "http://llvm.org/svn/llvm-project/libcxx/branches/release_${LLVM_VERSION_SHORT}" libcxx
+  cd "${LLVM_SRC_BASE}/projects" || (echo "Directory does not exist"; exit 1)
+  svn co "http://llvm.org/svn/llvm-project/libcxxabi/branches/release_${LLVM_VERSION_SHORT}" libcxxabi
 
   # Apply existing patches if needed
   if [ -f "${DIR}/patches/llvm${LLVM_VERSION_SHORT}.patch" ]; then
@@ -129,10 +121,6 @@ build_llvm() {
 
     # For memory sanitizer, we have a multi-stage build process
     if [[ "${SANITIZER_BUILD}" == "memory" ]]; then
-       if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
-         echo "Memory sanitizer builds for <= LLVM 3.7 are not supported"
-         exit 1
-       fi
        # Build uninstrumented compiler
        mkdir -p "${SANITIZER_LLVM_UNINSTRUMENTED}"
        cd "${SANITIZER_LLVM_UNINSTRUMENTED}"
@@ -181,114 +169,66 @@ build_llvm() {
 
 
   # Configure LLVM
-  if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
-    local CONFIG=("--enable-jit" "--prefix=${LLVM_INSTALL}")
-    if [[ "${enable_optimized}" == "1" ]]; then
-      CONFIG+=(--enable-optimized)
-    else
-      CONFIG+=(--disable-optimized)
-    fi
-
-    if [[ "${disable_assertions}" == "1" ]]; then
-      CONFIG+=(--disable-assertions)
-    else
-      CONFIG+=(--enable-assertions)
-    fi
-
-    if [[ "${enable_debug}" == "1" ]]; then
-      CONFIG+=(--enable-debug-runtime --enable-debug-symbols)
-    else
-      CONFIG+=(--disable-debug-symbols)
-    fi
-
-    local variables=()
-    if [[ -n "${CC:-}" ]]; then
-        variables+=("CC=${CC}")
-    fi
-
-    if [[ -n "${CXX:-}" ]]; then
-        variables+=("CXX=${CXX}")
-    fi
-
-    if [[ -n "${LDFLAGS:-}" ]]; then
-        variables+=("LDFLAGS=${LLVM_LDFLAGS}")
-    fi
-
-    if [[ -n "${LLVM_CFLAGS:-}" ]]; then
-        variables+=("CFLAGS=${LLVM_CFLAGS}")
-    fi
-
-    if [[ -n "${LLVM_CXXFLAGS:-}" ]]; then
-        variables+=("CXXFLAGS=${LLVM_CXXFLAGS}")
-    fi
-
-    if [[ -n "${LLVM_LDFLAGS:-}" ]]; then
-        variables+=("LDFLAGS=${LLVM_LDFLAGS}")
-    fi
-    ${variables[@]+"${variables[@]}"} "${LLVM_SRC_BASE}/configure" "${CONFIG[@]}"
+  CONFIG=(
+     "-DCMAKE_INSTALL_PREFIX=${LLVM_INSTALL}"
+     "-LLVM_BUILD_LLVM_DYLIB=TRUE"
+  )
+  # cmake build
+  if [[ "${enable_optimized}" == "1" && "${enable_debug}" != "1" ]]; then
+    CONFIG+=("-DCMAKE_BUILD_TYPE=Release")
+  fi
+  if [[ "${enable_optimized}" == "1" && "${enable_debug}" == "1" ]]; then
+    CONFIG+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo")
+  fi
+  if [[ "${enable_optimized}" != "1" && "${enable_debug}" == "1" ]]; then
+    CONFIG+=("-DCMAKE_BUILD_TYPE=Debug")
+  fi
 
+  if [[ "${disable_assertions}" == "1" ]]; then
+    CONFIG+=("-DLLVM_ENABLE_ASSERTIONS=Off")
   else
-    CONFIG=(
-        "-DCMAKE_INSTALL_PREFIX=${LLVM_INSTALL}"
-        "-LLVM_BUILD_LLVM_DYLIB=TRUE"
-    )
-    # cmake build
-    if [[ "${enable_optimized}" == "1" && "${enable_debug}" != "1" ]]; then
-      CONFIG+=("-DCMAKE_BUILD_TYPE=Release")
-    fi
-    if [[ "${enable_optimized}" == "1" && "${enable_debug}" == "1" ]]; then
-      CONFIG+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo")
-    fi
-    if [[ "${enable_optimized}" != "1" && "${enable_debug}" == "1" ]]; then
-      CONFIG+=("-DCMAKE_BUILD_TYPE=Debug")
-    fi
-
-    if [[ "${disable_assertions}" == "1" ]]; then
-      CONFIG+=("-DLLVM_ENABLE_ASSERTIONS=Off")
-    else
-      CONFIG+=("-DLLVM_ENABLE_ASSERTIONS=On")
-    fi
+    CONFIG+=("-DLLVM_ENABLE_ASSERTIONS=On")
+  fi
 
-    if [[ -n "${LLVM_CFLAGS:-}" ]]; then
-      CONFIG+=("-DCMAKE_C_FLAGS=\"$LLVM_CFLAGS\"")
-    fi
+  if [[ -n "${LLVM_CFLAGS:-}" ]]; then
+    CONFIG+=("-DCMAKE_C_FLAGS=\"$LLVM_CFLAGS\"")
+  fi
 
-    if [[ -n "${LLVM_CXXFLAGS:-}" ]]; then
-      CONFIG+=("-DCMAKE_CXX_FLAGS=\"$LLVM_CXXFLAGS\"")
-    fi
+  if [[ -n "${LLVM_CXXFLAGS:-}" ]]; then
+    CONFIG+=("-DCMAKE_CXX_FLAGS=\"$LLVM_CXXFLAGS\"")
+  fi
 
-    if [[ "${requires_rtti}" -eq 1 ]]; then
-      CONFIG+=("-DLLVM_ENABLE_RTTI=TRUE")
-    fi
+  if [[ "${requires_rtti}" -eq 1 ]]; then
+    CONFIG+=("-DLLVM_ENABLE_RTTI=TRUE")
+  fi
 
-    # Remove unneeded targets
-    CONFIG+=(
-       -DLLVM_INCLUDE_EXAMPLES=OFF
-#       -DLLVM_INCLUDE_TESTS=OFF
-#       -DCLANG_INCLUDE_TESTS=OFF
-       -DLLVM_INCLUDE_BENCHMARKS=OFF
-       -DBUILD_SHARED_LIBS=ON
-    )
+  # Remove unneeded targets
+  CONFIG+=(
+     -DLLVM_INCLUDE_EXAMPLES=OFF
+#     -DLLVM_INCLUDE_TESTS=OFF
+#     -DCLANG_INCLUDE_TESTS=OFF
+     -DLLVM_INCLUDE_BENCHMARKS=OFF
+     -DBUILD_SHARED_LIBS=ON
+  )
 
-    local variables=("")
+  local variables=("")
 
-    if [[ -n "${CC:-}" ]]; then
-        variables+=("CC=${CC}")
-    fi
+  if [[ -n "${CC:-}" ]]; then
+    variables+=("CC=${CC}")
+  fi
 
-    if [[ -n "${CXX:-}" ]]; then
-        variables+=("CXX=${CXX}")
-    fi
+  if [[ -n "${CXX:-}" ]]; then
+    variables+=("CXX=${CXX}")
+  fi
 
-    if [[ -n "${LDFLAGS:-}" ]]; then
-        variables+=("LDFLAGS=${LLVM_LDFLAGS}")
-    fi
+  if [[ -n "${LDFLAGS:-}" ]]; then
+    variables+=("LDFLAGS=${LLVM_LDFLAGS}")
+  fi
 
-    if [[ -n "${variables[*]}" ]]; then
-      "${variables[*]}" cmake "${CONFIG[@]}" "${LLVM_SRC_BASE}"
-    else
-      cmake "${CONFIG[@]}" "${LLVM_SRC_BASE}"
-    fi
+  if [[ -n "${variables[*]}" ]]; then
+    "${variables[*]}" cmake "${CONFIG[@]}" "${LLVM_SRC_BASE}"
+  else
+    cmake "${CONFIG[@]}" "${LLVM_SRC_BASE}"
   fi
 
   # Linking LLVM can require a lot of memory.
@@ -363,4 +303,4 @@ get_build_artifacts_llvm() {
     [[ "${sanitizer}" == "memory" ]] && echo "${SANITIZER_LLVM_UNINSTRUMENTED}"
     [[ "${sanitizer}" == "memory" ]] && echo "${SANITIZER_LLVM_LIBCXX}"
   )
-}
\ No newline at end of file
+}
diff --git a/scripts/build/patches/llvm35.patch b/scripts/build/patches/llvm35.patch
deleted file mode 100644
index 47744b91..00000000
--- a/scripts/build/patches/llvm35.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-*** include/llvm/ADT/IntrusiveRefCntPtr.h       2014-07-06 00:20:59.000000000 +0200
---- include/llvm/ADT/IntrusiveRefCntPtr_new.h   2016-06-21 10:04:15.610143165 +0200
-***************
-*** 154,159 ****
---- 154,162 ----
-      }
-
-      template <class X>
-+     friend class IntrusiveRefCntPtr;
-+
-+     template <class X>
-      IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.get()) {
-        S.Obj = 0;
-      }
diff --git a/scripts/build/patches/llvm36.patch b/scripts/build/patches/llvm36.patch
deleted file mode 100644
index b5b84b09..00000000
--- a/scripts/build/patches/llvm36.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-diff --git include/llvm/IR/ValueMap.h include/llvm/IR/ValueMap.h
-index f2ea405f..a1ab2a50 100644
---- include/llvm/IR/ValueMap.h
-+++ include/llvm/IR/ValueMap.h
-@@ -104 +104 @@ public:
--  bool hasMD() const { return MDMap; }
-+  bool hasMD() const { return bool(MDMap); }
-diff --git projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
-index 0e776b90..5088f2d0 100644
---- projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
-+++ projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
-@@ -588,2 +588 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) {
--uptr internal_sigaltstack(const struct sigaltstack *ss,
--                         struct sigaltstack *oss) {
-+uptr internal_sigaltstack(const void *ss, void *oss) {
-diff --git projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.h projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
-index 3013c25f..d7d4db89 100644
---- projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
-+++ projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
-@@ -23 +22,0 @@ struct link_map;  // Opaque type returned by dlopen().
--struct sigaltstack;
-@@ -32,2 +31 @@ uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count);
--uptr internal_sigaltstack(const struct sigaltstack* ss,
--                          struct sigaltstack* oss);
-+uptr internal_sigaltstack(const void* ss, void* oss);
-diff --git projects/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc projects/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
-index d20b5248..33894054 100644
---- projects/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
-+++ projects/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
-@@ -239 +239 @@ static int TracerThread(void* argument) {
--  struct sigaltstack handler_stack;
-+  stack_t handler_stack;
-diff --git projects/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc projects/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc
-index 4dcfa558..8ce75be1 100644
---- projects/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc
-+++ projects/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc
-@@ -358 +358 @@ int ExtractResolvFDs(void *state, int *fds, int nfd) {
--  __res_state *statp = (__res_state*)state;
-+  struct __res_state *statp = (struct __res_state*)state;
diff --git a/scripts/build/v-libcxx.inc b/scripts/build/v-libcxx.inc
index 669bb536..147b4db4 100644
--- a/scripts/build/v-libcxx.inc
+++ b/scripts/build/v-libcxx.inc
@@ -3,15 +3,9 @@ required_variables_libcxx=(
 )
 
 required_variables_check_libcxx() {
-  local LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
-  local LLVM_VERSION_MINOR="${LLVM_VERSION/*./}"
-  # Check versions: no support for LLVM < 3.8
-#  if [[ "${LLVM_VERSION_MAJOR}" -eq 3 ]]; then
-#    [[ "${LLVM_VERSION_MINOR}" -lt 8 ]] && { echo "Version <= 3.7 not supported"; return 1; }
-#  fi
   return 0
 }
 
 artifact_dependency_libcxx(){
   echo "clang"
-}
\ No newline at end of file
+}
diff --git a/scripts/build/v-uclibc.inc b/scripts/build/v-uclibc.inc
index e7a2f720..7cdedfcd 100644
--- a/scripts/build/v-uclibc.inc
+++ b/scripts/build/v-uclibc.inc
@@ -6,12 +6,5 @@ required_variables_uclibc=(
 artifact_dependency_uclibc(){
   # Add llvm if needed; otherwise only use clang package
 # TODO this is quite distribution specific; should be handled in a more general case
-  local LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
-  local LLVM_VERSION_MINOR="${LLVM_VERSION/*./}"
-  # Check versions: no support for LLVM < 3.5
-  if [[ "${LLVM_VERSION_MAJOR}" -eq 3 ]]; then
-    [[ "${LLVM_VERSION_MINOR}" -lt 5 ]] && echo "llvm"
-  fi
-
   echo "clang"
-}
\ No newline at end of file
+}
diff --git a/test/lit.cfg b/test/lit.cfg
index 05dfd7f1..f6c7cd68 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -160,7 +160,7 @@ config.substitutions.append(
 
 # Add feature for the LLVM version in use, so it can be tested in REQUIRES and
 # XFAIL checks. We also add "not-XXX" variants, for the same reason.
-known_llvm_versions = set(["3.4", "3.5", "3.6", "3.7", "3.8", "3.9"])
+known_llvm_versions = set(["3.8", "3.9", "4.0", "5.0", "6.0", "7.0", "8.0"])
 current_llvm_version = "%s.%s" % (config.llvm_version_major,
                                   config.llvm_version_minor)
 config.available_features.add("llvm-" + current_llvm_version)
diff --git a/tools/kleaver/main.cpp b/tools/kleaver/main.cpp
index f5b5e13a..9033a2b4 100644
--- a/tools/kleaver/main.cpp
+++ b/tools/kleaver/main.cpp
@@ -37,11 +37,6 @@
 
 #include "llvm/Support/Signals.h"
 
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Support/system_error.h"
-#endif
-
 using namespace llvm;
 using namespace klee;
 using namespace klee::expr;
@@ -409,14 +404,6 @@ int main(int argc, char **argv) {
 
   std::string ErrorStr;
   
-#if LLVM_VERSION_CODE < LLVM_VERSION(3,5)
-  OwningPtr<MemoryBuffer> MB;
-  error_code ec=MemoryBuffer::getFileOrSTDIN(InputFile.c_str(), MB);
-  if (ec) {
-    llvm::errs() << argv[0] << ": error: " << ec.message() << "\n";
-    return 1;
-  }
-#else
   auto MBResult = MemoryBuffer::getFileOrSTDIN(InputFile.c_str());
   if (!MBResult) {
     llvm::errs() << argv[0] << ": error: " << MBResult.getError().message()
@@ -424,7 +411,6 @@ int main(int argc, char **argv) {
     return 1;
   }
   std::unique_ptr<MemoryBuffer> &MB = *MBResult;
-#endif
   
   ExprBuilder *Builder = 0;
   switch (BuilderKind) {
diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp
index ee115de3..be90548e 100644
--- a/tools/klee/main.cpp
+++ b/tools/klee/main.cpp
@@ -43,10 +43,6 @@
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/Signals.h"
 
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-#include "llvm/Support/system_error.h"
-#endif
-
 #if LLVM_VERSION_CODE >= LLVM_VERSION(4, 0)
 #include <llvm/Bitcode/BitcodeReader.h>
 #else
@@ -358,12 +354,7 @@ KleeHandler::KleeHandler(int argc, char **argv)
   SmallString<128> directory(dir_given ? OutputDir : InputFile);
 
   if (!dir_given) sys::path::remove_filename(directory);
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-  error_code ec;
-  if ((ec = sys::fs::make_absolute(directory)) != errc::success) {
-#else
   if (auto ec = sys::fs::make_absolute(directory)) {
-#endif
     klee_error("unable to determine absolute path: %s", ec.message().c_str());
   }
 
@@ -381,10 +372,7 @@ KleeHandler::KleeHandler(int argc, char **argv)
       llvm::sys::path::append(d, "klee-out-");
       raw_svector_ostream ds(d);
       ds << i;
-// SmallString is always up-to-date, no need to flush. See Support/raw_ostream.h
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 8)
-      ds.flush();
-#endif
+      // SmallString is always up-to-date, no need to flush. See Support/raw_ostream.h
 
       // create directory and try to link klee-last
       if (mkdir(d.c_str(), 0775) == 0) {
@@ -630,11 +618,7 @@ void KleeHandler::loadPathFile(std::string name,
 
 void KleeHandler::getKTestFilesInDir(std::string directoryPath,
                                      std::vector<std::string> &results) {
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
-  error_code ec;
-#else
   std::error_code ec;
-#endif
   llvm::sys::fs::directory_iterator i(directoryPath, ec), e;
   for (; i != e && !ec; i.increment(ec)) {
     auto f = i->path();