Index: include/CommonMemorySafetyPasses.h
===================================================================
--- include/CommonMemorySafetyPasses.h	(revision 162127)
+++ include/CommonMemorySafetyPasses.h	(working copy)
@@ -41,6 +41,10 @@
 FunctionPass *createOptimizeIdenticalLSChecksPass();
 void initializeOptimizeIdenticalLSChecksPass(PassRegistry&);
 
+// Remove implied fast load/store checks where possible.
+FunctionPass *createOptimizeImpliedFastLSChecksPass();
+void initializeOptimizeImpliedFastLSChecksPass(PassRegistry&);
+
 }
 
 #endif
Index: lib/CommonMemorySafety/OptimizeImpliedFastLSChecks.cpp
===================================================================
--- lib/CommonMemorySafety/OptimizeImpliedFastLSChecks.cpp	(revision 0)
+++ lib/CommonMemorySafety/OptimizeImpliedFastLSChecks.cpp	(working copy)
@@ -0,0 +1,149 @@
+//===- OptimizeImpliedFastLSChecks.cpp - Remove implied fast l/s checks ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass removes fast load/store checks that are implied by other
+// fast load/store checks. It works by traversing a dominator tree to find
+// out which checks must always happen before other checks.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "optimize-implied-fast-ls-checks"
+
+#include "CommonMemorySafetyPasses.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/Analysis/MSCInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Instructions.h"
+#include "llvm/Pass.h"
+#include "llvm/Module.h"
+#include "llvm/Transforms/Instrumentation.h"
+
+using namespace llvm;
+
+STATISTIC(FastMemoryChecksRemoved, "Fast load/store checks removed");
+
+namespace {
+  struct AccessData {
+    Value *AccessSize, *ObjSize;
+    const SCEV *Offset;
+
+    AccessData(Value *AccessSize, Value *ObjSize, const SCEV *Offset):
+        AccessSize(AccessSize), ObjSize(ObjSize), Offset(Offset) { }
+
+    bool operator<(const AccessData &Other) const {
+      return memcmp(this, &Other, sizeof(AccessData)) < 0;
+    }
+
+    bool operator==(const AccessData &Other) const {
+      return !memcmp(this, &Other, sizeof(AccessData));
+    }
+  };
+
+  class OptimizeImpliedFastLSChecks : public FunctionPass {
+    MSCInfo *MSCI;
+    ScalarEvolution *SE;
+
+    SmallSet <AccessData, 16> PreviousChecks;
+    SmallVector <CallInst*, 16> ToRemove;
+
+    void exploreNode(DomTreeNode* Node);
+
+  public:
+    static char ID;
+    OptimizeImpliedFastLSChecks(): FunctionPass(ID) { }
+
+    virtual bool runOnFunction(Function &F);
+
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.addRequired<DominatorTree>();
+      AU.addPreserved<DominatorTree>();
+      AU.addRequired<MSCInfo>();
+      AU.addRequired<ScalarEvolution>();
+      AU.setPreservesCFG();
+    }
+
+    virtual const char *getPassName() const {
+      return "OptimizeImpliedFastLSChecks";
+    }
+  };
+} // end anon namespace
+
+char OptimizeImpliedFastLSChecks::ID = 0;
+
+INITIALIZE_PASS(OptimizeImpliedFastLSChecks, "optimize-implied-fast-ls-checks",
+                "Remove implied fast load/store checks where possible.", false,
+                false)
+
+FunctionPass *llvm::createOptimizeImpliedFastLSChecksPass() {
+  return new OptimizeImpliedFastLSChecks();
+}
+
+bool OptimizeImpliedFastLSChecks::runOnFunction(Function &F) {
+  DominatorTree *DT = &getAnalysis<DominatorTree>();
+  MSCI = &getAnalysis<MSCInfo>();
+  SE = &getAnalysis<ScalarEvolution>();
+
+  exploreNode(DT->getRootNode());
+
+  for (size_t i = 0, N = ToRemove.size(); i != N; ++i) {
+    ToRemove[i]->eraseFromParent();
+    ++FastMemoryChecksRemoved;
+  }
+
+  bool modified = !ToRemove.empty();
+  PreviousChecks.clear();
+  ToRemove.clear();
+  return modified;
+}
+
+void OptimizeImpliedFastLSChecks::exploreNode(DomTreeNode* Node) {
+  SmallVector <AccessData, 4> LocalChecks;
+
+  // Iterate over all fast load/store checks.
+  // Remove the ones that are implied by dominating checks.
+  // Add the rest to the set of previous checks.
+  BasicBlock *BB = Node->getBlock();
+  for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
+    CallInst *CI = dyn_cast<CallInst>(I);
+    if (!CI)
+      continue;
+
+    CheckInfoType *Info = MSCI->getCheckInfo(CI->getCalledFunction());
+    if (!Info || !Info->isFastMemoryCheck())
+      continue;
+
+    Value *AccessPtr = CI->getArgOperand(Info->PtrArgNo);
+    Value *AccessSize = CI->getArgOperand(Info->SizeArgNo);
+    Value *ObjPtr = CI->getArgOperand(Info->ObjArgNo);
+    Value *ObjSize = CI->getArgOperand(Info->ObjSizeArgNo);
+    const SCEV *Offset = SE->getMinusSCEV(SE->getSCEV(AccessPtr),
+                                          SE->getSCEV(ObjPtr));
+
+    AccessData Access(AccessSize, ObjSize, Offset);
+    if (PreviousChecks.count(Access)) {
+      ToRemove.push_back(CI);
+    } else {
+      PreviousChecks.insert(Access);
+      LocalChecks.push_back(Access);
+    }
+  }
+
+  // Recursively call this function on basic blocks that are directly dominated.
+  const std::vector <DomTreeNode*> &Children = Node->getChildren();
+  for (size_t i = 0, N = Children.size(); i != N; ++i)
+    exploreNode(Children[i]);
+
+  // Restore the previous checks' set to its old state.
+  for (size_t i = 0, N = LocalChecks.size(); i != N; ++i)
+    PreviousChecks.erase(LocalChecks[i]);
+}
Index: tools/clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- tools/clang/lib/CodeGen/BackendUtil.cpp	(revision 162127)
+++ tools/clang/lib/CodeGen/BackendUtil.cpp	(working copy)
@@ -260,6 +260,11 @@
     MPM->add (createSAFECodeMSCInfoPass());
     MPM->add (createExactCheckOptPass());
     MPM->add (createOptimizeIdenticalLSChecksPass());
+
+    MPM->add (new DominatorTree());
+    MPM->add (new ScalarEvolution());
+    MPM->add (createOptimizeImpliedFastLSChecksPass());
+
     MPM->add (new OptimizeChecks());
     if (CodeGenOpts.MemSafeTerminate) {
       MPM->add (llvm::createSCTerminatePass ());
Index: tools/LTO/LTOCodeGenerator.cpp
===================================================================
--- tools/LTO/LTOCodeGenerator.cpp	(revision 162127)
+++ tools/LTO/LTOCodeGenerator.cpp	(working copy)
@@ -23,6 +23,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/ScalarEvolution.h"
 #include "llvm/Analysis/Verifier.h"
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -448,6 +449,11 @@
       passes.add(createSAFECodeMSCInfoPass());
       passes.add(createExactCheckOptPass());
       passes.add(createOptimizeIdenticalLSChecksPass());
+
+      passes.add(new DominatorTree());
+      passes.add(new ScalarEvolution());
+      passes.add(createOptimizeImpliedFastLSChecksPass());
+
       if (mergedModule->getFunction("main")) {
         passes.add(new CompleteChecks());
       }
