Issue 53079
Summary [clang] produces incorrect LLVM IR for atomic post increments on floats
Labels new issue
Assignees
Reporter jeaiii
    https://godbolt.org/z/f8668T31M

```
auto test0()
{
    static _Atomic float n;
    return __c11_atomic_fetch_add(&n, 1, 5);
}

auto test1()
{
    static _Atomic float n;
    return n++;
}

```
test0 -  generates `atomicrmw fadd` and correct intel assembly (there could be a slight improvement here)
test1 - generates an LLVM IR code sequence using atomic compare exchange `cmpxchg` instead of using `atomicrmw fadd`. This code sequence has a bug in that it only returns the value of the first load from the atomic float. If two threads call `test1()` at the same time they could get the same value returned (`%2` below), rather than n and n + 1. The generated compare exchange LLVM IR could be fixed by returning `%11`, but now that `atomicrmw fadd` exists it should be used instead.

if `float` is changed to `int` both functions generate `atomicrmw add`

LLVM IR of `test1()`
```
  %1 = load atomic i32, i32* bitcast (float* @_ZZ5test1vE1n to i32*) seq_cst, align 4, !dbg !32, !tbaa !33
  %2 = bitcast i32 %1 to float, !dbg !32
  br label %3, !dbg !32

3: ; preds = %3, %0
  %4 = phi float [ %2, %0 ], [ %11, %3 ], !dbg !32
  %5 = fadd float %4, 1.000000e+00, !dbg !32
  %6 = bitcast float %4 to i32, !dbg !32
  %7 = bitcast float %5 to i32, !dbg !32
  %8 = cmpxchg i32* bitcast (float* @_ZZ5test1vE1n to i32*), i32 %6, i32 %7 seq_cst seq_cst, align 4, !dbg !32
  %9 = extractvalue { i32, i1 } %8, 0, !dbg !32
  %10 = extractvalue { i32, i1 } %8, 1, !dbg !32
  %11 = bitcast i32 %9 to float, !dbg !32
  br i1 %10, label %12, label %3, !dbg !32

12: ; preds = %3
  ret float %2, !dbg !36
```

should return `%11` not `%2`
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to