[CMake] Detect SSE2 at compile time
https://bugs.webkit.org/show_bug.cgi?id=196488

Patch by Xan López <xan@igalia.com> on 2019-05-09
Reviewed by Carlos Garcia Campos.

.:

* Source/cmake/DetectSSE2.cmake: Added.
* Source/cmake/WebKitCompilerFlags.cmake: Detect SSE2 support and
add SSE2 to the global compiler flags.

Source/JavaScriptCore:

* assembler/MacroAssemblerX86Common.cpp: Remove unnecessary (and
incorrect) static_assert.
(JSC::MacroAssemblerX86Common::collectCPUFeatures):
* assembler/MacroAssemblerX86Common.h: Remove SSE2 flags.

Tools:

* Scripts/webkitdirs.pm:
(generateBuildSystemFromCMakeProject): Do not add SSE2 flags here
for x86 builds. This is now handled in WebKitCompilerFlags.cmake.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245127 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/ChangeLog b/ChangeLog
index 21aca778..0d5cfe4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2019-05-09  Xan López  <xan@igalia.com>
+
+        [CMake] Detect SSE2 at compile time
+        https://bugs.webkit.org/show_bug.cgi?id=196488
+
+        Reviewed by Carlos Garcia Campos.
+
+        * Source/cmake/DetectSSE2.cmake: Added.
+        * Source/cmake/WebKitCompilerFlags.cmake: Detect SSE2 support and
+        add SSE2 to the global compiler flags.
+
 2019-05-08  Don Olmstead  <don.olmstead@sony.com>
 
         [PlayStation] Update port options
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index d28ce69..6caacc0 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,15 @@
+2019-05-09  Xan López  <xan@igalia.com>
+
+        [CMake] Detect SSE2 at compile time
+        https://bugs.webkit.org/show_bug.cgi?id=196488
+
+        Reviewed by Carlos Garcia Campos.
+
+        * assembler/MacroAssemblerX86Common.cpp: Remove unnecessary (and
+        incorrect) static_assert.
+        (JSC::MacroAssemblerX86Common::collectCPUFeatures):
+        * assembler/MacroAssemblerX86Common.h: Remove SSE2 flags.
+
 2019-05-08  Yusuke Suzuki  <ysuzuki@apple.com>
 
         Unreviewed, build fix after r245064
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp
index 3175358..8c752c0 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp
@@ -168,11 +168,6 @@
 static_assert(sizeof(Probe::State) == PROBE_SIZE, "Probe::State::size's matches ctiMasmProbeTrampoline");
 static_assert((PROBE_EXECUTOR_OFFSET + PTR_SIZE) <= (PROBE_SIZE + OUT_SIZE), "Must have room after ProbeContext to stash the probe handler");
 
-#if CPU(X86)
-// SSE2 is a hard requirement on x86.
-static_assert(isSSE2Present(), "SSE2 support is required in JavaScriptCore");
-#endif
-
 #undef PROBE_OFFSETOF
 
 #if CPU(X86)
@@ -792,7 +787,6 @@
     std::call_once(onceKey, [] {
         {
             CPUID cpuid = getCPUID(0x1);
-            s_sse2CheckState = (cpuid[3] & (1 << 26)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
             s_sse4_1CheckState = (cpuid[2] & (1 << 19)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
             s_sse4_2CheckState = (cpuid[2] & (1 << 20)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
             s_popcntCheckState = (cpuid[2] & (1 << 23)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
@@ -809,7 +803,6 @@
     });
 }
 
-MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_sse2CheckState = CPUIDCheckState::NotChecked;
 MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_sse4_1CheckState = CPUIDCheckState::NotChecked;
 MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_sse4_2CheckState = CPUIDCheckState::NotChecked;
 MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_avxCheckState = CPUIDCheckState::NotChecked;
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
index 097bcb0..ff09729 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
@@ -4197,41 +4197,11 @@
     }
 #endif
 
-#if CPU(X86)
-#if OS(MAC_OS_X)
-
-    // All X86 Macs are guaranteed to support at least SSE2,
-    static bool isSSE2Present()
-    {
-        return true;
-    }
-
-#else // OS(MAC_OS_X)
-    static bool isSSE2Present()
-    {
-        if (s_sse2CheckState == CPUIDCheckState::NotChecked)
-            collectCPUFeatures();
-        return s_sse2CheckState == CPUIDCheckState::Set;
-    }
-
-#endif // OS(MAC_OS_X)
-#elif !defined(NDEBUG) // CPU(X86)
-
-    // On x86-64 we should never be checking for SSE2 in a non-debug build,
-    // but non debug add this method to keep the asserts above happy.
-    static bool isSSE2Present()
-    {
-        return true;
-    }
-
-#endif
-
     using CPUID = std::array<unsigned, 4>;
     static CPUID getCPUID(unsigned level);
     static CPUID getCPUIDEx(unsigned level, unsigned count);
     JS_EXPORT_PRIVATE static void collectCPUFeatures();
 
-    JS_EXPORT_PRIVATE static CPUIDCheckState s_sse2CheckState;
     JS_EXPORT_PRIVATE static CPUIDCheckState s_sse4_1CheckState;
     JS_EXPORT_PRIVATE static CPUIDCheckState s_sse4_2CheckState;
     JS_EXPORT_PRIVATE static CPUIDCheckState s_avxCheckState;
diff --git a/Source/cmake/DetectSSE2.cmake b/Source/cmake/DetectSSE2.cmake
new file mode 100644
index 0000000..dab07be
--- /dev/null
+++ b/Source/cmake/DetectSSE2.cmake
@@ -0,0 +1,61 @@
+#################################
+# Check for the presence of SSE2.
+#
+# Once done, this will define:
+# - SSE2_SUPPORT_FOUND - the system supports (at least) SSE2.
+#
+# Copyright (c) 2014, Pablo Fernandez Alcantarilla, Jesus Nuevo
+# Copyright (c) 2019, Igalia S.L.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+#   * Redistributions of source code must retain the above copyright notice,
+#     this list of conditions and the following disclaimer.
+#
+#   * Redistributions in binary form must reproduce the above copyright notice,
+#     this list of conditions and the following disclaimer in the documentation
+#     and/or other materials provided with the distribution.
+#
+#   * Neither the name of the copyright holders nor the names of its contributors
+#     may be used to endorse or promote products derived from this software without
+#     specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+# SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set(SSE2_SUPPORT_FOUND FALSE)
+
+macro(CHECK_FOR_SSE2)
+    include(CheckCXXSourceRuns)
+
+    check_cxx_source_runs("
+        #include <emmintrin.h>
+        int main ()
+        {
+            __m128d a, b;
+            double vals[2] = {0};
+            a = _mm_loadu_pd (vals);
+            b = _mm_add_pd (a,a);
+            _mm_storeu_pd (vals,b);
+            return 0;
+        }"
+        HAVE_SSE2_EXTENSIONS)
+
+    if (COMPILER_IS_GCC_OR_CLANG OR (MSVC AND NOT CMAKE_CL_64))
+        if (HAVE_SSE2_EXTENSIONS)
+            set(SSE2_SUPPORT_FOUND TRUE)
+            message(STATUS "Found SSE2 extensions")
+        endif ()
+    endif ()
+
+endmacro(CHECK_FOR_SSE2)
+
+CHECK_FOR_SSE2()
diff --git a/Source/cmake/WebKitCompilerFlags.cmake b/Source/cmake/WebKitCompilerFlags.cmake
index f56a47b..1f802d4 100644
--- a/Source/cmake/WebKitCompilerFlags.cmake
+++ b/Source/cmake/WebKitCompilerFlags.cmake
@@ -144,6 +144,15 @@
     if (CMAKE_COMPILER_IS_GNUCXX)
         WEBKIT_PREPEND_GLOBAL_COMPILER_FLAGS(-Wno-expansion-to-defined)
     endif ()
+
+    # Force SSE2 fp on x86 builds.
+    if (WTF_CPU_X86 AND NOT CMAKE_CROSSCOMPILING)
+        WEBKIT_PREPEND_GLOBAL_COMPILER_FLAGS(-msse2 -mfpmath=sse)
+        include(DetectSSE2)
+        if (NOT SSE2_SUPPORT_FOUND)
+            message(FATAL_ERROR "SSE2 support is required to compile WebKit")
+        endif ()
+    endif ()
 endif ()
 
 if (COMPILER_IS_GCC_OR_CLANG AND NOT MSVC)
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index db72aaa..e6a5cc0 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,14 @@
+2019-05-09  Xan López  <xan@igalia.com>
+
+        [CMake] Detect SSE2 at compile time
+        https://bugs.webkit.org/show_bug.cgi?id=196488
+
+        Reviewed by Carlos Garcia Campos.
+
+        * Scripts/webkitdirs.pm:
+        (generateBuildSystemFromCMakeProject): Do not add SSE2 flags here
+        for x86 builds. This is now handled in WebKitCompilerFlags.cmake.
+
 2019-05-08  Adrian Perez de Castro  <aperez@igalia.com>
 
         [WPE] Update dependencies to use libwpe + WPEBackend-fdo 1.3.0
diff --git a/Tools/Scripts/webkitdirs.pm b/Tools/Scripts/webkitdirs.pm
index 71be0a9..fb0ef50 100755
--- a/Tools/Scripts/webkitdirs.pm
+++ b/Tools/Scripts/webkitdirs.pm
@@ -2226,15 +2226,6 @@
     my $cmakeSourceDir = isCygwin() ? windowsSourceDir() : sourceDir();
     push @args, '"' . $cmakeSourceDir . '"';
 
-    # Compiler options to keep floating point values consistent
-    # between 32-bit and 64-bit architectures. This makes us use SSE
-    # when our architecture is 32-bit ('i686') or when it's not but
-    # the user has requested a 32-bit build.
-    if ((architecture() eq "i686" || (architecture() eq "x86_64" && shouldBuild32Bit())) && !isCrossCompilation() && !isAnyWindows()) {
-        $ENV{'CFLAGS'} = "-march=pentium4 -msse2 -mfpmath=sse " . ($ENV{'CFLAGS'} || "");
-        $ENV{'CXXFLAGS'} = "-march=pentium4 -msse2 -mfpmath=sse " . ($ENV{'CXXFLAGS'} || "");
-    }
-
     # We call system("cmake @args") instead of system("cmake", @args) so that @args is
     # parsed for shell metacharacters.
     my $wrapper = join(" ", wrapperPrefixIfNeeded()) . " ";