diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def --- a/clang/include/clang/Basic/BuiltinsX86.def +++ b/clang/include/clang/Basic/BuiltinsX86.def @@ -83,7 +83,7 @@ // MMX usage is no longer supported in Clang; all of the formerly "MMX" // intrinsic functions are now expanded into SSE2 code in the headers. -TARGET_BUILTIN(__builtin_ia32_emms, "v", "n", "mmx") +TARGET_BUILTIN(__builtin_ia32_emms, "v", "n", "") TARGET_BUILTIN(__builtin_ia32_vec_ext_v4hi, "sV4sIi", "ncV:64:", "sse") TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4ssIi", "ncV:64:", "sse") diff --git a/clang/lib/Headers/mmintrin.h b/clang/lib/Headers/mmintrin.h --- a/clang/lib/Headers/mmintrin.h +++ b/clang/lib/Headers/mmintrin.h @@ -41,14 +41,15 @@ #define __anyext128(x) (__m128i)__builtin_shufflevector((__v2si)(x), __extension__ (__v2si){}, 0, 1, -1, -1) #define __extract2_32(a) (__m64)__builtin_shufflevector((__v4si)(a), __extension__ (__v4si){}, 0, 2); -/// Clears the MMX state by setting the state of the x87 stack registers -/// to empty. +/// Clears the MMX state by setting the state of the x87 stack registers to +/// empty. This intrinsic is accepted but emits no instructions if MMX is +/// disabled at compile-time (e.g. via -mno-mmx). /// /// \headerfile /// /// This intrinsic corresponds to the EMMS instruction. /// -static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("mmx"))) +static __inline__ void __attribute__((__always_inline__, __nodebug__)) _mm_empty(void) { __builtin_ia32_emms(); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -26170,6 +26170,14 @@ return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(), SetCC, Operation.getValue(1)); } + case Intrinsic::x86_mmx_emms: { + // Emit nothing for the EMMS intrinsic when MMX is disabled. + if (!Subtarget.hasMMX()) { + SDValue Chain = Op.getOperand(0); + return Chain; + } + return SDValue(); + } } return SDValue(); } diff --git a/llvm/test/CodeGen/X86/mmx-emms.ll b/llvm/test/CodeGen/X86/mmx-emms.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/mmx-emms.ll @@ -0,0 +1,21 @@ +; RUN: llc -mcpu=i686 -mattr=+mmx < %s | FileCheck %s --check-prefixes=CHECK,CHECK-MMX +; RUN: llc -mcpu=i686 -mattr=-mmx < %s | FileCheck %s --check-prefixes=CHECK +; RUN: llc -mcpu=i686 -mattr=+sse2 < %s | FileCheck %s --check-prefixes=CHECK + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32" +target triple = "i386-pc-linux-gnu" + +;; Verify that the llvm.x86.mmx.emms intrinsic works whether or not +;; MMX is enabled, but that it doesn't emit any instructions if mmx is +;; disabled. + +;; CHECK-LABEL: mmx_emms: +;; CHECK: # %bb.0: +;; CHECK-MMX-NEXT: emms +;; CHECK-NEXT: retl +define void @mmx_emms() { + tail call void @llvm.x86.mmx.emms() nounwind + ret void +} + +declare void @llvm.x86.mmx.emms() nounwind