Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std::atomic<long double>::compare_exchange_weak does not update expected on failure #47978

Open
llvmbot opened this issue Dec 30, 2020 · 0 comments
Labels
bugzilla Issues migrated from bugzilla c++20

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 30, 2020

Bugzilla Link 48634
Version 11.0
OS Linux
Attachments Program reproducing the bug.
Reporter LLVM Bugzilla Contributor
CC @zygoloid

Extended Description

This program does not behave as intended:

#include <atomic>
#include <iostream>
int main() {
  std::atomic<long double> x;
  x.store(1.0);
  long double tmp = 2.0;
  bool worked = x.compare_exchange_weak(tmp, 3.0);
  std::cout << "worked " << worked << " set tmp to " << tmp << std::endl;

  std::atomic<double> x2;
  x2.store(1.0);
  double tmp2 = 2.0;
  worked = x2.compare_exchange_weak(tmp2, 3.0);
  std::cout << "worked " << worked << " set tmp to " << tmp2 << std::endl;

  return 0;
}

I compile with

  clang++-12 -std=c++17 atomiclongdoublecompareexchangeweak.cpp \
             -o atomiclongdoublecompareexchangeweak -Wall -O0 -g -latomic

The output is:

worked 0 set tmp to 2
worked 0 set tmp to 1

The expected output is

worked 0 set tmp to 1
worked 0 set tmp to 1

My version of clang++-12 is:

% clang++-12 -v
Ubuntu clang version 12.0.0-++20201229052625+b76014a4f15a-1~exp1~20201229163322.268
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/10
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/10
Candidate multilib: .;@m64
Selected multilib: .;@m64

The same problem occurs with clang++11 and other optimization levels.

The problem is that

  std::atomic<long double>::compare_exchange_weak(long double& expected,
                                                  long double desired)

does not update expected as specified when the expected value is not
found.

Here are the libraries my program is linked against:

% ldd ./atomiclongdoublecompareexchangeweak
	linux-vdso.so.1 (0x00007fffe5b79000)
	libatomic.so.1 => /lib/x86_64-linux-gnu/libatomic.so.1 (0x00007f61dcb69000)
	libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f61dc988000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f61dc839000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f61dc81e000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f61dc62c000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f61dc609000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f61dcb9c000)

The problem seems to be that the atomic headers lead to the fact that in
the end the compiler intrinsic

  __atomic_compare_exchange

is called for the 16 byte case. Unfortunately, I cannot easily find the
source code for this. In any case this function seems to misbehave
for the 16 byte case. I have traced the assembler code and this shows
the wrong behaviour.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 11, 2021
@huixie90 huixie90 changed the title std::atomic<long double>::compare_exchange_weak does not update expected on failure std::atomic<long double>::compare_exchange_weak does not update expected on failure Oct 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c++20
Projects
Status: No status
Development

No branches or pull requests

1 participant