uuid/test/test_msvc_simd_bug981648_main.cpp
Andrey Semashev 1a4e7ed9a8
Improve generated x86 code for AVX targets (#138)
* Re-format the test code for MSVC bug 981648.

* Improved generated x86 code for SSE4.1 and later targets.

Prefer movdqu to lddqu on CPUs supporting SSE4.1 and later. lddqu has one
extra cycle latency on Skylake and later Intel CPUs, and with AVX vlddqu
is not merged to the following instructions as a memory operand, which makes
the code slightly larger. Legacy SSE3 lddqu is still preferred when SSE4.1
is not enabled because it is faster on Prescott and the same as movdqu on
AMD CPUs. It also doesn't affect code size because movdqu cannot be converted
to a memory operand as memory operands are required to be aligned in SSE.

Closes https://github.com/boostorg/uuid/issues/137.

* Use movdqu universally for loading UUIDs.

This effectively drops the optimization for NetBurst CPUs and instead
prefers code that is slightly better on Skylake and later Intel CPUs,
even when the code is compiled for SSE3 and not SSE4.1.
2023-04-15 21:24:52 +03:00

49 lines
1.5 KiB
C++

/*
* Copyright 2014 Andrey Semashev
*
* Distributed under the Boost Software License, Version 1.0.
* See accompanying file LICENSE_1_0.txt or copy at
* https://www.boost.org/LICENSE_1_0.txt
*/
/*
* This is a part of the test for a workaround for MSVC 12 (VS2013) optimizer bug
* which causes incorrect SIMD code generation for operator==. See:
*
* https://svn.boost.org/trac/boost/ticket/8509#comment:3
* https://connect.microsoft.com/VisualStudio/feedbackdetail/view/981648#tabs
*
* This file contains the main entry point.
*/
#include <cstdio>
#include "test_msvc_simd_bug981648.hpp"
extern void mp_grid_update_marker_parameters(headerProperty* header_prop, my_obj &current_marker);
static my_obj g_my_obj;
int main(void)
{
my_obj *p = &g_my_obj;
p->m_uuid = uuid();
uuid one, two;
one.data[0] = 0; two.data[0] = 1;
//*****************************************
// This != statement generates two movdqu statements or pcmpeqd with a memory operand which crashes
if (one != two) {
std::printf("The first != operator works okay if it reaches this printf.\n");
}
my_obj a;
a.m_uuid.data[0] = 1;
std::printf("There should be a another printf coming next.\n");
//*****************************************
// The != statement in this function generates a movups and a movdqu statement.
// It also crashes because the optimizer also creates a pcmpeqd for a non-aligned memory location.
mp_grid_update_marker_parameters(p, a);
return 0;
}