Index: llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -3152,6 +3152,18 @@ void X86AsmParser::emitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out) { Out.emitInstruction(Inst, getSTI()); + + // If this instruction loads and we're hardening for LVI, emit an LFENCE. + if (getSTI().getFeatureBits()[X86::FeatureLVILoadHardening]) { + const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); + // LFENCE has the mayLoad property, don't double fence. + if (MCID.mayLoad() && Inst.getOpcode() != X86::LFENCE) { + MCInst FenceInst; + FenceInst.setOpcode(X86::LFENCE); + FenceInst.setLoc(Inst.getLoc()); + Out.emitInstruction(FenceInst, getSTI()); + } + } } bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, Index: llvm/test/CodeGen/X86/lvi-hardening-inline-asm.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/lvi-hardening-inline-asm.ll @@ -0,0 +1,139 @@ +; RUN: llc -verify-machineinstrs -mtriple=x86_64-unknown < %s | FileCheck %s + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @test_inline_asm() #0 { +entry: +; CHECK-LABEL: test_inline_asm: + call void asm sideeffect "mov 0x3fed(%rip),%rax", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !2 +; CHECK: movq 16365(%rip), %rax +; CHECK-NEXT: lfence + call void asm sideeffect "movdqa 0x0(%rip),%xmm0", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !3 +; CHECK: movdqa (%rip), %xmm0 +; CHECK-NEXT: lfence + call void asm sideeffect "movslq 0x3e5d(%rip),%rbx", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !4 +; CHECK: movslq 15965(%rip), %rbx +; CHECK-NEXT: lfence + call void asm sideeffect "mov (%r12,%rax,8),%rax", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !5 +; CHECK: movq (%r12,%rax,8), %rax +; CHECK-NEXT: lfence + call void asm sideeffect "movq (24)(%rsi), %r11", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !6 +; CHECK: movq 24(%rsi), %r11 +; CHECK-NEXT: lfence + call void asm sideeffect "cmove %r12,%rax", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !7 +; CHECK: cmoveq %r12, %rax +; CHECK-NOT: lfence + call void asm sideeffect "cmove (%r12),%rax", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !8 +; CHECK: cmoveq (%r12), %rax +; CHECK-NEXT: lfence + call void asm sideeffect "pop %rbx", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !9 +; CHECK: popq %rbx +; CHECK-NEXT: lfence + call void asm sideeffect "popq %rbx", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !10 +; CHECK: popq %rbx +; CHECK-NEXT: lfence + call void asm sideeffect "xchg (%r12),%rax", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !11 +; CHECK: xchgq %rax, (%r12) +; CHECK-NEXT: lfence + call void asm sideeffect "cmpxchg %r12,(%rax)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !12 +; CHECK: cmpxchgq %r12, (%rax) +; CHECK-NEXT: lfence + call void asm sideeffect "vpxor (%rcx,%rdx,1),%ymm1,%ymm0", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !13 +; CHECK: vpxor (%rcx,%rdx), %ymm1, %ymm0 +; CHECK-NEXT: lfence + call void asm sideeffect "vpmuludq 0x20(%rsi),%ymm0,%ymm12", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !14 +; CHECK: vpmuludq 32(%rsi), %ymm0, %ymm12 +; CHECK-NEXT: lfence + call void asm sideeffect "vpexpandq 0x40(%rdi),%zmm8{%k2}{z}", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !15 +; CHECK: vpexpandq 64(%rdi), %zmm8 {%k2} {z} +; CHECK-NEXT: lfence + call void asm sideeffect "addq (%r12),%rax", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !16 +; CHECK: addq (%r12), %rax +; CHECK-NEXT: lfence + call void asm sideeffect "subq Lpoly+0(%rip), %rax", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !17 +; CHECK: subq Lpoly+0(%rip), %rax +; CHECK-NEXT: lfence + call void asm sideeffect "adcq %r12,(%rax)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !18 +; CHECK: adcq %r12, (%rax) +; CHECK-NEXT: lfence + call void asm sideeffect "negq (%rax)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !19 +; CHECK: negq (%rax) +; CHECK-NEXT: lfence + call void asm sideeffect "incq %rax", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !20 +; CHECK: incq %rax +; CHECK-NOT: lfence + call void asm sideeffect "mulq (%rax)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !21 +; CHECK: mulq (%rax) +; CHECK-NEXT: lfence + call void asm sideeffect "imulq (%rax),%rdx", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !22 +; CHECK: imulq (%rax), %rdx +; CHECK-NEXT: lfence + call void asm sideeffect "shlq $$1,(%rax)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !23 +; CHECK: shlq (%rax) +; CHECK-NEXT: lfence + call void asm sideeffect "shrq $$1,(%rax)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !24 +; CHECK: shrq (%rax) +; CHECK-NEXT: lfence + call void asm sideeffect "repz cmpsb %es:(%rdi),%ds:(%rsi)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !25 +; FIXME: This should emit a warning +; CHECK: rep cmpsb %es:(%rdi), %ds:(%rsi) +; CHECK-NOT: lfence + call void asm sideeffect "pinsrw $$0x6,(%eax),%xmm0", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !26 +; CHECK: pinsrw $6, (%eax), %xmm0 +; CHECK-NEXT: lfence + call void asm sideeffect "ret", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !27 +; FIXME: This should emit a warning +; CHECK: retq +; CHECK-NOT: lfence + call void asm sideeffect "ret $$8", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !28 +; FIXME: This should emit a warning +; CHECK: retq $8 + call void asm sideeffect "jmpq *(%rdx)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !29 +; FIXME: This should emit a warning + call void asm sideeffect "jmpq *0x100(%rdx)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !30 +; FIXME: This should emit a warning + call void asm sideeffect "callq *200(%rdx)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !31 +; FIXME: This should emit a warning + call void asm sideeffect "fldt 0x8(%rbp)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !32 +; CHECK: fldt 8(%rbp) +; CHECK-NEXT: lfence + call void asm sideeffect "fld %st(0)", "~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !33 +; CHECK: fld %st(0) +; CHECK-NOT: lfence + ret void +} + +attributes #0 = { "target-features"="+lvi-load-hardening" } +attributes #1 = { nounwind } + +!2 = !{i32 42} +!3 = !{i32 83} +!4 = !{i32 125} +!5 = !{i32 169} +!6 = !{i32 211} +!7 = !{i32 252} +!8 = !{i32 287} +!9 = !{i32 324} +!10 = !{i32 352} +!11 = !{i32 381} +!12 = !{i32 417} +!13 = !{i32 456} +!14 = !{i32 507} +!15 = !{i32 559} +!16 = !{i32 613} +!17 = !{i32 649} +!18 = !{i32 693} +!19 = !{i32 729} +!20 = !{i32 760} +!21 = !{i32 789} +!22 = !{i32 820} +!23 = !{i32 857} +!24 = !{i32 891} +!25 = !{i32 925} +!26 = !{i32 977} +!27 = !{i32 1021} +!28 = !{i32 1044} +!29 = !{i32 1070} +!30 = !{i32 1102} +!31 = !{i32 1139} +!32 = !{i32 1175} +!33 = !{i32 1209, i32 1222}