Skip to content

[CodeGen] Merge lowerConstantIntrinsics into pre-isel lowering #97727

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions llvm/include/llvm/LinkAllPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ namespace {
(void) llvm::createLoopExtractorPass();
(void) llvm::createLoopSimplifyPass();
(void) llvm::createLoopStrengthReducePass();
(void) llvm::createLoopUnrollPass();
(void) llvm::createLowerConstantIntrinsicsPass();
(void)llvm::createLoopUnrollPass();
(void) llvm::createLowerGlobalDtorsLegacyPass();
(void) llvm::createLowerInvokePass();
(void) llvm::createLowerSwitchPass();
Expand Down
7 changes: 0 additions & 7 deletions llvm/include/llvm/Transforms/Scalar.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,6 @@ extern char &InferAddressSpacesID;
//
FunctionPass *createTLSVariableHoistPass();

//===----------------------------------------------------------------------===//
//
// 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
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/Transforms/Scalar/LowerConstantIntrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@

namespace llvm {

class DominatorTree;
class Function;
class TargetLibraryInfo;

bool lowerConstantIntrinsics(Function &F, const TargetLibraryInfo &TLI,
DominatorTree *DT);

struct LowerConstantIntrinsicsPass :
PassInfoMixin<LowerConstantIntrinsicsPass> {
Expand Down
50 changes: 47 additions & 3 deletions llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
#include "llvm/Analysis/ObjCARCInstKind.h"
#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetLowering.h"
Expand All @@ -24,10 +25,12 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"

using namespace llvm;
Expand All @@ -45,6 +48,7 @@ namespace {
struct PreISelIntrinsicLowering {
const TargetMachine &TM;
const function_ref<TargetTransformInfo &(Function &)> LookupTTI;
const function_ref<TargetLibraryInfo &(Function &)> LookupTLI;

/// If this is true, assume it's preferably to leave memory intrinsic calls
/// for replacement with a library call later. Otherwise this depends on
Expand All @@ -54,8 +58,9 @@ struct PreISelIntrinsicLowering {
explicit PreISelIntrinsicLowering(
const TargetMachine &TM_,
function_ref<TargetTransformInfo &(Function &)> LookupTTI_,
function_ref<TargetLibraryInfo &(Function &)> LookupTLI_,
bool UseMemIntrinsicLibFunc_ = true)
: TM(TM_), LookupTTI(LookupTTI_),
: TM(TM_), LookupTTI(LookupTTI_), LookupTLI(LookupTLI_),
UseMemIntrinsicLibFunc(UseMemIntrinsicLibFunc_) {}

static bool shouldExpandMemIntrinsicWithSize(Value *Size,
Expand All @@ -66,6 +71,27 @@ struct PreISelIntrinsicLowering {

} // namespace

template <class T> static bool forEachCall(Function &Intrin, T Callback) {
// Lowering all intrinsics in a function will delete multiple uses, so we
// can't use an early-inc-range. In case some remain, we don't want to look
// at them again. Unfortunately, Value::UseList is private, so we can't use a
// simple Use**. If LastUse is null, the next use to consider is
// Intrin.use_begin(), otherwise it's LastUse->getNext().
Use *LastUse = nullptr;
bool Changed = false;
while (!Intrin.use_empty() && (!LastUse || LastUse->getNext())) {
Use *U = LastUse ? LastUse->getNext() : &*Intrin.use_begin();
bool Removed = false;
// An intrinsic cannot have its address taken, so it cannot be an argument
// operand. It might be used as operand in debug metadata, though.
if (auto CI = dyn_cast<CallInst>(U->getUser()))
Changed |= Removed = Callback(CI);
if (!Removed)
LastUse = U;
}
return Changed;
}

static bool lowerLoadRelative(Function &F) {
if (F.use_empty())
return false;
Expand Down Expand Up @@ -285,6 +311,16 @@ bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
case Intrinsic::load_relative:
Changed |= lowerLoadRelative(F);
break;
case Intrinsic::is_constant:
case Intrinsic::objectsize:
Changed |= forEachCall(F, [&](CallInst *CI) {
Function *Parent = CI->getParent()->getParent();
TargetLibraryInfo &TLI = LookupTLI(*Parent);
bool Changed = lowerConstantIntrinsics(*Parent, TLI, /*DT=*/nullptr);
assert(Changed && "lowerConstantIntrinsics did not lower intrinsic");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assert fails for input like this

define void @bbi_97828() {
  ret void

dead:
  %x = call i32 @llvm.objectsize.i32.p21(ptr addrspace(21) null, i1 false, i1 false, i1 false)
  br label %dead
}

since lowerConstantIntrinsics is doing an RPOT traversal to find out which intrinsics to lower. So it may fail to find CI, and then there is no changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Opened #102442 to remove the assertion and add a test case.

return Changed;
});
break;
case Intrinsic::objc_autorelease:
Changed |= lowerObjCCall(F, "objc_autorelease");
break;
Expand Down Expand Up @@ -375,16 +411,20 @@ class PreISelIntrinsicLoweringLegacyPass : public ModulePass {

void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<TargetTransformInfoWrapperPass>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addRequired<TargetPassConfig>();
}

bool runOnModule(Module &M) override {
auto LookupTTI = [this](Function &F) -> TargetTransformInfo & {
return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
};
auto LookupTLI = [this](Function &F) -> TargetLibraryInfo & {
return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
};

const auto &TM = getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
PreISelIntrinsicLowering Lowering(TM, LookupTTI);
PreISelIntrinsicLowering Lowering(TM, LookupTTI, LookupTLI);
return Lowering.lowerIntrinsics(M);
}
};
Expand All @@ -396,6 +436,7 @@ char PreISelIntrinsicLoweringLegacyPass::ID;
INITIALIZE_PASS_BEGIN(PreISelIntrinsicLoweringLegacyPass,
"pre-isel-intrinsic-lowering",
"Pre-ISel Intrinsic Lowering", false, false)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_END(PreISelIntrinsicLoweringLegacyPass,
Expand All @@ -413,8 +454,11 @@ PreservedAnalyses PreISelIntrinsicLoweringPass::run(Module &M,
auto LookupTTI = [&FAM](Function &F) -> TargetTransformInfo & {
return FAM.getResult<TargetIRAnalysis>(F);
};
auto LookupTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
return FAM.getResult<TargetLibraryAnalysis>(F);
};

PreISelIntrinsicLowering Lowering(TM, LookupTTI);
PreISelIntrinsicLowering Lowering(TM, LookupTTI, LookupTLI);
if (!Lowering.lowerIntrinsics(M))
return PreservedAnalyses::all();
else
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/CodeGen/TargetPassConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,6 @@ void TargetPassConfig::addIRPasses() {
// TODO: add a pass insertion point here
addPass(&GCLoweringID);
addPass(&ShadowStackGCLoweringID);
addPass(createLowerConstantIntrinsicsPass());

// For MachO, lower @llvm.global_dtors into @llvm.global_ctors with
// __cxa_atexit() calls to avoid emitting the deprecated __mod_term_func.
Expand Down
46 changes: 2 additions & 44 deletions llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ static bool replaceConditionalBranchesOnConstant(Instruction *II,
return HasDeadBlocks;
}

static bool lowerConstantIntrinsics(Function &F, const TargetLibraryInfo &TLI,
DominatorTree *DT) {
bool llvm::lowerConstantIntrinsics(Function &F, const TargetLibraryInfo &TLI,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is still doing an RPOT traversal, although the commit message says that we now avoid the RPOT traversal. Is that intentional?

I guess the goal was to call lowerIsConstantIntrisic and lowerObjectSizeCall directly from pre-isel-lowering, rather than running lowerConstantIntrinsics for each such call in the function?

I think it is really weird to call this helper multiple times for the same function. Right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

although the commit message says that we now avoid the RPOT traversal. Is that intentional?

Yes. For most functions, the RPOT is avoided, because they have no constant intrinsics. If a function has constant intrinsics, it still does a RPOT.

I think it is really weird to call this helper multiple times for the same function. Right?

This function is called once per function (well, except for the degenerate case you point out below...): here we (somewhat) iterate over the uses, and when we find one, we lower all intrinsic calls in the function. These are then no longer in the use list, the next use is in a different function.

Copy link
Collaborator

@bjope bjope Aug 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, right. So PreISelIntrinsicLowering::lowerIntrinsics is iterating over used intrinsic functions. And then the forEachCall thing is finding out in which functions that the intrinsic is called. That way you avoid doing the RPO scanning for every function in the module.

Just a little bit weird that there is a dependency, that the switch in PreISelIntrinsicLowering::lowerIntrinsics for example may trigger on Intrinsic::objectsize, and then the calls to llvm::lowerConstantIntrinsics may lower lots of other instrinsics, and even remove dead code, as a "side-effect". There is no clear correspondance/correlation between what llvm::lowerConstantIntrinsics is doing and what is switched on in PreISelIntrinsicLowering::lowerIntrinsics.

DominatorTree *DT) {
std::optional<DomTreeUpdater> DTU;
if (DT)
DTU.emplace(DT, DomTreeUpdater::UpdateStrategy::Lazy);
Expand Down Expand Up @@ -165,45 +165,3 @@ LowerConstantIntrinsicsPass::run(Function &F, FunctionAnalysisManager &AM) {

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 complements the normal constant 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 {
const TargetLibraryInfo &TLI =
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
DominatorTree *DT = nullptr;
if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
DT = &DTWP->getDomTree();
return lowerConstantIntrinsics(F, TLI, DT);
}

void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
}
};
} // namespace

char LowerConstantIntrinsics::ID = 0;
INITIALIZE_PASS_BEGIN(LowerConstantIntrinsics, "lower-constant-intrinsics",
"Lower constant intrinsics", false, false)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_END(LowerConstantIntrinsics, "lower-constant-intrinsics",
"Lower constant intrinsics", false, false)

FunctionPass *llvm::createLowerConstantIntrinsicsPass() {
return new LowerConstantIntrinsics();
}
1 change: 0 additions & 1 deletion llvm/lib/Transforms/Scalar/Scalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
initializeLoopStrengthReducePass(Registry);
initializeLoopUnrollPass(Registry);
initializeLowerAtomicLegacyPassPass(Registry);
initializeLowerConstantIntrinsicsPass(Registry);
initializeMergeICmpsLegacyPassPass(Registry);
initializeNaryReassociateLegacyPassPass(Registry);
initializePartiallyInlineLibCallsLegacyPassPass(Registry);
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/AArch64/O0-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
; 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: Expand vector predication intrinsics
; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining)
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/AArch64/O3-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
; 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: Natural Loop Information
; CHECK-NEXT: Post-Dominator Tree Construction
Expand Down
5 changes: 0 additions & 5 deletions llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
; GCN-O0-NEXT: Lower uses of LDS variables from non-kernel functions
; GCN-O0-NEXT: FunctionPass Manager
; GCN-O0-NEXT: Expand Atomic instructions
; GCN-O0-NEXT: Lower constant intrinsics
; GCN-O0-NEXT: Remove unreachable blocks from the CFG
; GCN-O0-NEXT: Expand vector predication intrinsics
; GCN-O0-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining)
Expand Down Expand Up @@ -218,7 +217,6 @@
; GCN-O1-NEXT: Lazy Branch Probability Analysis
; GCN-O1-NEXT: Lazy Block Frequency Analysis
; GCN-O1-NEXT: Expand memcmp() to load/stores
; GCN-O1-NEXT: Lower constant intrinsics
; GCN-O1-NEXT: Remove unreachable blocks from the CFG
; GCN-O1-NEXT: Natural Loop Information
; GCN-O1-NEXT: Post-Dominator Tree Construction
Expand Down Expand Up @@ -508,7 +506,6 @@
; GCN-O1-OPTS-NEXT: Lazy Branch Probability Analysis
; GCN-O1-OPTS-NEXT: Lazy Block Frequency Analysis
; GCN-O1-OPTS-NEXT: Expand memcmp() to load/stores
; GCN-O1-OPTS-NEXT: Lower constant intrinsics
; GCN-O1-OPTS-NEXT: Remove unreachable blocks from the CFG
; GCN-O1-OPTS-NEXT: Natural Loop Information
; GCN-O1-OPTS-NEXT: Post-Dominator Tree Construction
Expand Down Expand Up @@ -817,7 +814,6 @@
; GCN-O2-NEXT: Lazy Branch Probability Analysis
; GCN-O2-NEXT: Lazy Block Frequency Analysis
; GCN-O2-NEXT: Expand memcmp() to load/stores
; GCN-O2-NEXT: Lower constant intrinsics
; GCN-O2-NEXT: Remove unreachable blocks from the CFG
; GCN-O2-NEXT: Natural Loop Information
; GCN-O2-NEXT: Post-Dominator Tree Construction
Expand Down Expand Up @@ -1134,7 +1130,6 @@
; GCN-O3-NEXT: Lazy Branch Probability Analysis
; GCN-O3-NEXT: Lazy Block Frequency Analysis
; GCN-O3-NEXT: Expand memcmp() to load/stores
; GCN-O3-NEXT: Lower constant intrinsics
; GCN-O3-NEXT: Remove unreachable blocks from the CFG
; GCN-O3-NEXT: Natural Loop Information
; GCN-O3-NEXT: Post-Dominator Tree Construction
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/ARM/O3-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
; 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: Natural Loop Information
; CHECK-NEXT: Post-Dominator Tree Construction
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/LoongArch/O0-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
; 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: Expand vector predication intrinsics
; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining)
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/LoongArch/opt-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
; LAXX-NEXT: Expand memcmp() to load/stores
; LAXX-NEXT: Lower Garbage Collection Instructions
; LAXX-NEXT: Shadow Stack GC Lowering
; LAXX-NEXT: Lower constant intrinsics
; LAXX-NEXT: Remove unreachable blocks from the CFG
; LAXX-NEXT: Natural Loop Information
; LAXX-NEXT: Post-Dominator Tree Construction
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/PowerPC/O0-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
; 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: Expand vector predication intrinsics
; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining)
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/PowerPC/O3-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
; 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: Natural Loop Information
; CHECK-NEXT: Post-Dominator Tree Construction
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/RISCV/O0-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
; 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: Expand vector predication intrinsics
; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining)
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/RISCV/O3-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
; 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: Natural Loop Information
; CHECK-NEXT: Post-Dominator Tree Construction
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/X86/O0-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
; 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: Expand vector predication intrinsics
; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining)
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/X86/opt-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
; 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: Natural Loop Information
; CHECK-NEXT: Post-Dominator Tree Construction
Expand Down
Loading