SelectionDAG implements an optimization for stack-protector which causes the StackProtector pass to only insert prologue instrumentation but generating epilogue instrumentation is deferred to SelectionDAG.
The StackProtector pass does the same for GlobalISel but this selection framework currently does not implement the same optimization as SelectionDAG which means no epilogue instrumentation gets inserted by the compiler. This primarily affects AArch64 at -O0 because this configuration enables GlobalISel by default.
The proposed patch fixes the immediate problem by having the StackProtector pass generate the epilogue instrumentation when GlobalISel is enabled, similarly to what is done when FastISel is active.
Notes:
- The patch changes meaning of TargetOptions::EnableGlobalISel. The flag was previously set only when a target switched on GlobalISel but it is now always set when the GlobalISel pipeline is enabled. This makes the flag consistent with TargetOptions::EnableFastISel and allows its use in StackProtector to determine when GlobalISel is enabled.
The EnableGlobalISel flag had previouly only one use in TargetPassConfig::isGlobalISelAbortEnabled(). The method used its value to determine whether GlobalISel was enabled by a target and returned false in such a case. To preserve the current behaviour, a new flag TargetOptions::GlobalISelAbort is introduced to separately record the abort behaviour.
- StackProtector::InsertStackProtectors() is updated to find a stack guard slot by searching for the llvm.stackprotector intrinsic when the prologue was not created by StackProtector itself but the pass still needs to generate the epilogue instrumentation. This fixes a problem when the pass would abort because the stack guard AllocInst pointer was null when generating the epilogue. This was hit by test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-stackprotect.ll.