Open reSHARMA opened 10 months ago
I've also reproduced the same with previous llvm versions
@llvm/issue-subscribers-backend-x86
Author: Reshabh Sharma (reSHARMA)
@dtcxzyw I was also able to reproduce this on aarch64
I've encountered the same issue on Arm. It seems related to the order of adding AAResultsWrapperPass and StackProtector in SelectionDAGISel::getAnalysisUsage(). Specifically, after the StackProtector pass is the ARMDAGToDAGISel pass, which inherits from SelectionDAGISel. In SelectionDAGISel::getAnalysisUsage(), it requires AAResultsWrapperPass and StackProtector.
void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
if (OptLevel != CodeGenOptLevel::None)
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<GCModuleInfo>();
AU.addRequired<StackProtector>();
AU.addPreserved<GCModuleInfo>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addRequired<TargetTransformInfoWrapperPass>();
AU.addRequired<AssumptionCacheTracker>();
if (UseMBPI && OptLevel != CodeGenOptLevel::None)
AU.addRequired<BranchProbabilityInfoWrapperPass>();
AU.addRequired<ProfileSummaryInfoWrapperPass>();
// AssignmentTrackingAnalysis only runs if assignment tracking is enabled for
// the module.
AU.addRequired<AssignmentTrackingAnalysis>();
AU.addPreserved<AssignmentTrackingAnalysis>();
if (OptLevel != CodeGenOptLevel::None)
LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
MachineFunctionPass::getAnalysisUsage(AU);
}
Debugging under normal conditions shows that when scheduling ARMDAGToDAGISel, the pass manager finds the AAResultsWrapperPass is not preserved, so it schedules it again. And the StackProtector pass doesn't get rescheduled because it has already been executed and preserved. If addPass(createStackProtectorPass()) is commented in TargetPassConfig::addISelPasses(), the pass manager will then schedule the StackProtector pass. However, the StackProtector pass will remove the preservation of AAResultsWrapperPass, causing ARMDAGToDAGISel to fail the requirement check for AAResultsWrapperPass later and resulting in an "Unable to schedule pass" error. Adjusting the order of AAResultsWrapperPass and StackProtector in SelectionDAGISel::getAnalysisUsage() can resolve this issue.
void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<GCModuleInfo>();
AU.addRequired<StackProtector>();
if (OptLevel != CodeGenOptLevel::None)
AU.addRequired<AAResultsWrapperPass>();
AU.addPreserved<GCModuleInfo>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addRequired<TargetTransformInfoWrapperPass>();
AU.addRequired<AssumptionCacheTracker>();
if (UseMBPI && OptLevel != CodeGenOptLevel::None)
AU.addRequired<BranchProbabilityInfoWrapperPass>();
AU.addRequired<ProfileSummaryInfoWrapperPass>();
// AssignmentTrackingAnalysis only runs if assignment tracking is enabled for
// the module.
AU.addRequired<AssignmentTrackingAnalysis>();
AU.addPreserved<AssignmentTrackingAnalysis>();
if (OptLevel != CodeGenOptLevel::None)
LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
MachineFunctionPass::getAnalysisUsage(AU);
}
However, I still don't understand the Legacy Pass Manager's mechanism. For instance, if I add a Module pass after addPass(createStackProtectorPass()), and its getAnalysisUsage() has setPreservesAll(), it also causes an "Unable to schedule pass" error. Does this mean that the Module pass automatically removes the previously preserved passes?
Clang crashes on any valid c code when StackProtectorPass is removed from the pass pipeline by commenting addPass(createStackProtectorPass()); in TargetPassConfig::addISelPrepare
Crash dump:
Preprocessed source:
Run script
It also crashes when I try to change the position of StackProtectorPass in the pipeline.