Index: lib/Target/X86/X86VZeroUpper.cpp =================================================================== --- lib/Target/X86/X86VZeroUpper.cpp +++ lib/Target/X86/X86VZeroUpper.cpp @@ -80,6 +80,7 @@ BlockStateMap BlockStates; DirtySuccessorsWorkList DirtySuccessors; bool EverMadeChange; + bool IsX86INTR; const TargetInstrInfo *TII; static char ID; @@ -181,7 +182,9 @@ for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) { MachineInstr *MI = I; - bool isControlFlow = MI->isCall() || MI->isReturn(); + // No need for vzeroupper before iret in interrupt handler function, + // epilogue will restore YMM registers if needed. + bool isControlFlow = MI->isCall() || (MI->isReturn() && !IsX86INTR); // Shortcut: don't need to check regular instructions in dirty state. if (!isControlFlow && CurState == EXITS_DIRTY) @@ -253,6 +256,7 @@ TII = ST.getInstrInfo(); MachineRegisterInfo &MRI = MF.getRegInfo(); EverMadeChange = false; + IsX86INTR = MF.getFunction()->getCallingConv() == CallingConv::X86_INTR; bool FnHasLiveInYmm = checkFnHasLiveInYmm(MRI); Index: test/CodeGen/X86/x86-interrupt_vzeroupper.ll =================================================================== --- test/CodeGen/X86/x86-interrupt_vzeroupper.ll +++ test/CodeGen/X86/x86-interrupt_vzeroupper.ll @@ -0,0 +1,41 @@ +; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Checks that interrupt handler code does not call "vzeroupper" instruction +;; before iret. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Command line: -Wall -march=nehalem -S -o - -emit-llvm -O2 +;; Source: +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;extern void foo (void *) __attribute__ ((interrupt)); +;;extern void bar (void); +;; +;;void foo (void *frame) +;;{ +;; bar (); +;;} +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; CHECK: vzeroupper +; CHECK-NEXT: call +; CHECK-NOT: vzeroupper +; CHECK: iret + +@llvm.used = appending global [1 x i8*] [i8* bitcast (void (i8*)* @foo to i8*)], section "llvm.metadata" + +; Function Attrs: nounwind uwtable +define x86_intrcc void @foo(i8* nocapture readnone %frame) #0 { +entry: + tail call void @bar() #2 + ret void +} + +declare void @bar() #1 + +attributes #0 = { nounwind uwtable "disable-tail-calls"="true" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "stackrealign" "target-cpu"="nehalem" "target-features"="+avx,+cx16,+fxsr,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+xsave,-3dnow,-3dnowa,-mmx" "unsafe-fp-math"="false" "use-soft-float"="true" } +attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="nehalem" "target-features"="+avx,+cx16,+fxsr,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+xsave" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind } + +!llvm.ident = !{!0} + +!0 = !{!"clang version 3.9.0 (trunk 259349) (llvm/trunk 259357)"}