[llvm] r295347 - x86 interrupt calling convention: only save xmm registers if the target supports SSE

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 16 10:25:38 PST 2017


Author: adibiagio
Date: Thu Feb 16 12:25:37 2017
New Revision: 295347

URL: http://llvm.org/viewvc/llvm-project?rev=295347&view=rev
Log:
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

Added:
    llvm/trunk/test/CodeGen/X86/x86-64-intrcc-nosse.ll
Modified:
    llvm/trunk/lib/Target/X86/X86CallingConv.td
    llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp

Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=295347&r1=295346&r2=295347&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86CallingConv.td (original)
+++ llvm/trunk/lib/Target/X86/X86CallingConv.td Thu Feb 16 12:25:37 2017
@@ -1074,6 +1074,8 @@ def CSR_32_AllRegs_AVX512 : CalleeSavedR
                                                  (sequence "K%u", 0, 7))>;
 
 def CSR_64_AllRegs     : CalleeSavedRegs<(add CSR_64_MostRegs, RAX)>;
+def CSR_64_AllRegs_NoSSE : CalleeSavedRegs<(add RAX, RBX, RCX, RDX, RSI, RDI, R8, R9,
+                                                R10, R11, R12, R13, R14, R15, RBP)>;
 def CSR_64_AllRegs_AVX : CalleeSavedRegs<(sub (add CSR_64_MostRegs, RAX,
                                                    (sequence "YMM%u", 0, 15)),
                                               (sequence "XMM%u", 0, 15))>;

Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=295347&r1=295346&r2=295347&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Thu Feb 16 12:25:37 2017
@@ -337,7 +337,9 @@ X86RegisterInfo::getCalleeSavedRegs(cons
         return CSR_64_AllRegs_AVX512_SaveList;
       if (HasAVX)
         return CSR_64_AllRegs_AVX_SaveList;
-      return CSR_64_AllRegs_SaveList;
+      if (HasSSE)
+        return CSR_64_AllRegs_SaveList;
+      return CSR_64_AllRegs_NoSSE_SaveList;
     } else {
       if (HasAVX512)
         return CSR_32_AllRegs_AVX512_SaveList;
@@ -447,7 +449,9 @@ X86RegisterInfo::getCallPreservedMask(co
         return CSR_64_AllRegs_AVX512_RegMask;
       if (HasAVX)
         return CSR_64_AllRegs_AVX_RegMask;
-      return CSR_64_AllRegs_RegMask;
+      if (HasSSE)
+        return CSR_64_AllRegs_RegMask;
+      return CSR_64_AllRegs_NoSSE_RegMask;
     } else {
       if (HasAVX512)
         return CSR_32_AllRegs_AVX512_RegMask;

Added: llvm/trunk/test/CodeGen/X86/x86-64-intrcc-nosse.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/x86-64-intrcc-nosse.ll?rev=295347&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/x86-64-intrcc-nosse.ll (added)
+++ llvm/trunk/test/CodeGen/X86/x86-64-intrcc-nosse.ll Thu Feb 16 12:25:37 2017
@@ -0,0 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=-sse < %s | FileCheck %s
+
+%struct.interrupt_frame = type { i64, i64, i64, i64, i64 }
+
+ at llvm.used = appending global [1 x i8*] [i8* bitcast (void (%struct.interrupt_frame*, i64)* @test_isr_sse_clobbers to i8*)], section "llvm.metadata"
+
+; Clobbered SSE must not be saved when the target doesn't support SSE
+define x86_intrcc void @test_isr_sse_clobbers(%struct.interrupt_frame* %frame, i64 %ecode) {
+  ; CHECK-LABEL: test_isr_sse_clobbers:
+  ; CHECK:       # BB#0:
+  ; CHECK-NEXT:    cld
+  ; CHECK-NEXT:    #APP
+  ; CHECK-NEXT:    #NO_APP
+  ; CHECK-NEXT:    addq $8, %rsp
+  ; CHECK-NEXT:    iretq
+  call void asm sideeffect "", "~{xmm0},~{xmm6}"()
+  ret void
+}




More information about the llvm-commits mailing list