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 @@ -50,6 +50,11 @@ cl::desc("Omit all lfences before branch instructions."), cl::init(false), cl::Hidden); +static cl::opt + OmitLFENCEInBasicBlocksWithoutLoads("x86-seses-omit-lfence-in-bb-without-loads", + cl::desc("Omit LFENCE in basic blocks without any loads even if there are stores."), + cl::init(false), cl::Hidden); + static bool hasConstantAddressingMode(const MachineInstr &MI); namespace { @@ -81,6 +86,20 @@ const X86Subtarget &Subtarget = MF.getSubtarget(); const X86InstrInfo *TII = Subtarget.getInstrInfo(); for (MachineBasicBlock &MBB : MF) { + if (OmitLFENCEInBasicBlocksWithoutLoads) { + + bool FoundLoad = false; + for (const MachineInstr &MI : MBB) { + if (MI.mayLoad()) { + FoundLoad = true; + break; + } + } + if (!FoundLoad) { + continue; + } + } + MachineInstr *FirstTerminator = nullptr; for (auto &MI : MBB) { diff --git a/llvm/test/CodeGen/X86/speculative-execution-side-effect-suppression-omit-lfence-in-bb-without-loads.ll b/llvm/test/CodeGen/X86/speculative-execution-side-effect-suppression-omit-lfence-in-bb-without-loads.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/speculative-execution-side-effect-suppression-omit-lfence-in-bb-without-loads.ll @@ -0,0 +1,41 @@ +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -x86-seses-enable -x86-seses-omit-lfence-in-bb-without-loads %s -o - | FileCheck %s --check-prefix=CHECK-FLAGGED +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -x86-seses-enable %s -o - | FileCheck %s --check-prefix=CHECK-FULL + +define dso_local void @_Z4buzzv() { +entry: + %a = alloca i32, align 4 + store i32 10, i32* %a, align 4 + ret void +} + +; CHECK-FLAGGED: .globl _Z4buzzv # -- Begin function _Z4buzzv +; CHECK-FLAGGED: .p2align 4, 0x90 +; CHECK-FLAGGED: .type _Z4buzzv,@function +; CHECK-FLAGGED:_Z4buzzv: # @_Z4buzzv +; CHECK-FLAGGED:.L_Z4buzzv$local: +; CHECK-FLAGGED: .cfi_startproc +; CHECK-FLAGGED:# %bb.0: # %entry +; CHECK-FLAGGED: movl $10, -4(%rsp) +; CHECK-FLAGGED: retq +; CHECK-FLAGGED:.Lfunc_end0: +; CHECK-FLAGGED: .size _Z4buzzv, .Lfunc_end0-_Z4buzzv +; CHECK-FLAGGED: .cfi_endproc +; CHECK-FLAGGED: # -- End function +; CHECK-FLAGGED: .section ".note.GNU-stack","",@progbits + + +; CHECK-FULL: .globl _Z4buzzv # -- Begin function _Z4buzzv +; CHECK-FULL: .p2align 4, 0x90 +; CHECK-FULL: .type _Z4buzzv,@function +; CHECK-FULL:_Z4buzzv: # @_Z4buzzv +; CHECK-FULL:.L_Z4buzzv$local: +; CHECK-FULL: .cfi_startproc +; CHECK-FULL:# %bb.0: # %entry +; CHECK-FULL: lfence +; CHECK-FULL: movl $10, -4(%rsp) +; CHECK-FULL: retq +; CHECK-FULL:.Lfunc_end0: +; CHECK-FULL: .size _Z4buzzv, .Lfunc_end0-_Z4buzzv +; CHECK-FULL: .cfi_endproc +; CHECK-FULL: # -- End function +; CHECK-FULL: .section ".note.GNU-stack","",@progbits