[llvm] 59d6e81 - Revert "[IPConstProp] Remove and move tests to SCCP."

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 30 05:07:21 PDT 2020


Author: Florian Hahn
Date: 2020-07-30T13:06:54+01:00
New Revision: 59d6e814ce0e7b40b7cc3ab136b9af2ffab9c6f8

URL: https://github.com/llvm/llvm-project/commit/59d6e814ce0e7b40b7cc3ab136b9af2ffab9c6f8
DIFF: https://github.com/llvm/llvm-project/commit/59d6e814ce0e7b40b7cc3ab136b9af2ffab9c6f8.diff

LOG: Revert "[IPConstProp] Remove and move tests to SCCP."

This reverts commit e77624a3be942c7abba48942b3a8da3462070a3f.

Looks like some clang tests manually invoke -ipconstprop via opt.....

Added: 
    llvm/lib/Transforms/IPO/IPConstantPropagation.cpp
    llvm/test/Transforms/IPConstantProp/2008-06-09-WeakProp.ll
    llvm/test/Transforms/IPConstantProp/PR43857.ll
    llvm/test/Transforms/IPConstantProp/arg-count-mismatch.ll
    llvm/test/Transforms/IPConstantProp/arg-type-mismatch.ll
    llvm/test/Transforms/IPConstantProp/comdat-ipo.ll
    llvm/test/Transforms/IPConstantProp/deadarg.ll
    llvm/test/Transforms/IPConstantProp/multiple_callbacks.ll
    llvm/test/Transforms/IPConstantProp/naked-return.ll
    llvm/test/Transforms/IPConstantProp/openmp_parallel_for.ll
    llvm/test/Transforms/IPConstantProp/pthreads.ll
    llvm/test/Transforms/IPConstantProp/recursion.ll
    llvm/test/Transforms/IPConstantProp/return-argument.ll
    llvm/test/Transforms/IPConstantProp/return-constant.ll
    llvm/test/Transforms/IPConstantProp/return-constants.ll
    llvm/test/Transforms/IPConstantProp/thread_local_acs.ll

Modified: 
    llvm/bindings/go/llvm/transforms_ipo.go
    llvm/bindings/ocaml/transforms/ipo/ipo_ocaml.c
    llvm/bindings/ocaml/transforms/ipo/llvm_ipo.mli
    llvm/docs/Passes.rst
    llvm/include/llvm-c/Transforms/IPO.h
    llvm/include/llvm/InitializePasses.h
    llvm/include/llvm/LinkAllPasses.h
    llvm/include/llvm/Transforms/IPO.h
    llvm/lib/Transforms/IPO/CMakeLists.txt
    llvm/lib/Transforms/IPO/IPO.cpp
    llvm/test/Transforms/SCCP/comdat-ipo.ll
    llvm/utils/findoptdiff
    llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn

Removed: 
    llvm/test/Transforms/SCCP/2008-06-09-WeakProp.ll
    llvm/test/Transforms/SCCP/PR43857.ll
    llvm/test/Transforms/SCCP/arg-count-mismatch.ll
    llvm/test/Transforms/SCCP/arg-type-mismatch.ll
    llvm/test/Transforms/SCCP/deadarg.ll
    llvm/test/Transforms/SCCP/multiple_callbacks.ll
    llvm/test/Transforms/SCCP/naked-return.ll
    llvm/test/Transforms/SCCP/openmp_parallel_for.ll
    llvm/test/Transforms/SCCP/pthreads.ll
    llvm/test/Transforms/SCCP/recursion.ll
    llvm/test/Transforms/SCCP/return-argument.ll
    llvm/test/Transforms/SCCP/return-constant.ll
    llvm/test/Transforms/SCCP/return-constants.ll
    llvm/test/Transforms/SCCP/thread_local_acs.ll


################################################################################
diff  --git a/llvm/bindings/go/llvm/transforms_ipo.go b/llvm/bindings/go/llvm/transforms_ipo.go
index 8a158f208bef..1dcb2af8bf24 100644
--- a/llvm/bindings/go/llvm/transforms_ipo.go
+++ b/llvm/bindings/go/llvm/transforms_ipo.go
@@ -32,6 +32,7 @@ func (pm PassManager) AddFunctionAttrsPass()         { C.LLVMAddFunctionAttrsPas
 func (pm PassManager) AddFunctionInliningPass()      { C.LLVMAddFunctionInliningPass(pm.C) }
 func (pm PassManager) AddGlobalDCEPass()             { C.LLVMAddGlobalDCEPass(pm.C) }
 func (pm PassManager) AddGlobalOptimizerPass()       { C.LLVMAddGlobalOptimizerPass(pm.C) }
+func (pm PassManager) AddIPConstantPropagationPass() { C.LLVMAddIPConstantPropagationPass(pm.C) }
 func (pm PassManager) AddPruneEHPass()               { C.LLVMAddPruneEHPass(pm.C) }
 func (pm PassManager) AddIPSCCPPass()                { C.LLVMAddIPSCCPPass(pm.C) }
 func (pm PassManager) AddInternalizePass(allButMain bool) {

diff  --git a/llvm/bindings/ocaml/transforms/ipo/ipo_ocaml.c b/llvm/bindings/ocaml/transforms/ipo/ipo_ocaml.c
index c0e213714ed0..9fcaa10534f6 100644
--- a/llvm/bindings/ocaml/transforms/ipo/ipo_ocaml.c
+++ b/llvm/bindings/ocaml/transforms/ipo/ipo_ocaml.c
@@ -73,6 +73,12 @@ CAMLprim value llvm_add_global_optimizer(LLVMPassManagerRef PM) {
   return Val_unit;
 }
 
+/* [`Module] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_ip_constant_propagation(LLVMPassManagerRef PM) {
+  LLVMAddIPConstantPropagationPass(PM);
+  return Val_unit;
+}
+
 /* [`Module] Llvm.PassManager.t -> unit */
 CAMLprim value llvm_add_prune_eh(LLVMPassManagerRef PM) {
   LLVMAddPruneEHPass(PM);

diff  --git a/llvm/bindings/ocaml/transforms/ipo/llvm_ipo.mli b/llvm/bindings/ocaml/transforms/ipo/llvm_ipo.mli
index a581924c6d54..6507c5d92c2b 100644
--- a/llvm/bindings/ocaml/transforms/ipo/llvm_ipo.mli
+++ b/llvm/bindings/ocaml/transforms/ipo/llvm_ipo.mli
@@ -56,6 +56,11 @@ external add_global_optimizer
   : [ `Module ] Llvm.PassManager.t -> unit
   = "llvm_add_global_optimizer"
 
+(** See the [llvm::createIPConstantPropagationPass] function. *)
+external add_ipc_propagation
+  : [ `Module ] Llvm.PassManager.t -> unit
+  = "llvm_add_ip_constant_propagation"
+
 (** See the [llvm::createPruneEHPass] function. *)
 external add_prune_eh
   : [ `Module ] Llvm.PassManager.t -> unit

diff  --git a/llvm/docs/Passes.rst b/llvm/docs/Passes.rst
index 13317ecc966e..e45adad98c15 100644
--- a/llvm/docs/Passes.rst
+++ b/llvm/docs/Passes.rst
@@ -676,6 +676,15 @@ This pass loops over all of the functions in the input module, looking for a
 main function.  If a main function is found, all other functions and all global
 variables with initializers are marked as internal.
 
+``-ipconstprop``: Interprocedural constant propagation
+------------------------------------------------------
+
+This pass implements an *extremely* simple interprocedural constant propagation
+pass.  It could certainly be improved in many 
diff erent ways, like using a
+worklist.  This pass makes arguments dead, but does not remove them.  The
+existing dead argument elimination pass should be run after this to clean up
+the mess.
+
 ``-ipsccp``: Interprocedural Sparse Conditional Constant Propagation
 --------------------------------------------------------------------
 

diff  --git a/llvm/include/llvm-c/Transforms/IPO.h b/llvm/include/llvm-c/Transforms/IPO.h
index 3f2cadf32366..cde3d2460920 100644
--- a/llvm/include/llvm-c/Transforms/IPO.h
+++ b/llvm/include/llvm-c/Transforms/IPO.h
@@ -57,6 +57,9 @@ void LLVMAddGlobalDCEPass(LLVMPassManagerRef PM);
 /** See llvm::createGlobalOptimizerPass function. */
 void LLVMAddGlobalOptimizerPass(LLVMPassManagerRef PM);
 
+/** See llvm::createIPConstantPropagationPass function. */
+void LLVMAddIPConstantPropagationPass(LLVMPassManagerRef PM);
+
 /** See llvm::createPruneEHPass function. */
 void LLVMAddPruneEHPass(LLVMPassManagerRef PM);
 

diff  --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index d23ecfb98ce9..cce6a4350402 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -179,6 +179,7 @@ void initializeGuardWideningLegacyPassPass(PassRegistry&);
 void initializeHardwareLoopsPass(PassRegistry&);
 void initializeHotColdSplittingLegacyPassPass(PassRegistry&);
 void initializeHWAddressSanitizerLegacyPassPass(PassRegistry &);
+void initializeIPCPPass(PassRegistry&);
 void initializeIPSCCPLegacyPassPass(PassRegistry&);
 void initializeIRCELegacyPassPass(PassRegistry&);
 void initializeIRTranslatorPass(PassRegistry&);

diff  --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h
index 9d7ac2b3f3b9..90e2e24294d4 100644
--- a/llvm/include/llvm/LinkAllPasses.h
+++ b/llvm/include/llvm/LinkAllPasses.h
@@ -116,6 +116,7 @@ namespace {
       (void) llvm::createGlobalsAAWrapperPass();
       (void) llvm::createGuardWideningPass();
       (void) llvm::createLoopGuardWideningPass();
+      (void) llvm::createIPConstantPropagationPass();
       (void) llvm::createIPSCCPPass();
       (void) llvm::createInductiveRangeCheckEliminationPass();
       (void) llvm::createIndVarSimplifyPass();

diff  --git a/llvm/include/llvm/Transforms/IPO.h b/llvm/include/llvm/Transforms/IPO.h
index 7b73eeaf8e45..28e454d3b0fc 100644
--- a/llvm/include/llvm/Transforms/IPO.h
+++ b/llvm/include/llvm/Transforms/IPO.h
@@ -155,6 +155,12 @@ Pass *createArgumentPromotionPass(unsigned maxElements = 3);
 /// createOpenMPOptLegacyPass - OpenMP specific optimizations.
 Pass *createOpenMPOptLegacyPass();
 
+//===----------------------------------------------------------------------===//
+/// createIPConstantPropagationPass - This pass propagates constants from call
+/// sites into the bodies of functions.
+///
+ModulePass *createIPConstantPropagationPass();
+
 //===----------------------------------------------------------------------===//
 /// createIPSCCPPass - This pass propagates constants from call sites into the
 /// bodies of functions, and keeps track of whether basic blocks are executable

diff  --git a/llvm/lib/Transforms/IPO/CMakeLists.txt b/llvm/lib/Transforms/IPO/CMakeLists.txt
index a17ef6337106..3f30c0289e8c 100644
--- a/llvm/lib/Transforms/IPO/CMakeLists.txt
+++ b/llvm/lib/Transforms/IPO/CMakeLists.txt
@@ -18,6 +18,7 @@ add_llvm_component_library(LLVMipo
   GlobalOpt.cpp
   GlobalSplit.cpp
   HotColdSplitting.cpp
+  IPConstantPropagation.cpp
   IPO.cpp
   InferFunctionAttrs.cpp
   InlineSimple.cpp

diff  --git a/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp b/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp
new file mode 100644
index 000000000000..8d05a72d68da
--- /dev/null
+++ b/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp
@@ -0,0 +1,308 @@
+//===-- IPConstantPropagation.cpp - Propagate constants through calls -----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass implements an _extremely_ simple interprocedural constant
+// propagation pass.  It could certainly be improved in many 
diff erent ways,
+// like using a worklist.  This pass makes arguments dead, but does not remove
+// them.  The existing dead argument elimination pass should be run after this
+// to clean up the mess.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/AbstractCallSite.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/IPO.h"
+using namespace llvm;
+
+#define DEBUG_TYPE "ipconstprop"
+
+STATISTIC(NumArgumentsProped, "Number of args turned into constants");
+STATISTIC(NumReturnValProped, "Number of return values turned into constants");
+
+namespace {
+  /// IPCP - The interprocedural constant propagation pass
+  ///
+  struct IPCP : public ModulePass {
+    static char ID; // Pass identification, replacement for typeid
+    IPCP() : ModulePass(ID) {
+      initializeIPCPPass(*PassRegistry::getPassRegistry());
+    }
+
+    bool runOnModule(Module &M) override;
+  };
+}
+
+/// PropagateConstantsIntoArguments - Look at all uses of the specified
+/// function.  If all uses are direct call sites, and all pass a particular
+/// constant in for an argument, propagate that constant in as the argument.
+///
+static bool PropagateConstantsIntoArguments(Function &F) {
+  if (F.arg_empty() || F.use_empty()) return false; // No arguments? Early exit.
+
+  // For each argument, keep track of its constant value and whether it is a
+  // constant or not.  The bool is driven to true when found to be non-constant.
+  SmallVector<PointerIntPair<Constant *, 1, bool>, 16> ArgumentConstants;
+  ArgumentConstants.resize(F.arg_size());
+
+  unsigned NumNonconstant = 0;
+  for (Use &U : F.uses()) {
+    User *UR = U.getUser();
+    // Ignore blockaddress uses.
+    if (isa<BlockAddress>(UR)) continue;
+
+    // If no abstract call site was created we did not understand the use, bail.
+    AbstractCallSite ACS(&U);
+    if (!ACS)
+      return false;
+
+    // Mismatched argument count is undefined behavior. Simply bail out to avoid
+    // handling of such situations below (avoiding asserts/crashes).
+    unsigned NumActualArgs = ACS.getNumArgOperands();
+    if (F.isVarArg() ? ArgumentConstants.size() > NumActualArgs
+                     : ArgumentConstants.size() != NumActualArgs)
+      return false;
+
+    // Check out all of the potentially constant arguments.  Note that we don't
+    // inspect varargs here.
+    Function::arg_iterator Arg = F.arg_begin();
+    for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++Arg) {
+
+      // If this argument is known non-constant, ignore it.
+      if (ArgumentConstants[i].getInt())
+        continue;
+
+      Value *V = ACS.getCallArgOperand(i);
+      Constant *C = dyn_cast_or_null<Constant>(V);
+
+      // Mismatched argument type is undefined behavior. Simply bail out to avoid
+      // handling of such situations below (avoiding asserts/crashes).
+      if (C && Arg->getType() != C->getType())
+        return false;
+
+      // We can only propagate thread independent values through callbacks.
+      // This is 
diff erent to direct/indirect call sites because for them we
+      // know the thread executing the caller and callee is the same. For
+      // callbacks this is not guaranteed, thus a thread dependent value could
+      // be 
diff erent for the caller and callee, making it invalid to propagate.
+      if (C && ACS.isCallbackCall() && C->isThreadDependent()) {
+        // Argument became non-constant. If all arguments are non-constant now,
+        // give up on this function.
+        if (++NumNonconstant == ArgumentConstants.size())
+          return false;
+
+        ArgumentConstants[i].setInt(true);
+        continue;
+      }
+
+      if (C && ArgumentConstants[i].getPointer() == nullptr) {
+        ArgumentConstants[i].setPointer(C); // First constant seen.
+      } else if (C && ArgumentConstants[i].getPointer() == C) {
+        // Still the constant value we think it is.
+      } else if (V == &*Arg) {
+        // Ignore recursive calls passing argument down.
+      } else {
+        // Argument became non-constant.  If all arguments are non-constant now,
+        // give up on this function.
+        if (++NumNonconstant == ArgumentConstants.size())
+          return false;
+        ArgumentConstants[i].setInt(true);
+      }
+    }
+  }
+
+  // If we got to this point, there is a constant argument!
+  assert(NumNonconstant != ArgumentConstants.size());
+  bool MadeChange = false;
+  Function::arg_iterator AI = F.arg_begin();
+  for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) {
+    // Do we have a constant argument?
+    if (ArgumentConstants[i].getInt() || AI->use_empty() ||
+        (AI->hasByValAttr() && !F.onlyReadsMemory()))
+      continue;
+
+    Value *V = ArgumentConstants[i].getPointer();
+    if (!V) V = UndefValue::get(AI->getType());
+    AI->replaceAllUsesWith(V);
+    ++NumArgumentsProped;
+    MadeChange = true;
+  }
+  return MadeChange;
+}
+
+
+// Check to see if this function returns one or more constants. If so, replace
+// all callers that use those return values with the constant value. This will
+// leave in the actual return values and instructions, but deadargelim will
+// clean that up.
+//
+// Additionally if a function always returns one of its arguments directly,
+// callers will be updated to use the value they pass in directly instead of
+// using the return value.
+static bool PropagateConstantReturn(Function &F) {
+  if (F.getReturnType()->isVoidTy())
+    return false; // No return value.
+
+  // We can infer and propagate the return value only when we know that the
+  // definition we'll get at link time is *exactly* the definition we see now.
+  // For more details, see GlobalValue::mayBeDerefined.
+  if (!F.isDefinitionExact())
+    return false;
+
+  // Don't touch naked functions. The may contain asm returning
+  // value we don't see, so we may end up interprocedurally propagating
+  // the return value incorrectly.
+  if (F.hasFnAttribute(Attribute::Naked))
+    return false;
+
+  // Check to see if this function returns a constant.
+  SmallVector<Value *,4> RetVals;
+  StructType *STy = dyn_cast<StructType>(F.getReturnType());
+  if (STy)
+    for (unsigned i = 0, e = STy->getNumElements(); i < e; ++i)
+      RetVals.push_back(UndefValue::get(STy->getElementType(i)));
+  else
+    RetVals.push_back(UndefValue::get(F.getReturnType()));
+
+  unsigned NumNonConstant = 0;
+  for (BasicBlock &BB : F)
+    if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
+      for (unsigned i = 0, e = RetVals.size(); i != e; ++i) {
+        // Already found conflicting return values?
+        Value *RV = RetVals[i];
+        if (!RV)
+          continue;
+
+        // Find the returned value
+        Value *V;
+        if (!STy)
+          V = RI->getOperand(0);
+        else
+          V = FindInsertedValue(RI->getOperand(0), i);
+
+        if (V) {
+          // Ignore undefs, we can change them into anything
+          if (isa<UndefValue>(V))
+            continue;
+
+          // Try to see if all the rets return the same constant or argument.
+          if (isa<Constant>(V) || isa<Argument>(V)) {
+            if (isa<UndefValue>(RV)) {
+              // No value found yet? Try the current one.
+              RetVals[i] = V;
+              continue;
+            }
+            // Returning the same value? Good.
+            if (RV == V)
+              continue;
+          }
+        }
+        // Different or no known return value? Don't propagate this return
+        // value.
+        RetVals[i] = nullptr;
+        // All values non-constant? Stop looking.
+        if (++NumNonConstant == RetVals.size())
+          return false;
+      }
+    }
+
+  // If we got here, the function returns at least one constant value.  Loop
+  // over all users, replacing any uses of the return value with the returned
+  // constant.
+  bool MadeChange = false;
+  for (Use &U : F.uses()) {
+    CallBase *CB = dyn_cast<CallBase>(U.getUser());
+
+    // Not a call instruction or a call instruction that's not calling F
+    // directly?
+    if (!CB || !CB->isCallee(&U))
+      continue;
+
+    // Call result not used?
+    if (CB->use_empty())
+      continue;
+
+    MadeChange = true;
+
+    if (!STy) {
+      Value* New = RetVals[0];
+      if (Argument *A = dyn_cast<Argument>(New))
+        // Was an argument returned? Then find the corresponding argument in
+        // the call instruction and use that.
+        New = CB->getArgOperand(A->getArgNo());
+      CB->replaceAllUsesWith(New);
+      continue;
+    }
+
+    for (auto I = CB->user_begin(), E = CB->user_end(); I != E;) {
+      Instruction *Ins = cast<Instruction>(*I);
+
+      // Increment now, so we can remove the use
+      ++I;
+
+      // Find the index of the retval to replace with
+      int index = -1;
+      if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(Ins))
+        if (EV->getNumIndices() == 1)
+          index = *EV->idx_begin();
+
+      // If this use uses a specific return value, and we have a replacement,
+      // replace it.
+      if (index != -1) {
+        Value *New = RetVals[index];
+        if (New) {
+          if (Argument *A = dyn_cast<Argument>(New))
+            // Was an argument returned? Then find the corresponding argument in
+            // the call instruction and use that.
+            New = CB->getArgOperand(A->getArgNo());
+          Ins->replaceAllUsesWith(New);
+          Ins->eraseFromParent();
+        }
+      }
+    }
+  }
+
+  if (MadeChange) ++NumReturnValProped;
+  return MadeChange;
+}
+
+char IPCP::ID = 0;
+INITIALIZE_PASS(IPCP, "ipconstprop",
+                "Interprocedural constant propagation", false, false)
+
+ModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); }
+
+bool IPCP::runOnModule(Module &M) {
+  if (skipModule(M))
+    return false;
+
+  bool Changed = false;
+  bool LocalChange = true;
+
+  // FIXME: instead of using smart algorithms, we just iterate until we stop
+  // making changes.
+  while (LocalChange) {
+    LocalChange = false;
+    for (Function &F : M)
+      if (!F.isDeclaration()) {
+        // Delete any klingons.
+        F.removeDeadConstantUsers();
+        if (F.hasLocalLinkage())
+          LocalChange |= PropagateConstantsIntoArguments(F);
+        Changed |= PropagateConstantReturn(F);
+      }
+    Changed |= LocalChange;
+  }
+  return Changed;
+}

diff  --git a/llvm/lib/Transforms/IPO/IPO.cpp b/llvm/lib/Transforms/IPO/IPO.cpp
index 45aca100086d..d37b9236380d 100644
--- a/llvm/lib/Transforms/IPO/IPO.cpp
+++ b/llvm/lib/Transforms/IPO/IPO.cpp
@@ -35,6 +35,7 @@ void llvm::initializeIPO(PassRegistry &Registry) {
   initializeGlobalOptLegacyPassPass(Registry);
   initializeGlobalSplitPass(Registry);
   initializeHotColdSplittingLegacyPassPass(Registry);
+  initializeIPCPPass(Registry);
   initializeAlwaysInlinerLegacyPassPass(Registry);
   initializeSimpleInlinerPass(Registry);
   initializeInferFunctionAttrsLegacyPassPass(Registry);
@@ -103,6 +104,10 @@ void LLVMAddGlobalOptimizerPass(LLVMPassManagerRef PM) {
   unwrap(PM)->add(createGlobalOptimizerPass());
 }
 
+void LLVMAddIPConstantPropagationPass(LLVMPassManagerRef PM) {
+  unwrap(PM)->add(createIPConstantPropagationPass());
+}
+
 void LLVMAddPruneEHPass(LLVMPassManagerRef PM) {
   unwrap(PM)->add(createPruneEHPass());
 }

diff  --git a/llvm/test/Transforms/SCCP/2008-06-09-WeakProp.ll b/llvm/test/Transforms/IPConstantProp/2008-06-09-WeakProp.ll
similarity index 91%
rename from llvm/test/Transforms/SCCP/2008-06-09-WeakProp.ll
rename to llvm/test/Transforms/IPConstantProp/2008-06-09-WeakProp.ll
index b6c5299ae7dc..270115cf5ddd 100644
--- a/llvm/test/Transforms/SCCP/2008-06-09-WeakProp.ll
+++ b/llvm/test/Transforms/IPConstantProp/2008-06-09-WeakProp.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -ipsccp -S | FileCheck %s
+; RUN: opt < %s -ipconstprop -S | FileCheck %s
 ; Should not propagate the result of a weak function.
 ; PR2411
 

diff  --git a/llvm/test/Transforms/SCCP/PR43857.ll b/llvm/test/Transforms/IPConstantProp/PR43857.ll
similarity index 86%
rename from llvm/test/Transforms/SCCP/PR43857.ll
rename to llvm/test/Transforms/IPConstantProp/PR43857.ll
index efe4bca4f514..0d0d14d398de 100644
--- a/llvm/test/Transforms/SCCP/PR43857.ll
+++ b/llvm/test/Transforms/IPConstantProp/PR43857.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -S -ipsccp | FileCheck %s
+; RUN: opt < %s -S -ipconstprop | FileCheck %s
 
 %struct.wobble = type { i32 }
 %struct.zot = type { %struct.wobble, %struct.wobble, %struct.wobble }
@@ -19,7 +19,7 @@ define void @baz(<8 x i32> %arg) local_unnamed_addr {
 ; CHECK-LABEL: @baz(
 ; CHECK-NEXT:  bb:
 ; CHECK-NEXT:    [[TMP:%.*]] = call [[STRUCT_ZOT:%.*]] @widget(<8 x i32> [[ARG:%.*]])
-; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue [[STRUCT_ZOT]] undef, 0, 0
+; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue [[STRUCT_ZOT]] %tmp, 0, 0
 ; CHECK-NEXT:    ret void
 ;
 bb:

diff  --git a/llvm/test/Transforms/SCCP/arg-count-mismatch.ll b/llvm/test/Transforms/IPConstantProp/arg-count-mismatch.ll
similarity index 96%
rename from llvm/test/Transforms/SCCP/arg-count-mismatch.ll
rename to llvm/test/Transforms/IPConstantProp/arg-count-mismatch.ll
index ba5f1a6d83f7..7afe858e52d1 100644
--- a/llvm/test/Transforms/SCCP/arg-count-mismatch.ll
+++ b/llvm/test/Transforms/IPConstantProp/arg-count-mismatch.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -ipsccp -S -o - | FileCheck %s
+; RUN: opt < %s -ipconstprop -S -o - | FileCheck %s
 
 ; The original C source looked like this:
 ;
@@ -53,7 +53,7 @@ define internal i16 @bar(i16 %p1, i16 %p2) {
 
 define internal i16 @vararg_prop(i16 %p1, ...) {
 ; CHECK-LABEL: @vararg_prop(
-; CHECK-NEXT:    ret i16 undef
+; CHECK-NEXT:    ret i16 7
 ;
   ret i16 %p1
 }

diff  --git a/llvm/test/Transforms/SCCP/arg-type-mismatch.ll b/llvm/test/Transforms/IPConstantProp/arg-type-mismatch.ll
similarity index 92%
rename from llvm/test/Transforms/SCCP/arg-type-mismatch.ll
rename to llvm/test/Transforms/IPConstantProp/arg-type-mismatch.ll
index 9a9da52174c2..ff924d73390b 100644
--- a/llvm/test/Transforms/SCCP/arg-type-mismatch.ll
+++ b/llvm/test/Transforms/IPConstantProp/arg-type-mismatch.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -ipsccp -S -o - | FileCheck %s
+; RUN: opt < %s -ipconstprop -S -o - | FileCheck %s
 
 ; This test is just to verify that we do not crash/assert due to mismatch in
 ; argument type between the caller and callee.

diff  --git a/llvm/test/Transforms/IPConstantProp/comdat-ipo.ll b/llvm/test/Transforms/IPConstantProp/comdat-ipo.ll
new file mode 100644
index 000000000000..a19c89cb9bcf
--- /dev/null
+++ b/llvm/test/Transforms/IPConstantProp/comdat-ipo.ll
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -ipconstprop -S | FileCheck %s
+
+; See PR26774
+
+define i32 @baz() {
+; CHECK-LABEL: @baz(
+; CHECK-NEXT:    ret i32 10
+;
+  ret i32 10
+}
+
+; We can const-prop @baz's return value *into* @foo, but cannot
+; constprop @foo's return value into bar.
+
+define linkonce_odr i32 @foo() {
+; CHECK-LABEL: @foo(
+; CHECK-NEXT:    [[VAL:%.*]] = call i32 @baz()
+; CHECK-NEXT:    ret i32 10
+;
+
+  %val = call i32 @baz()
+  ret i32 %val
+}
+
+define i32 @bar() {
+; CHECK-LABEL: @bar(
+; CHECK-NEXT:    [[VAL:%.*]] = call i32 @foo()
+; CHECK-NEXT:    ret i32 [[VAL]]
+;
+
+  %val = call i32 @foo()
+  ret i32 %val
+}

diff  --git a/llvm/test/Transforms/SCCP/deadarg.ll b/llvm/test/Transforms/IPConstantProp/deadarg.ll
similarity index 77%
rename from llvm/test/Transforms/SCCP/deadarg.ll
rename to llvm/test/Transforms/IPConstantProp/deadarg.ll
index 1117acc7d013..25b9749b5079 100644
--- a/llvm/test/Transforms/SCCP/deadarg.ll
+++ b/llvm/test/Transforms/IPConstantProp/deadarg.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -ipsccp -disable-output
+; RUN: opt < %s -ipconstprop -disable-output
 define internal void @foo(i32 %X) {
   call void @foo( i32 %X )
   ret void

diff  --git a/llvm/test/Transforms/SCCP/multiple_callbacks.ll b/llvm/test/Transforms/IPConstantProp/multiple_callbacks.ll
similarity index 96%
rename from llvm/test/Transforms/SCCP/multiple_callbacks.ll
rename to llvm/test/Transforms/IPConstantProp/multiple_callbacks.ll
index 3d196f86e4a1..6684044e24ce 100644
--- a/llvm/test/Transforms/SCCP/multiple_callbacks.ll
+++ b/llvm/test/Transforms/IPConstantProp/multiple_callbacks.ll
@@ -1,6 +1,5 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes
-; RUN: opt -ipsccp -S %s | FileCheck %s
-;
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -ipconstprop -S < %s | FileCheck %s
 ;
 ;                            /---------------------------------------|
 ;                            |                /----------------------|----|
@@ -39,7 +38,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 define internal i32 @cb0(i32 %zero) {
 ; CHECK-LABEL: @cb0(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i32 [[ZERO:%.*]]
+; CHECK-NEXT:    ret i32 0
 ;
 entry:
   ret i32 %zero

diff  --git a/llvm/test/Transforms/SCCP/naked-return.ll b/llvm/test/Transforms/IPConstantProp/naked-return.ll
similarity index 97%
rename from llvm/test/Transforms/SCCP/naked-return.ll
rename to llvm/test/Transforms/IPConstantProp/naked-return.ll
index daeb176b0997..133662a211b4 100644
--- a/llvm/test/Transforms/SCCP/naked-return.ll
+++ b/llvm/test/Transforms/IPConstantProp/naked-return.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -ipsccp -S %s | FileCheck %s
+; RUN: opt -ipconstprop -S %s | FileCheck %s
 
 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
 target triple = "i686-pc-windows-msvc19.0.24215"

diff  --git a/llvm/test/Transforms/SCCP/openmp_parallel_for.ll b/llvm/test/Transforms/IPConstantProp/openmp_parallel_for.ll
similarity index 98%
rename from llvm/test/Transforms/SCCP/openmp_parallel_for.ll
rename to llvm/test/Transforms/IPConstantProp/openmp_parallel_for.ll
index 27831c6e6619..338cc8886e29 100644
--- a/llvm/test/Transforms/SCCP/openmp_parallel_for.ll
+++ b/llvm/test/Transforms/IPConstantProp/openmp_parallel_for.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -ipsccp < %s | FileCheck %s
+; RUN: opt -S -ipconstprop < %s | FileCheck %s
 ;
 ;    void bar(int, float, double);
 ;
@@ -53,7 +53,7 @@ define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.
 ; CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i64 [[Q:%.*]], i64* [[Q_ADDR]], align 8
+; CHECK-NEXT:    store i64 4617315517961601024, i64* [[Q_ADDR]], align 8
 ; CHECK-NEXT:    [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double*
 ; CHECK-NEXT:    [[TMP:%.*]] = load i32, i32* [[N:%.*]], align 4
 ; CHECK-NEXT:    [[SUB3:%.*]] = add nsw i32 [[TMP]], -3

diff  --git a/llvm/test/Transforms/SCCP/pthreads.ll b/llvm/test/Transforms/IPConstantProp/pthreads.ll
similarity index 93%
rename from llvm/test/Transforms/SCCP/pthreads.ll
rename to llvm/test/Transforms/IPConstantProp/pthreads.ll
index a9d2b942c1a5..dcad3858da13 100644
--- a/llvm/test/Transforms/SCCP/pthreads.ll
+++ b/llvm/test/Transforms/IPConstantProp/pthreads.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -ipsccp -S < %s | FileCheck %s
+; RUN: opt -ipconstprop -S < %s | FileCheck %s
 ;
 ;    #include <pthread.h>
 ;
@@ -44,7 +44,7 @@ declare !callback !0 dso_local i32 @pthread_create(i64*, %union.pthread_attr_t*,
 define internal i8* @foo(i8* %arg) {
 ; CHECK-LABEL: @foo(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i8* [[ARG:%.*]]
+; CHECK-NEXT:    ret i8* null
 ;
 entry:
   ret i8* %arg
@@ -53,7 +53,7 @@ entry:
 define internal i8* @bar(i8* %arg) {
 ; CHECK-LABEL: @bar(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i8* [[ARG:%.*]]
+; CHECK-NEXT:    ret i8* bitcast (i8** @GlobalVPtr to i8*)
 ;
 entry:
   ret i8* %arg

diff  --git a/llvm/test/Transforms/SCCP/recursion.ll b/llvm/test/Transforms/IPConstantProp/recursion.ll
similarity index 90%
rename from llvm/test/Transforms/SCCP/recursion.ll
rename to llvm/test/Transforms/IPConstantProp/recursion.ll
index e4f5f1d240e7..ac8ff9ca00e3 100644
--- a/llvm/test/Transforms/SCCP/recursion.ll
+++ b/llvm/test/Transforms/IPConstantProp/recursion.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -ipsccp -deadargelim -S | FileCheck %s
+; RUN: opt < %s -ipconstprop -deadargelim -S | FileCheck %s
 
 ; CHECK-NOT: %X
 

diff  --git a/llvm/test/Transforms/SCCP/return-argument.ll b/llvm/test/Transforms/IPConstantProp/return-argument.ll
similarity index 91%
rename from llvm/test/Transforms/SCCP/return-argument.ll
rename to llvm/test/Transforms/IPConstantProp/return-argument.ll
index 764b4898c961..6a3eac0c120d 100644
--- a/llvm/test/Transforms/SCCP/return-argument.ll
+++ b/llvm/test/Transforms/IPConstantProp/return-argument.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -ipsccp -S | FileCheck %s
+; RUN: opt < %s -ipconstprop -S | FileCheck %s
 
 ;; This function returns its second argument on all return statements
 define internal i32* @incdec(i1 %C, i32* %V) {
@@ -49,13 +49,11 @@ define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
 ; CHECK-NEXT:    [[Q:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[W:%.*]] = call i32* @incdec(i1 [[C:%.*]], i32* [[Q]])
 ; CHECK-NEXT:    [[S1:%.*]] = call { i32, i32 } @foo(i32 1, i32 2)
-; CHECK-NEXT:    [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
 ; CHECK-NEXT:    [[S2:%.*]] = invoke { i32, i32 } @foo(i32 3, i32 4)
 ; CHECK-NEXT:    to label [[OK:%.*]] unwind label [[LPAD:%.*]]
 ; CHECK:       OK:
-; CHECK-NEXT:    [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
-; CHECK-NEXT:    [[Z:%.*]] = add i32 [[X1]], [[X2]]
-; CHECK-NEXT:    store i32 [[Z]], i32* [[W]], align 4
+; CHECK-NEXT:    [[Z:%.*]] = add i32 1, 3
+; CHECK-NEXT:    store i32 [[Z]], i32* [[Q]], align 4
 ; CHECK-NEXT:    br label [[RET:%.*]]
 ; CHECK:       LPAD:
 ; CHECK-NEXT:    [[EXN:%.*]] = landingpad { i8*, i32 }

diff  --git a/llvm/test/Transforms/SCCP/return-constant.ll b/llvm/test/Transforms/IPConstantProp/return-constant.ll
similarity index 91%
rename from llvm/test/Transforms/SCCP/return-constant.ll
rename to llvm/test/Transforms/IPConstantProp/return-constant.ll
index 5cf53eea12b7..d75aa9b96931 100644
--- a/llvm/test/Transforms/SCCP/return-constant.ll
+++ b/llvm/test/Transforms/IPConstantProp/return-constant.ll
@@ -1,13 +1,13 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -ipsccp -instcombine -S | FileCheck %s
+; RUN: opt < %s -ipconstprop -instcombine -S | FileCheck %s
 
 define internal i32 @foo(i1 %C) {
 ; CHECK-LABEL: @foo(
 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[T:%.*]], label [[F:%.*]]
 ; CHECK:       T:
-; CHECK-NEXT:    ret i32 undef
+; CHECK-NEXT:    ret i32 52
 ; CHECK:       F:
-; CHECK-NEXT:    ret i32 undef
+; CHECK-NEXT:    ret i32 52
 ;
   br i1 %C, label %T, label %F
 

diff  --git a/llvm/test/Transforms/SCCP/return-constants.ll b/llvm/test/Transforms/IPConstantProp/return-constants.ll
similarity index 70%
rename from llvm/test/Transforms/SCCP/return-constants.ll
rename to llvm/test/Transforms/IPConstantProp/return-constants.ll
index cbf178d2efca..461106731614 100644
--- a/llvm/test/Transforms/SCCP/return-constants.ll
+++ b/llvm/test/Transforms/IPConstantProp/return-constants.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -ipsccp -S | FileCheck %s
+; RUN: opt < %s -ipconstprop -S | FileCheck %s
 
 %0 = type { i32, i32 }
 
@@ -7,9 +7,13 @@ define internal %0 @foo(i1 %Q) {
 ; CHECK-LABEL: @foo(
 ; CHECK-NEXT:    br i1 [[Q:%.*]], label [[T:%.*]], label [[F:%.*]]
 ; CHECK:       T:
-; CHECK-NEXT:    ret [[TMP0:%.*]] { i32 21, i32 22 }
+; CHECK-NEXT:    [[MRV:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
+; CHECK-NEXT:    [[MRV1:%.*]] = insertvalue [[TMP0]] %mrv, i32 22, 1
+; CHECK-NEXT:    ret [[TMP0]] %mrv1
 ; CHECK:       F:
-; CHECK-NEXT:    ret [[TMP0]] { i32 21, i32 23 }
+; CHECK-NEXT:    [[MRV2:%.*]] = insertvalue [[TMP0]] undef, i32 21, 0
+; CHECK-NEXT:    [[MRV3:%.*]] = insertvalue [[TMP0]] %mrv2, i32 23, 1
+; CHECK-NEXT:    ret [[TMP0]] %mrv3
 ;
   br i1 %Q, label %T, label %F
 
@@ -26,11 +30,14 @@ F:                                                ; preds = %0
 
 define internal %0 @bar(i1 %Q) {
 ; CHECK-LABEL: @bar(
+; CHECK-NEXT:    [[A:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
 ; CHECK-NEXT:    br i1 [[Q:%.*]], label [[T:%.*]], label [[F:%.*]]
 ; CHECK:       T:
-; CHECK-NEXT:    ret [[TMP0:%.*]] { i32 21, i32 22 }
+; CHECK-NEXT:    [[B:%.*]] = insertvalue [[TMP0]] %A, i32 22, 1
+; CHECK-NEXT:    ret [[TMP0]] %B
 ; CHECK:       F:
-; CHECK-NEXT:    ret [[TMP0]] { i32 21, i32 23 }
+; CHECK-NEXT:    [[C:%.*]] = insertvalue [[TMP0]] %A, i32 23, 1
+; CHECK-NEXT:    ret [[TMP0]] %C
 ;
   %A = insertvalue %0 undef, i32 21, 0
   br i1 %Q, label %T, label %F
@@ -50,6 +57,7 @@ define %0 @caller(i1 %Q) {
 ; CHECK-NEXT:    [[B:%.*]] = extractvalue [[TMP0]] %X, 1
 ; CHECK-NEXT:    [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]])
 ; CHECK-NEXT:    [[D:%.*]] = extractvalue [[TMP0]] %Y, 1
+; CHECK-NEXT:    [[M:%.*]] = add i32 21, 21
 ; CHECK-NEXT:    [[N:%.*]] = add i32 [[B]], [[D]]
 ; CHECK-NEXT:    ret [[TMP0]] %X
 ;

diff  --git a/llvm/test/Transforms/SCCP/thread_local_acs.ll b/llvm/test/Transforms/IPConstantProp/thread_local_acs.ll
similarity index 92%
rename from llvm/test/Transforms/SCCP/thread_local_acs.ll
rename to llvm/test/Transforms/IPConstantProp/thread_local_acs.ll
index 69c0cfeec163..3f843d26077a 100644
--- a/llvm/test/Transforms/SCCP/thread_local_acs.ll
+++ b/llvm/test/Transforms/IPConstantProp/thread_local_acs.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -ipsccp -S < %s | FileCheck %s
+; RUN: opt -ipconstprop -S < %s | FileCheck %s
 ;
 ;    #include <threads.h>
 ;    thread_local int gtl = 0;
@@ -24,7 +24,7 @@ define internal i32 @callee(i32* %thread_local_ptr, i32* %shared_ptr) {
 ; CHECK-LABEL: @callee(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[TMP:%.*]] = load i32, i32* [[THREAD_LOCAL_PTR:%.*]], align 4
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[SHARED_PTR:%.*]], align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* @gsh, align 4
 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP]], [[TMP1]]
 ; CHECK-NEXT:    ret i32 [[ADD]]
 ;

diff  --git a/llvm/test/Transforms/SCCP/comdat-ipo.ll b/llvm/test/Transforms/SCCP/comdat-ipo.ll
index fc715f45406f..618075fd5e3f 100644
--- a/llvm/test/Transforms/SCCP/comdat-ipo.ll
+++ b/llvm/test/Transforms/SCCP/comdat-ipo.ll
@@ -1,12 +1,8 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -ipsccp -S | FileCheck %s
 
 ; See PR26774
 
 define i32 @baz() {
-; CHECK-LABEL: @baz(
-; CHECK-NEXT:    ret i32 10
-;
   ret i32 10
 }
 
@@ -15,9 +11,8 @@ define i32 @baz() {
 
 define linkonce_odr i32 @foo() {
 ; CHECK-LABEL: @foo(
-; CHECK-NEXT:    [[VAL:%.*]] = call i32 @baz()
-; CHECK-NEXT:    ret i32 10
-;
+; CHECK-NEXT:  %val = call i32 @baz()
+; CHECK-NEXT:  ret i32 10
 
   %val = call i32 @baz()
   ret i32 %val
@@ -25,9 +20,8 @@ define linkonce_odr i32 @foo() {
 
 define i32 @bar() {
 ; CHECK-LABEL: @bar(
-; CHECK-NEXT:    [[VAL:%.*]] = call i32 @foo()
-; CHECK-NEXT:    ret i32 [[VAL]]
-;
+; CHECK-NEXT:  %val = call i32 @foo()
+; CHECK-NEXT:  ret i32 %val
 
   %val = call i32 @foo()
   ret i32 %val

diff  --git a/llvm/utils/findopt
diff  b/llvm/utils/findopt
diff 
index 925e2dce4bf3..9a8803184384 100755
--- a/llvm/utils/findopt
diff 
+++ b/llvm/utils/findopt
diff 
@@ -70,7 +70,7 @@ dis2="$llvm2/Debug/bin/llvm-dis"
 opt1="$llvm1/Debug/bin/opt"
 opt2="$llvm2/Debug/bin/opt"
 
-all_switches="-verify -lowersetjmp -simplifycfg -mem2reg -globalopt -globaldce -deadargelim -instcombine -simplifycfg -prune-eh -inline -simplify-libcalls -argpromotion -tailduplicate -simplifycfg -sroa -instcombine -predsimplify -condprop -tailcallelim -simplifycfg -reassociate -licm -loop-unswitch -instcombine -indvars -loop-unroll -instcombine -load-vn -gcse -sccp -instcombine -condprop -dse -dce -simplifycfg -deadtypeelim -constmerge -internalize -ipsccp -globalopt -constmerge -deadargelim -inline -prune-eh -globalopt -globaldce -argpromotion -instcombine -predsimplify -sroa -globalsmodref-aa -licm -load-vn -gcse -dse -instcombine -simplifycfg -verify"
+all_switches="-verify -lowersetjmp -simplifycfg -mem2reg -globalopt -globaldce -ipconstprop -deadargelim -instcombine -simplifycfg -prune-eh -inline -simplify-libcalls -argpromotion -tailduplicate -simplifycfg -sroa -instcombine -predsimplify -condprop -tailcallelim -simplifycfg -reassociate -licm -loop-unswitch -instcombine -indvars -loop-unroll -instcombine -load-vn -gcse -sccp -instcombine -condprop -dse -dce -simplifycfg -deadtypeelim -constmerge -internalize -ipsccp -globalopt -constmerge -deadargelim -inline -prune-eh -globalopt -globaldce -argpromotion -instcombine -predsimplify -sroa -globalsmodref-aa -licm -load-vn -gcse -dse -instcombine -simplifycfg -verify"
 
 #counter=0
 function tryit {

diff  --git a/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn
index 168bb499dcff..7d48256b6cfa 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn
@@ -38,6 +38,7 @@ static_library("IPO") {
     "GlobalOpt.cpp",
     "GlobalSplit.cpp",
     "HotColdSplitting.cpp",
+    "IPConstantPropagation.cpp",
     "IPO.cpp",
     "InferFunctionAttrs.cpp",
     "InlineSimple.cpp",


        


More information about the llvm-commits mailing list