[llvm] r374743 - Add a pass to lower is.constant and objectsize intrinsics

Joerg Sonnenberger via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 13 16:00:15 PDT 2019


Author: joerg
Date: Sun Oct 13 16:00:15 2019
New Revision: 374743

URL: http://llvm.org/viewvc/llvm-project?rev=374743&view=rev
Log:
Add a pass to lower is.constant and objectsize intrinsics

This pass lowers is.constant and objectsize intrinsics not simplified by
earlier constant folding, i.e. if the object given is not constant or if
not using the optimized pass chain. The result is recursively simplified
and constant conditionals are pruned, so that dead blocks are removed
even for -O0. This allows inline asm blocks with operand constraints to
work all the time.

The new pass replaces the existing lowering in the codegen-prepare pass
and fallbacks in SDAG/GlobalISEL and FastISel. The latter now assert
on the intrinsics.

Differential Revision: https://reviews.llvm.org/D65280

Added:
    llvm/trunk/include/llvm/Transforms/Scalar/LowerConstantIntrinsics.h
    llvm/trunk/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp
    llvm/trunk/test/Transforms/LowerConstantIntrinsics/
    llvm/trunk/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll
      - copied, changed from r374742, llvm/trunk/test/CodeGen/X86/is-constant.ll
    llvm/trunk/test/Transforms/LowerConstantIntrinsics/crash-on-large-allocas.ll
      - copied, changed from r374742, llvm/trunk/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll
    llvm/trunk/test/Transforms/LowerConstantIntrinsics/objectsize_basic.ll
      - copied, changed from r374742, llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll
Removed:
    llvm/trunk/test/CodeGen/Generic/is-constant.ll
    llvm/trunk/test/CodeGen/X86/is-constant.ll
    llvm/trunk/test/CodeGen/X86/object-size.ll
    llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll
    llvm/trunk/test/Transforms/CodeGenPrepare/builtin-condition.ll
    llvm/trunk/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll
Modified:
    llvm/trunk/bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.mli
    llvm/trunk/bindings/ocaml/transforms/scalar_opts/scalar_opts_ocaml.c
    llvm/trunk/include/llvm-c/Transforms/Scalar.h
    llvm/trunk/include/llvm/InitializePasses.h
    llvm/trunk/include/llvm/LinkAllPasses.h
    llvm/trunk/include/llvm/Transforms/Scalar.h
    llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
    llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/trunk/lib/CodeGen/TargetPassConfig.cpp
    llvm/trunk/lib/Passes/PassBuilder.cpp
    llvm/trunk/lib/Passes/PassRegistry.def
    llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
    llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt
    llvm/trunk/lib/Transforms/Scalar/Scalar.cpp
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
    llvm/trunk/test/CodeGen/AArch64/O0-pipeline.ll
    llvm/trunk/test/CodeGen/AArch64/O3-pipeline.ll
    llvm/trunk/test/CodeGen/ARM/O3-pipeline.ll
    llvm/trunk/test/CodeGen/X86/O0-pipeline.ll
    llvm/trunk/test/CodeGen/X86/O3-pipeline.ll
    llvm/trunk/test/Other/new-pm-defaults.ll
    llvm/trunk/test/Other/new-pm-thinlto-defaults.ll
    llvm/trunk/test/Other/opt-O2-pipeline.ll
    llvm/trunk/test/Other/opt-O3-pipeline.ll
    llvm/trunk/test/Other/opt-Os-pipeline.ll
    llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
    llvm/trunk/utils/gn/secondary/llvm/lib/Transforms/Scalar/BUILD.gn

Modified: llvm/trunk/bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.mli
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.mli?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.mli (original)
+++ llvm/trunk/bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.mli Sun Oct 13 16:00:15 2019
@@ -191,6 +191,11 @@ external add_lower_expect_intrinsic
   : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
   = "llvm_add_lower_expect_intrinsic"
 
+(** See the [llvm::createLowerConstantIntrinsicsPass] function. *)
+external add_lower_constant_intrinsics
+  : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+  = "llvm_add_lower_constant_intrinsics"
+
 (** See the [llvm::createTypeBasedAliasAnalysisPass] function. *)
 external add_type_based_alias_analysis
   : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit

Modified: llvm/trunk/bindings/ocaml/transforms/scalar_opts/scalar_opts_ocaml.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/transforms/scalar_opts/scalar_opts_ocaml.c?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/bindings/ocaml/transforms/scalar_opts/scalar_opts_ocaml.c (original)
+++ llvm/trunk/bindings/ocaml/transforms/scalar_opts/scalar_opts_ocaml.c Sun Oct 13 16:00:15 2019
@@ -237,6 +237,12 @@ CAMLprim value llvm_add_lower_expect_int
 }
 
 /* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_lower_constant_intrinsics(LLVMPassManagerRef PM) {
+  LLVMAddLowerConstantIntrinsicsPass(PM);
+  return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
 CAMLprim value llvm_add_type_based_alias_analysis(LLVMPassManagerRef PM) {
   LLVMAddTypeBasedAliasAnalysisPass(PM);
   return Val_unit;

Modified: llvm/trunk/include/llvm-c/Transforms/Scalar.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Transforms/Scalar.h?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/include/llvm-c/Transforms/Scalar.h (original)
+++ llvm/trunk/include/llvm-c/Transforms/Scalar.h Sun Oct 13 16:00:15 2019
@@ -147,6 +147,9 @@ void LLVMAddEarlyCSEMemSSAPass(LLVMPassM
 /** See llvm::createLowerExpectIntrinsicPass function */
 void LLVMAddLowerExpectIntrinsicPass(LLVMPassManagerRef PM);
 
+/** See llvm::createLowerConstantIntrinsicsPass function */
+void LLVMAddLowerConstantIntrinsicsPass(LLVMPassManagerRef PM);
+
 /** See llvm::createTypeBasedAliasAnalysisPass function */
 void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM);
 

Modified: llvm/trunk/include/llvm/InitializePasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/include/llvm/InitializePasses.h (original)
+++ llvm/trunk/include/llvm/InitializePasses.h Sun Oct 13 16:00:15 2019
@@ -243,6 +243,7 @@ void initializeLoopVectorizePass(PassReg
 void initializeLoopVersioningLICMPass(PassRegistry&);
 void initializeLoopVersioningPassPass(PassRegistry&);
 void initializeLowerAtomicLegacyPassPass(PassRegistry&);
+void initializeLowerConstantIntrinsicsPass(PassRegistry&);
 void initializeLowerEmuTLSPass(PassRegistry&);
 void initializeLowerExpectIntrinsicPass(PassRegistry&);
 void initializeLowerGuardIntrinsicLegacyPassPass(PassRegistry&);

Modified: llvm/trunk/include/llvm/LinkAllPasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LinkAllPasses.h (original)
+++ llvm/trunk/include/llvm/LinkAllPasses.h Sun Oct 13 16:00:15 2019
@@ -140,6 +140,7 @@ namespace {
       (void) llvm::createLoopVersioningLICMPass();
       (void) llvm::createLoopIdiomPass();
       (void) llvm::createLoopRotatePass();
+      (void) llvm::createLowerConstantIntrinsicsPass();
       (void) llvm::createLowerExpectIntrinsicPass();
       (void) llvm::createLowerInvokePass();
       (void) llvm::createLowerSwitchPass();

Modified: llvm/trunk/include/llvm/Transforms/Scalar.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Scalar.h (original)
+++ llvm/trunk/include/llvm/Transforms/Scalar.h Sun Oct 13 16:00:15 2019
@@ -397,6 +397,13 @@ FunctionPass *createLowerExpectIntrinsic
 
 //===----------------------------------------------------------------------===//
 //
+// LowerConstantIntrinsicss - Expand any remaining llvm.objectsize and
+// llvm.is.constant intrinsic calls, even for the unknown cases.
+//
+FunctionPass *createLowerConstantIntrinsicsPass();
+
+//===----------------------------------------------------------------------===//
+//
 // PartiallyInlineLibCalls - Tries to inline the fast path of library
 // calls such as sqrt.
 //

Added: llvm/trunk/include/llvm/Transforms/Scalar/LowerConstantIntrinsics.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/LowerConstantIntrinsics.h?rev=374743&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Scalar/LowerConstantIntrinsics.h (added)
+++ llvm/trunk/include/llvm/Transforms/Scalar/LowerConstantIntrinsics.h Sun Oct 13 16:00:15 2019
@@ -0,0 +1,41 @@
+//===- LowerConstantIntrinsics.h - Lower constant int. pass -*- C++ -*-========//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// The header file for the LowerConstantIntrinsics pass as used by the new pass
+/// manager.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_LOWERCONSTANTINTRINSICS_H
+#define LLVM_TRANSFORMS_SCALAR_LOWERCONSTANTINTRINSICS_H
+
+#include "llvm/IR/Function.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+struct LowerConstantIntrinsicsPass :
+    PassInfoMixin<LowerConstantIntrinsicsPass> {
+public:
+  explicit LowerConstantIntrinsicsPass() {}
+
+  /// Run the pass over the function.
+  ///
+  /// This will lower all remaining 'objectsize' and 'is.constant'`
+  /// intrinsic calls in this function, even when the argument has no known
+  /// size or is not a constant respectively. The resulting constant is
+  /// propagated and conditional branches are resolved where possible.
+  /// This complements the Instruction Simplification and
+  /// Instruction Combination passes of the optimized pass chain.
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
+};
+
+}
+
+#endif

Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Sun Oct 13 16:00:15 2019
@@ -1868,24 +1868,10 @@ bool CodeGenPrepare::optimizeCallInst(Ca
       });
       return true;
     }
-    case Intrinsic::objectsize: {
-      // Lower all uses of llvm.objectsize.*
-      Value *RetVal =
-          lowerObjectSizeCall(II, *DL, TLInfo, /*MustSucceed=*/true);
-
-      resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
-        replaceAndRecursivelySimplify(CI, RetVal, TLInfo, nullptr);
-      });
-      return true;
-    }
-    case Intrinsic::is_constant: {
-      // If is_constant hasn't folded away yet, lower it to false now.
-      Constant *RetVal = ConstantInt::get(II->getType(), 0);
-      resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
-        replaceAndRecursivelySimplify(CI, RetVal, TLInfo, nullptr);
-      });
-      return true;
-    }
+    case Intrinsic::objectsize:
+      llvm_unreachable("llvm.objectsize.* should have been lowered already");
+    case Intrinsic::is_constant:
+      llvm_unreachable("llvm.is.constant.* should have been lowered already");
     case Intrinsic::aarch64_stlxr:
     case Intrinsic::aarch64_stxr: {
       ZExtInst *ExtVal = dyn_cast<ZExtInst>(CI->getArgOperand(0));

Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Sun Oct 13 16:00:15 2019
@@ -1437,18 +1437,12 @@ bool IRTranslator::translateKnownIntrins
     MIRBuilder.buildConstant(Reg, TypeID);
     return true;
   }
-  case Intrinsic::objectsize: {
-    // If we don't know by now, we're never going to know.
-    const ConstantInt *Min = cast<ConstantInt>(CI.getArgOperand(1));
+  case Intrinsic::objectsize:
+    llvm_unreachable("llvm.objectsize.* should have been lowered already");
 
-    MIRBuilder.buildConstant(getOrCreateVReg(CI), Min->isZero() ? -1ULL : 0);
-    return true;
-  }
   case Intrinsic::is_constant:
-    // If this wasn't constant-folded away by now, then it's not a
-    // constant.
-    MIRBuilder.buildConstant(getOrCreateVReg(CI), 0);
-    return true;
+    llvm_unreachable("llvm.is.constant.* should have been lowered already");
+
   case Intrinsic::stackguard:
     getStackGuard(getOrCreateVReg(CI), MIRBuilder);
     return true;

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Sun Oct 13 16:00:15 2019
@@ -1454,24 +1454,12 @@ bool FastISel::selectIntrinsicCall(const
             TII.get(TargetOpcode::DBG_LABEL)).addMetadata(DI->getLabel());
     return true;
   }
-  case Intrinsic::objectsize: {
-    ConstantInt *CI = cast<ConstantInt>(II->getArgOperand(1));
-    unsigned long long Res = CI->isZero() ? -1ULL : 0;
-    Constant *ResCI = ConstantInt::get(II->getType(), Res);
-    unsigned ResultReg = getRegForValue(ResCI);
-    if (!ResultReg)
-      return false;
-    updateValueMap(II, ResultReg);
-    return true;
-  }
-  case Intrinsic::is_constant: {
-    Constant *ResCI = ConstantInt::get(II->getType(), 0);
-    unsigned ResultReg = getRegForValue(ResCI);
-    if (!ResultReg)
-      return false;
-    updateValueMap(II, ResultReg);
-    return true;
-  }
+  case Intrinsic::objectsize:
+    llvm_unreachable("llvm.objectsize.* should have been lowered already");
+
+  case Intrinsic::is_constant:
+    llvm_unreachable("llvm.is.constant.* should have been lowered already");
+
   case Intrinsic::launder_invariant_group:
   case Intrinsic::strip_invariant_group:
   case Intrinsic::expect: {

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Sun Oct 13 16:00:15 2019
@@ -6388,29 +6388,11 @@ void SelectionDAGBuilder::visitIntrinsic
     DAG.setRoot(Res);
     return;
   }
-  case Intrinsic::objectsize: {
-    // If we don't know by now, we're never going to know.
-    ConstantInt *CI = dyn_cast<ConstantInt>(I.getArgOperand(1));
-
-    assert(CI && "Non-constant type in __builtin_object_size?");
-
-    SDValue Arg = getValue(I.getCalledValue());
-    EVT Ty = Arg.getValueType();
-
-    if (CI->isZero())
-      Res = DAG.getConstant(-1ULL, sdl, Ty);
-    else
-      Res = DAG.getConstant(0, sdl, Ty);
-
-    setValue(&I, Res);
-    return;
-  }
+  case Intrinsic::objectsize:
+    llvm_unreachable("llvm.objectsize.* should have been lowered already");
 
   case Intrinsic::is_constant:
-    // If this wasn't constant-folded away by now, then it's not a
-    // constant.
-    setValue(&I, DAG.getConstant(0, sdl, MVT::i1));
-    return;
+    llvm_unreachable("llvm.is.constant.* should have been lowered already");
 
   case Intrinsic::annotation:
   case Intrinsic::ptr_annotation:

Modified: llvm/trunk/lib/CodeGen/TargetPassConfig.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetPassConfig.cpp?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetPassConfig.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetPassConfig.cpp Sun Oct 13 16:00:15 2019
@@ -657,6 +657,7 @@ void TargetPassConfig::addIRPasses() {
   // TODO: add a pass insertion point here
   addPass(createGCLoweringPass());
   addPass(createShadowStackGCLoweringPass());
+  addPass(createLowerConstantIntrinsicsPass());
 
   // Make sure that no unreachable blocks are instruction selected.
   addPass(createUnreachableBlockEliminationPass());

Modified: llvm/trunk/lib/Passes/PassBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/lib/Passes/PassBuilder.cpp (original)
+++ llvm/trunk/lib/Passes/PassBuilder.cpp Sun Oct 13 16:00:15 2019
@@ -142,6 +142,7 @@
 #include "llvm/Transforms/Scalar/LoopUnrollAndJamPass.h"
 #include "llvm/Transforms/Scalar/LoopUnrollPass.h"
 #include "llvm/Transforms/Scalar/LowerAtomic.h"
+#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
 #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
 #include "llvm/Transforms/Scalar/LowerGuardIntrinsic.h"
 #include "llvm/Transforms/Scalar/LowerWidenableCondition.h"
@@ -891,6 +892,8 @@ ModulePassManager PassBuilder::buildModu
 
   FunctionPassManager OptimizePM(DebugLogging);
   OptimizePM.addPass(Float2IntPass());
+  OptimizePM.addPass(LowerConstantIntrinsicsPass());
+
   // FIXME: We need to run some loop optimizations to re-rotate loops after
   // simplify-cfg and others undo their rotation.
 

Modified: llvm/trunk/lib/Passes/PassRegistry.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/lib/Passes/PassRegistry.def (original)
+++ llvm/trunk/lib/Passes/PassRegistry.def Sun Oct 13 16:00:15 2019
@@ -187,6 +187,7 @@ FUNCTION_PASS("libcalls-shrinkwrap", Lib
 FUNCTION_PASS("loweratomic", LowerAtomicPass())
 FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass())
 FUNCTION_PASS("lower-guard-intrinsic", LowerGuardIntrinsicPass())
+FUNCTION_PASS("lower-constant-intrinsics", LowerConstantIntrinsicsPass())
 FUNCTION_PASS("lower-widenable-condition", LowerWidenableConditionPass())
 FUNCTION_PASS("guard-widening", GuardWideningPass())
 FUNCTION_PASS("gvn", GVN())

Modified: llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp Sun Oct 13 16:00:15 2019
@@ -654,6 +654,7 @@ void PassManagerBuilder::populateModuleP
   MPM.add(createGlobalsAAWrapperPass());
 
   MPM.add(createFloat2IntPass());
+  MPM.add(createLowerConstantIntrinsicsPass());
 
   addExtensionsToPM(EP_VectorizerStart, MPM);
 

Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt (original)
+++ llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Sun Oct 13 16:00:15 2019
@@ -44,6 +44,7 @@ add_llvm_library(LLVMScalarOpts
   LoopUnswitch.cpp
   LoopVersioningLICM.cpp
   LowerAtomic.cpp
+  LowerConstantIntrinsics.cpp
   LowerExpectIntrinsic.cpp
   LowerGuardIntrinsic.cpp
   LowerWidenableCondition.cpp

Added: llvm/trunk/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp?rev=374743&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp (added)
+++ llvm/trunk/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp Sun Oct 13 16:00:15 2019
@@ -0,0 +1,170 @@
+//===- LowerConstantIntrinsics.cpp - Lower constant intrinsic 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 lowers all remaining 'objectsize' 'is.constant' intrinsic calls
+// and provides constant propagation and basic CFG cleanup on the result.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/Analysis/MemoryBuiltins.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/Local.h"
+
+using namespace llvm;
+using namespace llvm::PatternMatch;
+
+#define DEBUG_TYPE "lower-is-constant-intrinsic"
+
+STATISTIC(IsConstantIntrinsicsHandled,
+          "Number of 'is.constant' intrinsic calls handled");
+STATISTIC(ObjectSizeIntrinsicsHandled,
+          "Number of 'objectsize' intrinsic calls handled");
+
+static Value *lowerIsConstantIntrinsic(IntrinsicInst *II) {
+  Value *Op = II->getOperand(0);
+
+  return isa<Constant>(Op) ? ConstantInt::getTrue(II->getType())
+                           : ConstantInt::getFalse(II->getType());
+}
+
+static bool replaceConditionalBranchesOnConstant(Instruction *II,
+                                                 Value *NewValue) {
+  bool HasDeadBlocks = false;
+  SmallSetVector<Instruction *, 8> Worklist;
+  replaceAndRecursivelySimplify(II, NewValue, nullptr, nullptr, nullptr,
+                                &Worklist);
+  for (auto I : Worklist) {
+    BranchInst *BI = dyn_cast<BranchInst>(I);
+    if (!BI)
+      continue;
+    if (BI->isUnconditional())
+      continue;
+
+    BasicBlock *Target, *Other;
+    if (match(BI->getOperand(0), m_Zero())) {
+      Target = BI->getSuccessor(1);
+      Other = BI->getSuccessor(0);
+    } else if (match(BI->getOperand(0), m_One())) {
+      Target = BI->getSuccessor(0);
+      Other = BI->getSuccessor(1);
+    } else {
+      Target = nullptr;
+      Other = nullptr;
+    }
+    if (Target && Target != Other) {
+      BasicBlock *Source = BI->getParent();
+      Other->removePredecessor(Source);
+      BI->eraseFromParent();
+      BranchInst::Create(Target, Source);
+      if (pred_begin(Other) == pred_end(Other))
+        HasDeadBlocks = true;
+    }
+  }
+  return HasDeadBlocks;
+}
+
+static bool lowerConstantIntrinsics(Function &F, const TargetLibraryInfo *TLI) {
+  bool HasDeadBlocks = false;
+  const auto &DL = F.getParent()->getDataLayout();
+  SmallVector<WeakTrackingVH, 8> Worklist;
+
+  ReversePostOrderTraversal<Function *> RPOT(&F);
+  for (BasicBlock *BB : RPOT) {
+    for (Instruction &I: *BB) {
+      IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
+      if (!II)
+        continue;
+      switch (II->getIntrinsicID()) {
+      default:
+        break;
+      case Intrinsic::is_constant:
+      case Intrinsic::objectsize:
+        Worklist.push_back(WeakTrackingVH(&I));
+        break;
+      }
+    }
+  }
+  for (WeakTrackingVH &VH: Worklist) {
+    // Items on the worklist can be mutated by earlier recursive replaces.
+    // This can remove the intrinsic as dead (VH == null), but also replace
+    // the intrinsic in place.
+    if (!VH)
+      continue;
+    IntrinsicInst *II = dyn_cast<IntrinsicInst>(&*VH);
+    if (!II)
+      continue;
+    Value *NewValue;
+    switch (II->getIntrinsicID()) {
+    default:
+      continue;
+    case Intrinsic::is_constant:
+      NewValue = lowerIsConstantIntrinsic(II);
+      IsConstantIntrinsicsHandled++;
+      break;
+    case Intrinsic::objectsize:
+      NewValue = lowerObjectSizeCall(II, DL, TLI, true);
+      ObjectSizeIntrinsicsHandled++;
+      break;
+    }
+    HasDeadBlocks |= replaceConditionalBranchesOnConstant(II, NewValue);
+  }
+  if (HasDeadBlocks)
+    removeUnreachableBlocks(F);
+  return !Worklist.empty();
+}
+
+PreservedAnalyses
+LowerConstantIntrinsicsPass::run(Function &F, FunctionAnalysisManager &AM) {
+  if (lowerConstantIntrinsics(F, AM.getCachedResult<TargetLibraryAnalysis>(F)))
+    return PreservedAnalyses::none();
+
+  return PreservedAnalyses::all();
+}
+
+namespace {
+/// Legacy pass for lowering is.constant intrinsics out of the IR.
+///
+/// When this pass is run over a function it converts is.constant intrinsics
+/// into 'true' or 'false'. This is completements the normal constand folding
+/// to 'true' as part of Instruction Simplify passes.
+class LowerConstantIntrinsics : public FunctionPass {
+public:
+  static char ID;
+  LowerConstantIntrinsics() : FunctionPass(ID) {
+    initializeLowerConstantIntrinsicsPass(*PassRegistry::getPassRegistry());
+  }
+
+  bool runOnFunction(Function &F) override {
+    auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
+    const TargetLibraryInfo *TLI = TLIP ? &TLIP->getTLI(F) : nullptr;
+    return lowerConstantIntrinsics(F, TLI);
+  }
+};
+} // namespace
+
+char LowerConstantIntrinsics::ID = 0;
+INITIALIZE_PASS(LowerConstantIntrinsics, "lower-constant-intrinsics",
+                "Lower constant intrinsics", false, false)
+
+FunctionPass *llvm::createLowerConstantIntrinsicsPass() {
+  return new LowerConstantIntrinsics();
+}

Modified: llvm/trunk/lib/Transforms/Scalar/Scalar.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/Scalar.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Sun Oct 13 16:00:15 2019
@@ -79,6 +79,7 @@ void llvm::initializeScalarOpts(PassRegi
   initializeLoopVersioningLICMPass(Registry);
   initializeLoopIdiomRecognizeLegacyPassPass(Registry);
   initializeLowerAtomicLegacyPassPass(Registry);
+  initializeLowerConstantIntrinsicsPass(Registry);
   initializeLowerExpectIntrinsicPass(Registry);
   initializeLowerGuardIntrinsicLegacyPassPass(Registry);
   initializeLowerWidenableConditionLegacyPassPass(Registry);
@@ -284,6 +285,10 @@ void LLVMAddBasicAliasAnalysisPass(LLVMP
   unwrap(PM)->add(createBasicAAWrapperPass());
 }
 
+void LLVMAddLowerConstantIntrinsicsPass(LLVMPassManagerRef PM) {
+  unwrap(PM)->add(createLowerConstantIntrinsicsPass());
+}
+
 void LLVMAddLowerExpectIntrinsicPass(LLVMPassManagerRef PM) {
   unwrap(PM)->add(createLowerExpectIntrinsicPass());
 }

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll Sun Oct 13 16:00:15 2019
@@ -1183,23 +1183,6 @@ define void @test_memset(i8* %dst, i8 %v
   ret void
 }
 
-declare i64 @llvm.objectsize.i64(i8*, i1)
-declare i32 @llvm.objectsize.i32(i8*, i1)
-define void @test_objectsize(i8* %addr0, i8* %addr1) {
-; CHECK-LABEL: name: test_objectsize
-; CHECK: [[ADDR0:%[0-9]+]]:_(p0) = COPY $x0
-; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $x1
-; CHECK: {{%[0-9]+}}:_(s64) = G_CONSTANT i64 -1
-; CHECK: {{%[0-9]+}}:_(s64) = G_CONSTANT i64 0
-; CHECK: {{%[0-9]+}}:_(s32) = G_CONSTANT i32 -1
-; CHECK: {{%[0-9]+}}:_(s32) = G_CONSTANT i32 0
-  %size64.0 = call i64 @llvm.objectsize.i64(i8* %addr0, i1 0)
-  %size64.intmin = call i64 @llvm.objectsize.i64(i8* %addr0, i1 1)
-  %size32.0 = call i32 @llvm.objectsize.i32(i8* %addr0, i1 0)
-  %size32.intmin = call i32 @llvm.objectsize.i32(i8* %addr0, i1 1)
-  ret void
-}
-
 define void @test_large_const(i128* %addr) {
 ; CHECK-LABEL: name: test_large_const
 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0

Modified: llvm/trunk/test/CodeGen/AArch64/O0-pipeline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/O0-pipeline.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/O0-pipeline.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/O0-pipeline.ll Sun Oct 13 16:00:15 2019
@@ -21,6 +21,7 @@
 ; CHECK-NEXT:       Module Verifier
 ; CHECK-NEXT:       Lower Garbage Collection Instructions
 ; CHECK-NEXT:       Shadow Stack GC Lowering
+; CHECK-NEXT:       Lower constant intrinsics
 ; CHECK-NEXT:       Remove unreachable blocks from the CFG
 ; CHECK-NEXT:       Instrument function entry/exit with calls to e.g. mcount() (post inlining)
 ; CHECK-NEXT:       Scalarize Masked Memory Intrinsics

Modified: llvm/trunk/test/CodeGen/AArch64/O3-pipeline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/O3-pipeline.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/O3-pipeline.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/O3-pipeline.ll Sun Oct 13 16:00:15 2019
@@ -38,6 +38,7 @@
 ; CHECK-NEXT:       Expand memcmp() to load/stores
 ; CHECK-NEXT:       Lower Garbage Collection Instructions
 ; CHECK-NEXT:       Shadow Stack GC Lowering
+; CHECK-NEXT:       Lower constant intrinsics
 ; CHECK-NEXT:       Remove unreachable blocks from the CFG
 ; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Natural Loop Information

Modified: llvm/trunk/test/CodeGen/ARM/O3-pipeline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/O3-pipeline.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/O3-pipeline.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/O3-pipeline.ll Sun Oct 13 16:00:15 2019
@@ -22,6 +22,7 @@
 ; CHECK-NEXT:      Expand memcmp() to load/stores
 ; CHECK-NEXT:      Lower Garbage Collection Instructions
 ; CHECK-NEXT:      Shadow Stack GC Lowering
+; CHECK-NEXT:      Lower constant intrinsics
 ; CHECK-NEXT:      Remove unreachable blocks from the CFG
 ; CHECK-NEXT:      Dominator Tree Construction
 ; CHECK-NEXT:      Natural Loop Information

Removed: llvm/trunk/test/CodeGen/Generic/is-constant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/is-constant.ll?rev=374742&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Generic/is-constant.ll (original)
+++ llvm/trunk/test/CodeGen/Generic/is-constant.ll (removed)
@@ -1,114 +0,0 @@
-; RUN: opt -O2 -S < %s  | FileCheck %s
-; RUN: llc -o /dev/null 2>&1 < %s
-; RUN: llc -O0 -o /dev/null 2>&1 < %s
-
-;; The llc runs above are just to ensure it doesn't blow up upon
-;; seeing an is_constant intrinsic.
-
-declare i1 @llvm.is.constant.i32(i32 %a)
-declare i1 @llvm.is.constant.i64(i64 %a)
-declare i1 @llvm.is.constant.i256(i256 %a)
-declare i1 @llvm.is.constant.v2i64(<2 x i64> %a)
-declare i1 @llvm.is.constant.f32(float %a)
-declare i1 @llvm.is.constant.sl_i32i32s({i32, i32} %a)
-declare i1 @llvm.is.constant.a2i64([2 x i64] %a)
-declare i1 @llvm.is.constant.p0i64(i64* %a)
-
-;; Basic test that optimization folds away the is.constant when given
-;; a constant.
-define i1 @test_constant() #0 {
-; CHECK-LABEL: @test_constant(
-; CHECK-NOT: llvm.is.constant
-; CHECK: ret i1 true
-%y = call i1 @llvm.is.constant.i32(i32 44)
-  ret i1 %y
-}
-
-;; And test that the intrinsic sticks around when given a
-;; non-constant.
-define i1 @test_nonconstant(i32 %x) #0 {
-; CHECK-LABEL: @test_nonconstant(
-; CHECK: @llvm.is.constant
-  %y = call i1 @llvm.is.constant.i32(i32 %x)
-  ret i1 %y
-}
-
-;; Ensure that nested is.constants fold.
-define i32 @test_nested() #0 {
-; CHECK-LABEL: @test_nested(
-; CHECK-NOT: llvm.is.constant
-; CHECK: ret i32 13
-  %val1 = call i1 @llvm.is.constant.i32(i32 27)
-  %val2 = zext i1 %val1 to i32
-  %val3 = add i32 %val2, 12
-  %1 = call i1 @llvm.is.constant.i32(i32 %val3)
-  %2 = zext i1 %1 to i32
-  %3 = add i32 %2, 12
-  ret i32 %3
-}
-
- at G = global [2 x i64] zeroinitializer
-define i1 @test_global() #0 {
-; CHECK-LABEL: @test_global(
-; CHECK: llvm.is.constant
-  %ret = call i1 @llvm.is.constant.p0i64(i64* getelementptr ([2 x i64], [2 x i64]* @G, i32 0, i32 0))
-  ret i1 %ret
-}
-
-define i1 @test_diff() #0 {
-; CHECK-LABEL: @test_diff(
-  %ret = call i1 @llvm.is.constant.i64(i64 sub (
-      i64 ptrtoint (i64* getelementptr inbounds ([2 x i64], [2 x i64]* @G, i64 0, i64 1) to i64),
-      i64 ptrtoint ([2 x i64]* @G to i64)))
-  ret i1 %ret
-}
-
-define i1 @test_various_types(i256 %int, float %float, <2 x i64> %vec, {i32, i32} %struct, [2 x i64] %arr, i64* %ptr) #0 {
-; CHECK-LABEL: @test_various_types(
-; CHECK: llvm.is.constant
-; CHECK: llvm.is.constant
-; CHECK: llvm.is.constant
-; CHECK: llvm.is.constant
-; CHECK: llvm.is.constant
-; CHECK: llvm.is.constant
-; CHECK-NOT: llvm.is.constant
-  %v1 = call i1 @llvm.is.constant.i256(i256 %int)
-  %v2 = call i1 @llvm.is.constant.f32(float %float)
-  %v3 = call i1 @llvm.is.constant.v2i64(<2 x i64> %vec)
-  %v4 = call i1 @llvm.is.constant.sl_i32i32s({i32, i32} %struct)
-  %v5 = call i1 @llvm.is.constant.a2i64([2 x i64] %arr)
-  %v6 = call i1 @llvm.is.constant.p0i64(i64* %ptr)
-
-  %c1 = call i1 @llvm.is.constant.i256(i256 -1)
-  %c2 = call i1 @llvm.is.constant.f32(float 17.0)
-  %c3 = call i1 @llvm.is.constant.v2i64(<2 x i64> <i64 -1, i64 44>)
-  %c4 = call i1 @llvm.is.constant.sl_i32i32s({i32, i32} {i32 -1, i32 32})
-  %c5 = call i1 @llvm.is.constant.a2i64([2 x i64] [i64 -1, i64 32])
-  %c6 = call i1 @llvm.is.constant.p0i64(i64* inttoptr (i32 42 to i64*))
-
-  %x1 = add i1 %v1, %c1
-  %x2 = add i1 %v2, %c2
-  %x3 = add i1 %v3, %c3
-  %x4 = add i1 %v4, %c4
-  %x5 = add i1 %v5, %c5
-  %x6 = add i1 %v6, %c6
-
-  %res2 = add i1 %x1, %x2
-  %res3 = add i1 %res2, %x3
-  %res4 = add i1 %res3, %x4
-  %res5 = add i1 %res4, %x5
-  %res6 = add i1 %res5, %x6
-
-  ret i1 %res6
-}
-
-define i1 @test_various_types2() #0 {
-; CHECK-LABEL: @test_various_types2(
-; CHECK: ret i1 false
-  %r = call i1 @test_various_types(i256 -1, float 22.0, <2 x i64> <i64 -1, i64 44>,
-                     {i32, i32} {i32 -1, i32 55}, [2 x i64] [i64 -1, i64 55],
-		     i64* inttoptr (i64 42 to i64*))
-  ret i1 %r
-}
-
-attributes #0 = { nounwind uwtable }

Modified: llvm/trunk/test/CodeGen/X86/O0-pipeline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/O0-pipeline.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/O0-pipeline.ll (original)
+++ llvm/trunk/test/CodeGen/X86/O0-pipeline.ll Sun Oct 13 16:00:15 2019
@@ -24,6 +24,7 @@
 ; CHECK-NEXT:       Module Verifier
 ; CHECK-NEXT:       Lower Garbage Collection Instructions
 ; CHECK-NEXT:       Shadow Stack GC Lowering
+; CHECK-NEXT:       Lower constant intrinsics
 ; CHECK-NEXT:       Remove unreachable blocks from the CFG
 ; CHECK-NEXT:       Instrument function entry/exit with calls to e.g. mcount() (post inlining)
 ; CHECK-NEXT:       Scalarize Masked Memory Intrinsics

Modified: llvm/trunk/test/CodeGen/X86/O3-pipeline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/O3-pipeline.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/O3-pipeline.ll (original)
+++ llvm/trunk/test/CodeGen/X86/O3-pipeline.ll Sun Oct 13 16:00:15 2019
@@ -35,6 +35,7 @@
 ; CHECK-NEXT:       Expand memcmp() to load/stores
 ; CHECK-NEXT:       Lower Garbage Collection Instructions
 ; CHECK-NEXT:       Shadow Stack GC Lowering
+; CHECK-NEXT:       Lower constant intrinsics
 ; CHECK-NEXT:       Remove unreachable blocks from the CFG
 ; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Natural Loop Information

Removed: llvm/trunk/test/CodeGen/X86/is-constant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/is-constant.ll?rev=374742&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/is-constant.ll (original)
+++ llvm/trunk/test/CodeGen/X86/is-constant.ll (removed)
@@ -1,50 +0,0 @@
-; RUN: llc -O2 < %s | FileCheck %s --check-prefix=CHECK-O2 --check-prefix=CHECK
-; RUN: llc -O0 -fast-isel < %s | FileCheck %s --check-prefix=CHECK-O0 --check-prefix=CHECK
-; RUN: llc -O0 -fast-isel=0 < %s | FileCheck %s --check-prefix=CHECK-O0 --check-prefix=CHECK
-; RUN: llc -O0 -global-isel < %s | FileCheck %s --check-prefix=CHECK-O0 --check-prefix=CHECK
-
-;; Ensure that an unfoldable is.constant gets lowered reasonably in
-;; optimized codegen, in particular, that the "true" branch is
-;; eliminated.
-;;
-;; This isn't asserting any specific output from non-optimized runs,
-;; (e.g., currently the not-taken branch does not get eliminated). But
-;; it does ensure that lowering succeeds in all 3 codegen paths.
-
-target triple = "x86_64-unknown-linux-gnu"
-
-declare i1 @llvm.is.constant.i32(i32 %a) nounwind readnone
-declare i1 @llvm.is.constant.i64(i64 %a) nounwind readnone
-declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1) nounwind readnone
-
-declare i32 @subfun_1()
-declare i32 @subfun_2()
-
-define i32 @test_branch(i32 %in) nounwind {
-; CHECK-LABEL:    test_branch:
-; CHECK-O2:       %bb.0:
-; CHECK-O2-NEXT:  jmp subfun_2
-  %v = call i1 @llvm.is.constant.i32(i32 %in)
-  br i1 %v, label %True, label %False
-
-True:
-  %call1 = tail call i32 @subfun_1()
-  ret i32 %call1
-
-False:
-  %call2 = tail call i32 @subfun_2()
-  ret i32 %call2
-}
-
-;; llvm.objectsize is another tricky case which gets folded to -1 very
-;; late in the game. We'd like to ensure that llvm.is.constant of
-;; llvm.objectsize is true.
-define i1 @test_objectsize(i8* %obj) nounwind {
-; CHECK-LABEL:    test_objectsize:
-; CHECK-O2:       %bb.0:
-; CHECK-O2:       movb $1, %al
-; CHECK-O2-NEXT:  retq
-  %os = call i64 @llvm.objectsize.i64.p0i8(i8* %obj, i1 false, i1 false, i1 false)
-  %v = call i1 @llvm.is.constant.i64(i64 %os)
-  ret i1 %v
-}

Removed: llvm/trunk/test/CodeGen/X86/object-size.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/object-size.ll?rev=374742&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/object-size.ll (original)
+++ llvm/trunk/test/CodeGen/X86/object-size.ll (removed)
@@ -1,55 +0,0 @@
-; RUN: llc -O0 < %s | FileCheck %s
-
-; ModuleID = 'ts.c'
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
-target triple = "x86_64-apple-darwin10.0"
-
- at p = common global i8* null, align 8              ; <i8**> [#uses=4]
- at .str = private constant [3 x i8] c"Hi\00"        ; <[3 x i8]*> [#uses=1]
-
-define void @bar() nounwind ssp {
-entry:
-  %tmp = load i8*, i8** @p                             ; <i8*> [#uses=1]
-  %0 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp, i1 0) ; <i64> [#uses=1]
-  %cmp = icmp ne i64 %0, -1                       ; <i1> [#uses=1]
-; CHECK: movq $-1, [[RAX:%r..]]
-; CHECK: cmpq $-1, [[RAX]]
-  br i1 %cmp, label %cond.true, label %cond.false
-
-cond.true:                                        ; preds = %entry
-  %tmp1 = load i8*, i8** @p                            ; <i8*> [#uses=1]
-  %tmp2 = load i8*, i8** @p                            ; <i8*> [#uses=1]
-  %1 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp2, i1 1) ; <i64> [#uses=1]
-  %call = call i8* @__strcpy_chk(i8* %tmp1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i64 %1) ssp ; <i8*> [#uses=1]
-  br label %cond.end
-
-cond.false:                                       ; preds = %entry
-  %tmp3 = load i8*, i8** @p                            ; <i8*> [#uses=1]
-  %call4 = call i8* @__inline_strcpy_chk(i8* %tmp3, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0)) ssp ; <i8*> [#uses=1]
-  br label %cond.end
-
-cond.end:                                         ; preds = %cond.false, %cond.true
-  %cond = phi i8* [ %call, %cond.true ], [ %call4, %cond.false ] ; <i8*> [#uses=0]
-  ret void
-}
-
-declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) nounwind readonly
-
-declare i8* @__strcpy_chk(i8*, i8*, i64) ssp
-
-define internal i8* @__inline_strcpy_chk(i8* %__dest, i8* %__src) nounwind ssp {
-entry:
-  %retval = alloca i8*                            ; <i8**> [#uses=2]
-  %__dest.addr = alloca i8*                       ; <i8**> [#uses=3]
-  %__src.addr = alloca i8*                        ; <i8**> [#uses=2]
-  store i8* %__dest, i8** %__dest.addr
-  store i8* %__src, i8** %__src.addr
-  %tmp = load i8*, i8** %__dest.addr                   ; <i8*> [#uses=1]
-  %tmp1 = load i8*, i8** %__src.addr                   ; <i8*> [#uses=1]
-  %tmp2 = load i8*, i8** %__dest.addr                  ; <i8*> [#uses=1]
-  %0 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp2, i1 1) ; <i64> [#uses=1]
-  %call = call i8* @__strcpy_chk(i8* %tmp, i8* %tmp1, i64 %0) ssp ; <i8*> [#uses=1]
-  store i8* %call, i8** %retval
-  %1 = load i8*, i8** %retval                          ; <i8*> [#uses=1]
-  ret i8* %1
-}

Modified: llvm/trunk/test/Other/new-pm-defaults.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pm-defaults.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/Other/new-pm-defaults.ll (original)
+++ llvm/trunk/test/Other/new-pm-defaults.ll Sun Oct 13 16:00:15 2019
@@ -231,6 +231,7 @@
 ; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
 ; CHECK-O-NEXT: Starting llvm::Function pass manager run.
 ; CHECK-O-NEXT: Running pass: Float2IntPass
+; CHECK-O-NEXT: Running pass: LowerConstantIntrinsicsPass on foo
 ; CHECK-EP-VECTORIZER-START-NEXT: Running pass: NoOpFunctionPass
 ; CHECK-O-NEXT: Running pass: FunctionToLoopPassAdaptor<{{.*}}LoopRotatePass
 ; CHECK-O-NEXT: Starting llvm::Function pass manager run.

Modified: llvm/trunk/test/Other/new-pm-thinlto-defaults.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pm-thinlto-defaults.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/Other/new-pm-thinlto-defaults.ll (original)
+++ llvm/trunk/test/Other/new-pm-thinlto-defaults.ll Sun Oct 13 16:00:15 2019
@@ -205,6 +205,7 @@
 ; CHECK-POSTLINK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
 ; CHECK-POSTLINK-O-NEXT: Starting llvm::Function pass manager run.
 ; CHECK-POSTLINK-O-NEXT: Running pass: Float2IntPass
+; CHECK-POSTLINK-O-NEXT: Running pass: LowerConstantIntrinsicsPass
 ; CHECK-POSTLINK-O-NEXT: Running pass: FunctionToLoopPassAdaptor<{{.*}}LoopRotatePass
 ; CHECK-POSTLINK-O-NEXT: Starting llvm::Function pass manager run
 ; CHECK-POSTLINK-O-NEXT: Running pass: LoopSimplifyPass

Modified: llvm/trunk/test/Other/opt-O2-pipeline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/opt-O2-pipeline.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/Other/opt-O2-pipeline.ll (original)
+++ llvm/trunk/test/Other/opt-O2-pipeline.ll Sun Oct 13 16:00:15 2019
@@ -187,6 +187,8 @@
 ; CHECK-NEXT:     FunctionPass Manager
 ; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Float to int
+; CHECK-NEXT:       Lower constant intrinsics
+; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
 ; CHECK-NEXT:       Function Alias Analysis Results
 ; CHECK-NEXT:       Memory SSA

Modified: llvm/trunk/test/Other/opt-O3-pipeline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/opt-O3-pipeline.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/Other/opt-O3-pipeline.ll (original)
+++ llvm/trunk/test/Other/opt-O3-pipeline.ll Sun Oct 13 16:00:15 2019
@@ -192,6 +192,8 @@
 ; CHECK-NEXT:     FunctionPass Manager
 ; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Float to int
+; CHECK-NEXT:       Lower constant intrinsics
+; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
 ; CHECK-NEXT:       Function Alias Analysis Results
 ; CHECK-NEXT:       Memory SSA

Modified: llvm/trunk/test/Other/opt-Os-pipeline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/opt-Os-pipeline.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/Other/opt-Os-pipeline.ll (original)
+++ llvm/trunk/test/Other/opt-Os-pipeline.ll Sun Oct 13 16:00:15 2019
@@ -174,6 +174,8 @@
 ; CHECK-NEXT:     FunctionPass Manager
 ; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Float to int
+; CHECK-NEXT:       Lower constant intrinsics
+; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
 ; CHECK-NEXT:       Function Alias Analysis Results
 ; CHECK-NEXT:       Memory SSA

Modified: llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll (original)
+++ llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll Sun Oct 13 16:00:15 2019
@@ -514,26 +514,6 @@ exit:
   ret void
 }
 
-; This was crashing when trying to delay instruction removal/deletion.
-
-declare i64 @llvm.objectsize.i64.p0i8(i8*, i1 immarg, i1 immarg, i1 immarg) #0
-
-define hidden fastcc void @crash() {
-; CHECK-LABEL: @crash(
-; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 undef, i64 undef)
-; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
-; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
-; CHECK-NEXT:    [[T2:%.*]] = select i1 undef, i1 undef, i1 [[OV]]
-; CHECK-NEXT:    unreachable
-;
-  %t0 = add i64 undef, undef
-  %t1 = icmp ult i64 %t0, undef
-  %t2 = select i1 undef, i1 undef, i1 %t1
-  %t3 = call i64 @llvm.objectsize.i64.p0i8(i8* nonnull undef, i1 false, i1 false, i1 false)
-  %t4 = icmp ugt i64 %t3, 7
-  unreachable
-}
-
 ; Check that every instruction inserted by -codegenprepare has a debug location.
 ; DEBUG: CheckModuleDebugify: PASS
 

Removed: llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll?rev=374742&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll (original)
+++ llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll (removed)
@@ -1,86 +0,0 @@
-; RUN: opt -codegenprepare -S < %s | FileCheck %s
-
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
-target triple = "x86_64-apple-darwin10.0.0"
-
-; CHECK-LABEL: @test1(
-; objectsize should fold to a constant, which causes the branch to fold to an
-; uncond branch. Next, we fold the control flow alltogether.
-; rdar://8785296
-define i32 @test1(i8* %ptr) nounwind ssp noredzone align 2 {
-entry:
-  %0 = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false, i1 false, i1 false)
-  %1 = icmp ugt i64 %0, 3
-  br i1 %1, label %T, label %trap
-
-; CHECK: entry:
-; CHECK-NOT: br label %
-
-trap:                                             ; preds = %0, %entry
-  tail call void @llvm.trap() noreturn nounwind
-  unreachable
-
-T:
-; CHECK: ret i32 4
-  ret i32 4
-}
-
-; CHECK-LABEL: @test_objectsize_null_flag(
-define i64 @test_objectsize_null_flag(i8* %ptr) {
-entry:
-  ; CHECK: ret i64 -1
-  %0 = tail call i64 @llvm.objectsize.i64(i8* null, i1 false, i1 true, i1 false)
-  ret i64 %0
-}
-
-; CHECK-LABEL: @test_objectsize_null_flag_min(
-define i64 @test_objectsize_null_flag_min(i8* %ptr) {
-entry:
-  ; CHECK: ret i64 0
-  %0 = tail call i64 @llvm.objectsize.i64(i8* null, i1 true, i1 true, i1 false)
-  ret i64 %0
-}
-
-; Test foldable null pointers because we evaluate them with non-exact modes in
-; CodeGenPrepare.
-; CHECK-LABEL: @test_objectsize_null_flag_noas0(
-define i64 @test_objectsize_null_flag_noas0() {
-entry:
-  ; CHECK: ret i64 -1
-  %0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 false,
-                                               i1 true, i1 false)
-  ret i64 %0
-}
-
-; CHECK-LABEL: @test_objectsize_null_flag_min_noas0(
-define i64 @test_objectsize_null_flag_min_noas0() {
-entry:
-  ; CHECK: ret i64 0
-  %0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 true,
-                                               i1 true, i1 false)
-  ret i64 %0
-}
-
-; CHECK-LABEL: @test_objectsize_null_known_flag_noas0
-define i64 @test_objectsize_null_known_flag_noas0() {
-entry:
-  ; CHECK: ret i64 -1
-  %0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 false,
-                                               i1 false, i1 false)
-  ret i64 %0
-}
-
-; CHECK-LABEL: @test_objectsize_null_known_flag_min_noas0
-define i64 @test_objectsize_null_known_flag_min_noas0() {
-entry:
-  ; CHECK: ret i64 0
-  %0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 true,
-                                               i1 false, i1 false)
-  ret i64 %0
-}
-
-
-declare i64 @llvm.objectsize.i64(i8*, i1, i1, i1) nounwind readonly
-declare i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)*, i1, i1, i1) nounwind readonly
-
-declare void @llvm.trap() nounwind

Removed: llvm/trunk/test/Transforms/CodeGenPrepare/builtin-condition.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/builtin-condition.ll?rev=374742&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/CodeGenPrepare/builtin-condition.ll (original)
+++ llvm/trunk/test/Transforms/CodeGenPrepare/builtin-condition.ll (removed)
@@ -1,123 +0,0 @@
-; RUN: opt -codegenprepare -S  < %s | FileCheck %s
-
-; Ensure we act sanely on overflow.
-; CHECK-LABEL: define i32 @bar
-define i32 @bar() {
-entry:
-  ; CHECK: ret i32 -1
-  %az = alloca [2147483649 x i32], align 16
-  %a = alloca i8*, align 8
-  %arraydecay = getelementptr inbounds [2147483649 x i32], [2147483649 x i32]* %az, i32 0, i32 0
-  %0 = bitcast i32* %arraydecay to i8*
-  store i8* %0, i8** %a, align 8
-  %1 = load i8*, i8** %a, align 8
-  %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false)
-  ret i32 %2
-}
-
-; CHECK-LABEL: define i32 @baz
-define i32 @baz(i32 %n) {
-entry:
-  ; CHECK: ret i32 -1
-  %az = alloca [1 x i32], align 16
-  %bz = alloca [4294967297 x i32], align 16
-  %tobool = icmp ne i32 %n, 0
-  %arraydecay = getelementptr inbounds [1 x i32], [1 x i32]* %az, i64 0, i64 0
-  %arraydecay1 = getelementptr inbounds [4294967297 x i32], [4294967297 x i32]* %bz, i64 0, i64 0
-  %cond = select i1 %tobool, i32* %arraydecay, i32* %arraydecay1
-  %0 = bitcast i32* %cond to i8*
-  %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false)
-  ret i32 %1
-}
-
-declare i32 @llvm.objectsize.i32.p0i8(i8*, i1)
-
-; The following tests were generated by:
-; #include<stdlib.h>
-; #define STATIC_BUF_SIZE 10
-; #define LARGER_BUF_SIZE 30
-;
-; size_t foo1(int flag) {
-;   char *cptr;
-;   char chararray[LARGER_BUF_SIZE];
-;   char chararray2[STATIC_BUF_SIZE];
-;   if(flag)
-;     cptr = chararray2;
-;    else
-;     cptr = chararray;
-;
-;   return  __builtin_object_size(cptr, 2);
-; }
-;
-; size_t foo2(int n) {
-;   char Small[10];
-;   char Large[20];
-;   char *Ptr = n ? Small : Large + 19;
-;   return __builtin_object_size(Ptr, 0);
-; }
-;
-; void foo() {
-;   size_t ret;
-;   size_t ret1;
-;   ret = foo1(0);
-;   ret1 = foo2(0);
-;   printf("\n%d %d\n", ret, ret1);
-; }
-
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-unknown-linux-gnu"
-
- at .str = private unnamed_addr constant [8 x i8] c"\0A%d %d\0A\00", align 1
-
-define i64 @foo1(i32 %flag) {
-entry:
-  %chararray = alloca [30 x i8], align 16
-  %chararray2 = alloca [10 x i8], align 1
-  %0 = getelementptr inbounds [30 x i8], [30 x i8]* %chararray, i64 0, i64 0
-  call void @llvm.lifetime.start.p0i8(i64 30, i8* %0)
-  %1 = getelementptr inbounds [10 x i8], [10 x i8]* %chararray2, i64 0, i64 0
-  call void @llvm.lifetime.start.p0i8(i64 10, i8* %1)
-  %tobool = icmp eq i32 %flag, 0
-  %cptr.0 = select i1 %tobool, i8* %0, i8* %1
-  %2 = call i64 @llvm.objectsize.i64.p0i8(i8* %cptr.0, i1 true)
-  call void @llvm.lifetime.end.p0i8(i64 10, i8* %1)
-  call void @llvm.lifetime.end.p0i8(i64 30, i8* %0)
-  ret i64 %2
-; CHECK-LABEL: foo1
-; CHECK:  ret i64 10
-}
-
-declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
-
-declare i64 @llvm.objectsize.i64.p0i8(i8*, i1)
-
-declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
-
-define i64 @foo2(i32 %n) {
-entry:
-  %Small = alloca [10 x i8], align 1
-  %Large = alloca [20 x i8], align 16
-  %0 = getelementptr inbounds [10 x i8], [10 x i8]* %Small, i64 0, i64 0
-  call void @llvm.lifetime.start.p0i8(i64 10, i8* %0)
-  %1 = getelementptr inbounds [20 x i8], [20 x i8]* %Large, i64 0, i64 0
-  call void @llvm.lifetime.start.p0i8(i64 20, i8* %1)
-  %tobool = icmp ne i32 %n, 0
-  %add.ptr = getelementptr inbounds [20 x i8], [20 x i8]* %Large, i64 0, i64 19
-  %cond = select i1 %tobool, i8* %0, i8* %add.ptr
-  %2 = call i64 @llvm.objectsize.i64.p0i8(i8* %cond, i1 false)
-  call void @llvm.lifetime.end.p0i8(i64 20, i8* %1)
-  call void @llvm.lifetime.end.p0i8(i64 10, i8* %0)
-  ret i64 %2
-; CHECK-LABEL: foo2
-; CHECK:  ret i64 10
-}
-
-define void @foo() {
-entry:
-  %call = tail call i64 @foo1(i32 0)
-  %call1 = tail call i64 @foo2(i32 0)
-  %call2 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i64 %call, i64 %call1)
-  ret void
-}
-
-declare i32 @printf(i8* nocapture readonly, ...)

Removed: llvm/trunk/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll?rev=374742&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll (original)
+++ llvm/trunk/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll (removed)
@@ -1,16 +0,0 @@
-; RUN: opt -S -codegenprepare %s -o - | FileCheck %s
-;
-; Ensure that we don't {crash,return a bad value} when given an alloca larger
-; than what a pointer can represent.
-
-target datalayout = "p:16:16"
-
-; CHECK-LABEL: @alloca_overflow_is_unknown(
-define i16 @alloca_overflow_is_unknown() {
-  %i = alloca i8, i32 65537
-  %j = call i16 @llvm.objectsize.i16.p0i8(i8* %i, i1 false, i1 false, i1 false)
-  ; CHECK: ret i16 -1
-  ret i16 %j
-}
-
-declare i16 @llvm.objectsize.i16.p0i8(i8*, i1, i1, i1)

Copied: llvm/trunk/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll (from r374742, llvm/trunk/test/CodeGen/X86/is-constant.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll?p2=llvm/trunk/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll&p1=llvm/trunk/test/CodeGen/X86/is-constant.ll&r1=374742&r2=374743&rev=374743&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/is-constant.ll (original)
+++ llvm/trunk/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll Sun Oct 13 16:00:15 2019
@@ -1,29 +1,30 @@
-; RUN: llc -O2 < %s | FileCheck %s --check-prefix=CHECK-O2 --check-prefix=CHECK
-; RUN: llc -O0 -fast-isel < %s | FileCheck %s --check-prefix=CHECK-O0 --check-prefix=CHECK
-; RUN: llc -O0 -fast-isel=0 < %s | FileCheck %s --check-prefix=CHECK-O0 --check-prefix=CHECK
-; RUN: llc -O0 -global-isel < %s | FileCheck %s --check-prefix=CHECK-O0 --check-prefix=CHECK
+; RUN: opt -lower-constant-intrinsics -S < %s | FileCheck %s
 
 ;; Ensure that an unfoldable is.constant gets lowered reasonably in
 ;; optimized codegen, in particular, that the "true" branch is
 ;; eliminated.
-;;
-;; This isn't asserting any specific output from non-optimized runs,
-;; (e.g., currently the not-taken branch does not get eliminated). But
-;; it does ensure that lowering succeeds in all 3 codegen paths.
 
-target triple = "x86_64-unknown-linux-gnu"
+;; Also ensure that any unfoldable objectsize is resolved in order.
+
+;; CHECK-NOT: tail call i32 @subfun_1()
+;; CHECK:     tail call i32 @subfun_2()
+;; CHECK-NOT: tail call i32 @subfun_1()
 
 declare i1 @llvm.is.constant.i32(i32 %a) nounwind readnone
 declare i1 @llvm.is.constant.i64(i64 %a) nounwind readnone
+declare i1 @llvm.is.constant.i256(i256 %a) nounwind readnone
+declare i1 @llvm.is.constant.v2i64(<2 x i64> %a) nounwind readnone
+declare i1 @llvm.is.constant.f32(float %a) nounwind readnone
+declare i1 @llvm.is.constant.sl_i32i32s({i32, i32} %a) nounwind readnone
+declare i1 @llvm.is.constant.a2i64([2 x i64] %a) nounwind readnone
+declare i1 @llvm.is.constant.p0i64(i64* %a) nounwind readnone
+
 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1) nounwind readnone
 
 declare i32 @subfun_1()
 declare i32 @subfun_2()
 
 define i32 @test_branch(i32 %in) nounwind {
-; CHECK-LABEL:    test_branch:
-; CHECK-O2:       %bb.0:
-; CHECK-O2-NEXT:  jmp subfun_2
   %v = call i1 @llvm.is.constant.i32(i32 %in)
   br i1 %v, label %True, label %False
 
@@ -40,11 +41,74 @@ False:
 ;; late in the game. We'd like to ensure that llvm.is.constant of
 ;; llvm.objectsize is true.
 define i1 @test_objectsize(i8* %obj) nounwind {
-; CHECK-LABEL:    test_objectsize:
-; CHECK-O2:       %bb.0:
-; CHECK-O2:       movb $1, %al
-; CHECK-O2-NEXT:  retq
+;; CHECK-LABEL:    test_objectsize
+;; CHECK-NOT:      llvm.objectsize
+;; CHECK-NOT:      llvm.is.constant
+;; CHECK:          ret i1 true
   %os = call i64 @llvm.objectsize.i64.p0i8(i8* %obj, i1 false, i1 false, i1 false)
-  %v = call i1 @llvm.is.constant.i64(i64 %os)
+  %os1 = add i64 %os, 1
+  %v = call i1 @llvm.is.constant.i64(i64 %os1)
   ret i1 %v
 }
+
+ at test_phi_a = dso_local global i32 0, align 4
+declare dso_local i32 @test_phi_b(...)
+
+; Function Attrs: nounwind uwtable
+define dso_local i32 @test_phi() {
+entry:
+  %0 = load i32, i32* @test_phi_a, align 4
+  %1 = tail call i1 @llvm.is.constant.i32(i32 %0)
+  br i1 %1, label %cond.end, label %cond.false
+
+cond.false:                                       ; preds = %entry
+  %call = tail call i32 bitcast (i32 (...)* @test_phi_b to i32 ()*)() #3
+  %.pre = load i32, i32* @test_phi_a, align 4
+  br label %cond.end
+
+cond.end:                                         ; preds = %entry, %cond.false
+  %2 = phi i32 [ %.pre, %cond.false ], [ %0, %entry ]
+  %cond = phi i32 [ %call, %cond.false ], [ 1, %entry ]
+  %cmp = icmp eq i32 %cond, %2
+  br i1 %cmp, label %cond.true1, label %cond.end4
+
+cond.true1:                                       ; preds = %cond.end
+  %call2 = tail call i32 bitcast (i32 (...)* @test_phi_b to i32 ()*)() #3
+  br label %cond.end4
+
+cond.end4:                                        ; preds = %cond.end, %cond.true1
+  ret i32 undef
+}
+
+define i1 @test_various_types(i256 %int, float %float, <2 x i64> %vec, {i32, i32} %struct, [2 x i64] %arr, i64* %ptr) #0 {
+; CHECK-LABEL: @test_various_types(
+; CHECK-NOT: llvm.is.constant
+  %v1 = call i1 @llvm.is.constant.i256(i256 %int)
+  %v2 = call i1 @llvm.is.constant.f32(float %float)
+  %v3 = call i1 @llvm.is.constant.v2i64(<2 x i64> %vec)
+  %v4 = call i1 @llvm.is.constant.sl_i32i32s({i32, i32} %struct)
+  %v5 = call i1 @llvm.is.constant.a2i64([2 x i64] %arr)
+  %v6 = call i1 @llvm.is.constant.p0i64(i64* %ptr)
+
+  %c1 = call i1 @llvm.is.constant.i256(i256 -1)
+  %c2 = call i1 @llvm.is.constant.f32(float 17.0)
+  %c3 = call i1 @llvm.is.constant.v2i64(<2 x i64> <i64 -1, i64 44>)
+  %c4 = call i1 @llvm.is.constant.sl_i32i32s({i32, i32} {i32 -1, i32 32})
+  %c5 = call i1 @llvm.is.constant.a2i64([2 x i64] [i64 -1, i64 32])
+  %c6 = call i1 @llvm.is.constant.p0i64(i64* inttoptr (i32 42 to i64*))
+
+  %x1 = add i1 %v1, %c1
+  %x2 = add i1 %v2, %c2
+  %x3 = add i1 %v3, %c3
+  %x4 = add i1 %v4, %c4
+  %x5 = add i1 %v5, %c5
+  %x6 = add i1 %v6, %c6
+
+  %res2 = add i1 %x1, %x2
+  %res3 = add i1 %res2, %x3
+  %res4 = add i1 %res3, %x4
+  %res5 = add i1 %res4, %x5
+  %res6 = add i1 %res5, %x6
+
+  ret i1 %res6
+}

Copied: llvm/trunk/test/Transforms/LowerConstantIntrinsics/crash-on-large-allocas.ll (from r374742, llvm/trunk/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerConstantIntrinsics/crash-on-large-allocas.ll?p2=llvm/trunk/test/Transforms/LowerConstantIntrinsics/crash-on-large-allocas.ll&p1=llvm/trunk/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll&r1=374742&r2=374743&rev=374743&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll (original)
+++ llvm/trunk/test/Transforms/LowerConstantIntrinsics/crash-on-large-allocas.ll Sun Oct 13 16:00:15 2019
@@ -1,4 +1,4 @@
-; RUN: opt -S -codegenprepare %s -o - | FileCheck %s
+; RUN: opt -S -lower-constant-intrinsics %s -o - | FileCheck %s
 ;
 ; Ensure that we don't {crash,return a bad value} when given an alloca larger
 ; than what a pointer can represent.

Copied: llvm/trunk/test/Transforms/LowerConstantIntrinsics/objectsize_basic.ll (from r374742, llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerConstantIntrinsics/objectsize_basic.ll?p2=llvm/trunk/test/Transforms/LowerConstantIntrinsics/objectsize_basic.ll&p1=llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll&r1=374742&r2=374743&rev=374743&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll (original)
+++ llvm/trunk/test/Transforms/LowerConstantIntrinsics/objectsize_basic.ll Sun Oct 13 16:00:15 2019
@@ -1,12 +1,15 @@
-; RUN: opt -codegenprepare -S < %s | FileCheck %s
+; RUN: opt -lower-constant-intrinsics -S < %s | FileCheck %s
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 target triple = "x86_64-apple-darwin10.0.0"
 
+declare i64 @llvm.objectsize.i64(i8*, i1, i1, i1) nounwind readonly
+declare i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)*, i1, i1, i1) nounwind readonly
+declare void @llvm.trap() nounwind
+
 ; CHECK-LABEL: @test1(
 ; objectsize should fold to a constant, which causes the branch to fold to an
-; uncond branch. Next, we fold the control flow alltogether.
-; rdar://8785296
+; uncond branch.
 define i32 @test1(i8* %ptr) nounwind ssp noredzone align 2 {
 entry:
   %0 = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false, i1 false, i1 false)
@@ -14,7 +17,7 @@ entry:
   br i1 %1, label %T, label %trap
 
 ; CHECK: entry:
-; CHECK-NOT: br label %
+; CHECK-NOT: label %trap
 
 trap:                                             ; preds = %0, %entry
   tail call void @llvm.trap() noreturn nounwind
@@ -78,9 +81,3 @@ entry:
                                                i1 false, i1 false)
   ret i64 %0
 }
-
-
-declare i64 @llvm.objectsize.i64(i8*, i1, i1, i1) nounwind readonly
-declare i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)*, i1, i1, i1) nounwind readonly
-
-declare void @llvm.trap() nounwind

Modified: llvm/trunk/utils/gn/secondary/llvm/lib/Transforms/Scalar/BUILD.gn
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/gn/secondary/llvm/lib/Transforms/Scalar/BUILD.gn?rev=374743&r1=374742&r2=374743&view=diff
==============================================================================
--- llvm/trunk/utils/gn/secondary/llvm/lib/Transforms/Scalar/BUILD.gn (original)
+++ llvm/trunk/utils/gn/secondary/llvm/lib/Transforms/Scalar/BUILD.gn Sun Oct 13 16:00:15 2019
@@ -57,6 +57,7 @@ static_library("Scalar") {
     "LowerAtomic.cpp",
     "LowerExpectIntrinsic.cpp",
     "LowerGuardIntrinsic.cpp",
+    "LowerConstantIntrinsics.cpp",
     "LowerWidenableCondition.cpp",
     "MakeGuardsExplicit.cpp",
     "MemCpyOptimizer.cpp",




More information about the llvm-commits mailing list