@@ -293,21 +293,19 @@ static RValue emitBinaryAtomic(CIRGenFunction &CGF, cir::AtomicFetchKind kind,
293
293
294
294
static RValue emitBinaryAtomicPost (CIRGenFunction &cgf,
295
295
cir::AtomicFetchKind atomicOpkind,
296
- const CallExpr *e,
297
- cir::BinOpKind binopKind ) {
296
+ const CallExpr *e, cir::BinOpKind binopKind,
297
+ bool invert = false ) {
298
298
mlir::Value val;
299
299
mlir::Type valueType;
300
300
clang::QualType typ = e->getType ();
301
301
mlir::Value result =
302
302
makeBinaryAtomicValue (cgf, atomicOpkind, e, &val, &valueType);
303
303
clang::CIRGen::CIRGenBuilderTy &builder = cgf.getBuilder ();
304
304
result = builder.create <cir::BinOp>(result.getLoc (), binopKind, result, val);
305
+ if (invert)
306
+ result = builder.create <cir::UnaryOp>(result.getLoc (),
307
+ cir::UnaryOpKind::Not, result);
305
308
result = emitFromInt (cgf, result, typ, valueType);
306
- // FIXME: Some callers of this function expect the result to be inverted,
307
- // which would need invert flag passed in and do the inversion here like
308
- // traditional clang code gen does. When we implment those caller builtins
309
- // we should implement the inversion here.
310
- assert (!MissingFeatures::emitBinaryAtomicPostHasInvert ());
311
309
return RValue::get (result);
312
310
}
313
311
@@ -1841,7 +1839,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
1841
1839
case Builtin::BI__sync_nand_and_fetch_4:
1842
1840
case Builtin::BI__sync_nand_and_fetch_8:
1843
1841
case Builtin::BI__sync_nand_and_fetch_16:
1844
- llvm_unreachable (" BI__sync_nand_and_fetch like NYI" );
1842
+ return emitBinaryAtomicPost (*this , cir::AtomicFetchKind::Nand, E,
1843
+ cir::BinOpKind::And, true );
1845
1844
1846
1845
case Builtin::BI__sync_val_compare_and_swap_1:
1847
1846
case Builtin::BI__sync_val_compare_and_swap_2:
0 commit comments