Adds codegen for 'atomic capture' constructs with the following forms of expressions/statements:
v = x binop= expr; v = x++; v = ++x; v = x--; v = --x; v = x = x binop expr; v = x = expr binop x; {v = x; x = binop= expr;} {v = x; x++;} {v = x; ++x;} {v = x; x--;} {v = x; --x;} {x = x binop expr; v = x;} {x binop= expr; v = x;} {x++; v = x;} {++x; v = x;} {x--; v = x;} {--x; v = x;} {x = x binop expr; v = x;} {x = expr binop x; v = x;} {v = x; x = expr;}
If x and expr are integer and binop is associative or x is a LHS in a RHS of the assignment expression, and atomics are allowed for type of x on the target platform atomicrmw instruction is emitted.
Otherwise compare-and-swap sequence is emitted.
Update of 'v' is not required to be be atomic with respect to the read or write of the 'x'.
bb: ... atomic load <x> cont: <expected> = phi [ <x>, label %bb ], [ <new_failed>, %cont ] <desired> = <expected> binop <expr> <res> = cmpxchg atomic &<x>, desired, expected <new_failed> = <res>.field1; br <res>field2, label %exit, label %cont exit: atomic store <old/new x>, <v> ...
If 'x' was updated with `atomicrmw``` instruction and 'v' must be updated with the new value of 'x', an additional atomic load of 'x' is used to read the new value to be stored to 'v'. Otherwise previous value of 'x', returned by atomic instruction is used (if 'v' must be rewritten by the old value of 'x'), or newly calculated update value for 'x' is used (if 'v' must be rewritten by the new value of 'x').
Unfortunately, this makes the operation no longer atomic.