diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 22 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 14 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/TargetPassConfig.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/Passes/PassBuilder.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Passes/PassRegistry.def | 1 | ||||
| -rw-r--r-- | llvm/lib/Transforms/IPO/PassManagerBuilder.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp | 170 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/Scalar.cpp | 5 |
11 files changed, 67 insertions, 199 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 061c8e51a99..0594d5fe1b1 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -1868,10 +1868,24 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool &ModifiedDT) { }); 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::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::aarch64_stlxr: case Intrinsic::aarch64_stxr: { ZExtInst *ExtVal = dyn_cast<ZExtInst>(CI->getArgOperand(0)); diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 1d1eea4d23d..08f3e4f5bd3 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1437,12 +1437,18 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, MIRBuilder.buildConstant(Reg, TypeID); return true; } - case Intrinsic::objectsize: - llvm_unreachable("llvm.objectsize.* should have been lowered already"); + case Intrinsic::objectsize: { + // If we don't know by now, we're never going to know. + const ConstantInt *Min = cast<ConstantInt>(CI.getArgOperand(1)); + MIRBuilder.buildConstant(getOrCreateVReg(CI), Min->isZero() ? -1ULL : 0); + return true; + } case Intrinsic::is_constant: - llvm_unreachable("llvm.is.constant.* should have been lowered already"); - + // If this wasn't constant-folded away by now, then it's not a + // constant. + MIRBuilder.buildConstant(getOrCreateVReg(CI), 0); + return true; case Intrinsic::stackguard: getStackGuard(getOrCreateVReg(CI), MIRBuilder); return true; diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 347776b2367..0fd2bd7815b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1454,12 +1454,24 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) { TII.get(TargetOpcode::DBG_LABEL)).addMetadata(DI->getLabel()); 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::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::launder_invariant_group: case Intrinsic::strip_invariant_group: case Intrinsic::expect: { diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 9a29a010c14..3c36cc6f659 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6388,11 +6388,29 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, DAG.setRoot(Res); return; } - case Intrinsic::objectsize: - llvm_unreachable("llvm.objectsize.* should have been lowered already"); + 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::is_constant: - llvm_unreachable("llvm.is.constant.* should have been lowered already"); + // If this wasn't constant-folded away by now, then it's not a + // constant. + setValue(&I, DAG.getConstant(0, sdl, MVT::i1)); + return; case Intrinsic::annotation: case Intrinsic::ptr_annotation: diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp index f1f4f65adf7..ba780e718bb 100644 --- a/llvm/lib/CodeGen/TargetPassConfig.cpp +++ b/llvm/lib/CodeGen/TargetPassConfig.cpp @@ -657,7 +657,6 @@ 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()); diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 25558e1b514..bfa3ecfb280 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -142,7 +142,6 @@ #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" @@ -892,8 +891,6 @@ ModulePassManager PassBuilder::buildModuleOptimizationPipeline( 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. diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 1fa274d172b..eb350cb665f 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -187,7 +187,6 @@ FUNCTION_PASS("libcalls-shrinkwrap", LibCallsShrinkWrapPass()) 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()) diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp index 5314a8219b1..3ea77f08fd3 100644 --- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -654,7 +654,6 @@ void PassManagerBuilder::populateModulePassManager( MPM.add(createGlobalsAAWrapperPass()); MPM.add(createFloat2IntPass()); - MPM.add(createLowerConstantIntrinsicsPass()); addExtensionsToPM(EP_VectorizerStart, MPM); diff --git a/llvm/lib/Transforms/Scalar/CMakeLists.txt b/llvm/lib/Transforms/Scalar/CMakeLists.txt index 89c2faebfbc..e6f8901ec81 100644 --- a/llvm/lib/Transforms/Scalar/CMakeLists.txt +++ b/llvm/lib/Transforms/Scalar/CMakeLists.txt @@ -44,7 +44,6 @@ add_llvm_library(LLVMScalarOpts LoopUnswitch.cpp LoopVersioningLICM.cpp LowerAtomic.cpp - LowerConstantIntrinsics.cpp LowerExpectIntrinsic.cpp LowerGuardIntrinsic.cpp LowerWidenableCondition.cpp diff --git a/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp b/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp deleted file mode 100644 index d0fcf38b5a7..00000000000 --- a/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp +++ /dev/null @@ -1,170 +0,0 @@ -//===- 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(); -} diff --git a/llvm/lib/Transforms/Scalar/Scalar.cpp b/llvm/lib/Transforms/Scalar/Scalar.cpp index 1d2e40bf62b..688b8b9079e 100644 --- a/llvm/lib/Transforms/Scalar/Scalar.cpp +++ b/llvm/lib/Transforms/Scalar/Scalar.cpp @@ -79,7 +79,6 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) { initializeLoopVersioningLICMPass(Registry); initializeLoopIdiomRecognizeLegacyPassPass(Registry); initializeLowerAtomicLegacyPassPass(Registry); - initializeLowerConstantIntrinsicsPass(Registry); initializeLowerExpectIntrinsicPass(Registry); initializeLowerGuardIntrinsicLegacyPassPass(Registry); initializeLowerWidenableConditionLegacyPassPass(Registry); @@ -285,10 +284,6 @@ void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createBasicAAWrapperPass()); } -void LLVMAddLowerConstantIntrinsicsPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createLowerConstantIntrinsicsPass()); -} - void LLVMAddLowerExpectIntrinsicPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createLowerExpectIntrinsicPass()); } |

