diff --git a/llvm/lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp b/llvm/lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp --- a/llvm/lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp +++ b/llvm/lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp @@ -60,6 +60,11 @@ cl::desc("Don't LFENCE in basic blocks with one load and no stores."), cl::init(false), cl::Hidden); +static cl::opt LFENCEDataInvariantInstructions( + "x86-seses-lfence-data-invariant-inst", + cl::desc("LFENCE before instructions that are data invariant."), + cl::init(true), cl::Hidden); + static bool hasConstantAddressingMode(const MachineInstr &MI); namespace { @@ -119,6 +124,13 @@ MachineInstr *FirstTerminator = nullptr; for (auto &MI : MBB) { + // If the current instruction is data invariant and we are not LFENCEing + // data invariant instructions, then continue to the next instruction. + if (!LFENCEDataInvariantInstructions && + (TII->isDataInvariant(MI) || TII->isDataInvariantLoad(MI))) { + continue; + } + // We want to put an LFENCE before any instruction that // may load or store. This LFENCE is intended to avoid leaking any secret // data due to a given load or store. This results in closing the cache