Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit aa2ae0a

Browse files
adibiagioTimNN
authored andcommitted
x86 interrupt calling convention: only save xmm registers if the target supports SSE
The existing code always saves the xmm registers for 64-bit targets even if the target doesn't support SSE (which is common for kernels). Thus, the compiler inserts movaps instructions which lead to CPU exceptions when an interrupt handler is invoked. This commit fixes this bug by returning a register set without xmm registers from getCalleeSavedRegs and getCallPreservedMask for such targets. Patch by Philipp Oppermann. Differential Revision: https://reviews.llvm.org/D29959 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@295347 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 5c67756 commit aa2ae0a

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

lib/Target/X86/X86CallingConv.td

+2
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,8 @@ def CSR_32_AllRegs_AVX512 : CalleeSavedRegs<(add CSR_32_AllRegs,
10741074
(sequence "K%u", 0, 7))>;
10751075

10761076
def CSR_64_AllRegs : CalleeSavedRegs<(add CSR_64_MostRegs, RAX)>;
1077+
def CSR_64_AllRegs_NoSSE : CalleeSavedRegs<(add RAX, RBX, RCX, RDX, RSI, RDI, R8, R9,
1078+
R10, R11, R12, R13, R14, R15, RBP)>;
10771079
def CSR_64_AllRegs_AVX : CalleeSavedRegs<(sub (add CSR_64_MostRegs, RAX,
10781080
(sequence "YMM%u", 0, 15)),
10791081
(sequence "XMM%u", 0, 15))>;

lib/Target/X86/X86RegisterInfo.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,9 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
337337
return CSR_64_AllRegs_AVX512_SaveList;
338338
if (HasAVX)
339339
return CSR_64_AllRegs_AVX_SaveList;
340-
return CSR_64_AllRegs_SaveList;
340+
if (HasSSE)
341+
return CSR_64_AllRegs_SaveList;
342+
return CSR_64_AllRegs_NoSSE_SaveList;
341343
} else {
342344
if (HasAVX512)
343345
return CSR_32_AllRegs_AVX512_SaveList;
@@ -447,7 +449,9 @@ X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
447449
return CSR_64_AllRegs_AVX512_RegMask;
448450
if (HasAVX)
449451
return CSR_64_AllRegs_AVX_RegMask;
450-
return CSR_64_AllRegs_RegMask;
452+
if (HasSSE)
453+
return CSR_64_AllRegs_RegMask;
454+
return CSR_64_AllRegs_NoSSE_RegMask;
451455
} else {
452456
if (HasAVX512)
453457
return CSR_32_AllRegs_AVX512_RegMask;
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=-sse < %s | FileCheck %s
3+
4+
%struct.interrupt_frame = type { i64, i64, i64, i64, i64 }
5+
6+
@llvm.used = appending global [1 x i8*] [i8* bitcast (void (%struct.interrupt_frame*, i64)* @test_isr_sse_clobbers to i8*)], section "llvm.metadata"
7+
8+
; Clobbered SSE must not be saved when the target doesn't support SSE
9+
define x86_intrcc void @test_isr_sse_clobbers(%struct.interrupt_frame* %frame, i64 %ecode) {
10+
; CHECK-LABEL: test_isr_sse_clobbers:
11+
; CHECK: # BB#0:
12+
; CHECK-NEXT: cld
13+
; CHECK-NEXT: #APP
14+
; CHECK-NEXT: #NO_APP
15+
; CHECK-NEXT: addq $8, %rsp
16+
; CHECK-NEXT: iretq
17+
call void asm sideeffect "", "~{xmm0},~{xmm6}"()
18+
ret void
19+
}

0 commit comments

Comments
 (0)