jyknight created this revision. jyknight added reviewers: craig.topper, spatel, RKSimon. Herald added subscribers: pengfei, hiraditya. jyknight requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
In Clang, the other "MMX" intrinsic functions are being migrated to SSE2, and will thus be usable even when compiling with -mno-mmx. These SSE2 implementations don't require the use of _mm_empty(), but existing (properly-written) code will still have calls to _mm_empty(). It's therefore desirable to make the function a no-op in this mode. The function cannot be made a no-op universally, however, because MMX may still be used by inline assembly. Therefore, have _mm_empty be usable both with and without MMX -- and emit the LLVM intrinsic in both cases, but cause the llvm intrinsic to generate an EMMS instruction only if MMX is actually enabled. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D94268 Files: clang/include/clang/Basic/BuiltinsX86.def clang/lib/Headers/mmintrin.h llvm/lib/Target/X86/X86ISelLowering.cpp llvm/test/CodeGen/X86/mmx-emms.ll Index: llvm/test/CodeGen/X86/mmx-emms.ll =================================================================== --- /dev/null +++ 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 Index: llvm/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.cpp +++ 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(); } Index: clang/lib/Headers/mmintrin.h =================================================================== --- clang/lib/Headers/mmintrin.h +++ 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 <x86intrin.h> /// /// This intrinsic corresponds to the <c> EMMS </c> instruction. /// -static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("mmx"))) +static __inline__ void __attribute__((__always_inline__, __nodebug__)) _mm_empty(void) { __builtin_ia32_emms(); Index: clang/include/clang/Basic/BuiltinsX86.def =================================================================== --- clang/include/clang/Basic/BuiltinsX86.def +++ 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")
Index: llvm/test/CodeGen/X86/mmx-emms.ll =================================================================== --- /dev/null +++ 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 Index: llvm/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.cpp +++ 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(); } Index: clang/lib/Headers/mmintrin.h =================================================================== --- clang/lib/Headers/mmintrin.h +++ 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 <x86intrin.h> /// /// This intrinsic corresponds to the <c> EMMS </c> instruction. /// -static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("mmx"))) +static __inline__ void __attribute__((__always_inline__, __nodebug__)) _mm_empty(void) { __builtin_ia32_emms(); Index: clang/include/clang/Basic/BuiltinsX86.def =================================================================== --- clang/include/clang/Basic/BuiltinsX86.def +++ 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")
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits