Re-land "[MergeICmps] Disable mergeicmps if the target does not want to handle memcmp expansion.""

llvm-svn: 314980
diff --git a/llvm/lib/Transforms/Scalar/MergeICmps.cpp b/llvm/lib/Transforms/Scalar/MergeICmps.cpp
index a56cffc..a8e109d 100644
--- a/llvm/lib/Transforms/Scalar/MergeICmps.cpp
+++ b/llvm/lib/Transforms/Scalar/MergeICmps.cpp
@@ -28,6 +28,8 @@
 #include <vector>
 #include "llvm/ADT/APSInt.h"
 #include "llvm/Analysis/Loads.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/IntrinsicInst.h"
@@ -41,8 +43,6 @@
 
 #define DEBUG_TYPE "mergeicmps"
 
-#define MERGEICMPS_DOT_ON
-
 // A BCE atom.
 struct BCEAtom {
   BCEAtom() : GEP(nullptr), LoadI(nullptr), Offset() {}
@@ -430,10 +430,16 @@
 
     IRBuilder<> Builder(BB);
     const auto &DL = Phi.getModule()->getDataLayout();
-    Value *const MemCmpCall =
-        emitMemCmp(FirstComparison.Lhs().GEP, FirstComparison.Rhs().GEP,
-                   ConstantInt::get(DL.getIntPtrType(Context), TotalSize),
-                   Builder, DL, TLI);
+    GetElementPtrInst *LhsArg = FirstComparison.Lhs().GEP;
+    GetElementPtrInst *RhsArg = FirstComparison.Rhs().GEP;
+    // If the values are named, use the smaller name as first argument to
+    // memcmp() so that results are reproducible.
+    if (LhsArg->hasName() && RhsArg->hasName() &&
+        LhsArg->getName() > RhsArg->getName())
+      std::swap(LhsArg, RhsArg);
+    Value *const MemCmpCall = emitMemCmp(
+        LhsArg, RhsArg, ConstantInt::get(DL.getIntPtrType(Context), TotalSize),
+        Builder, DL, TLI);
     Value *const MemCmpIsZero = Builder.CreateICmpEQ(
         MemCmpCall, ConstantInt::get(Type::getInt32Ty(Context), 0));
 
@@ -589,22 +595,30 @@
   bool runOnFunction(Function &F) override {
     if (skipFunction(F)) return false;
     const auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
-    auto PA = runImpl(F, &TLI);
+    const auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+    auto PA = runImpl(F, &TLI, &TTI);
     return !PA.areAllPreserved();
   }
 
  private:
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<TargetLibraryInfoWrapperPass>();
+    AU.addRequired<TargetTransformInfoWrapperPass>();
   }
 
-  PreservedAnalyses runImpl(Function &F, const TargetLibraryInfo *TLI);
+  PreservedAnalyses runImpl(Function &F, const TargetLibraryInfo *TLI,
+                            const TargetTransformInfo *TTI);
 };
 
-PreservedAnalyses MergeICmps::runImpl(Function &F,
-                                      const TargetLibraryInfo *TLI) {
+PreservedAnalyses MergeICmps::runImpl(Function &F, const TargetLibraryInfo *TLI,
+                                      const TargetTransformInfo *TTI) {
   DEBUG(dbgs() << "MergeICmpsPass: " << F.getName() << "\n");
 
+  // We only try merging comparisons if the target wants to expand memcmp later.
+  // The rationale is to avoid turning small chains into memcmp calls.
+  unsigned MaxLoadSize;
+  if (!TTI->enableMemCmpExpansion(MaxLoadSize)) return PreservedAnalyses::all();
+
   bool MadeChange = false;
 
   for (auto BBIt = ++F.begin(); BBIt != F.end(); ++BBIt) {
@@ -623,6 +637,7 @@
 INITIALIZE_PASS_BEGIN(MergeICmps, "mergeicmps",
                       "Merge contiguous icmps into a memcmp", false, false)
 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
 INITIALIZE_PASS_END(MergeICmps, "mergeicmps",
                     "Merge contiguous icmps into a memcmp", false, false)