diff options
author | Yaxun (Sam) Liu <yaxun.liu@amd.com> | 2020-05-20 15:11:42 -0400 |
---|---|---|
committer | Yaxun (Sam) Liu <yaxun.liu@amd.com> | 2021-04-06 15:44:00 -0400 |
commit | 61d065e21ff37fb9040aed711c97daddac2f7577 (patch) | |
tree | ce0ccd3e55eb95a0758f068eb82d8947871a573a /clang/lib/Sema/SemaChecking.cpp | |
parent | ddebed8e9742add4372d54021cb55e06b655cfd6 (diff) | |
download | llvm-61d065e21ff37fb9040aed711c97daddac2f7577.zip llvm-61d065e21ff37fb9040aed711c97daddac2f7577.tar.gz llvm-61d065e21ff37fb9040aed711c97daddac2f7577.tar.bz2 |
Let clang atomic builtins fetch add/sub support floating point types
Recently atomicrmw started to support fadd/fsub:
https://reviews.llvm.org/D53965
However clang atomic builtins fetch add/sub still does not support
emitting atomicrmw fadd/fsub.
This patch adds that.
Reviewed by: John McCall, Artem Belevich, Matt Arsenault, JF Bastien,
James Y Knight, Louis Dionne, Olivier Giroux
Differential Revision: https://reviews.llvm.org/D71726
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 5b534f8..1d39de7 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -4931,7 +4931,8 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, case AtomicExpr::AO__atomic_add_fetch: case AtomicExpr::AO__atomic_sub_fetch: IsAddSub = true; - LLVM_FALLTHROUGH; + Form = Arithmetic; + break; case AtomicExpr::AO__c11_atomic_fetch_and: case AtomicExpr::AO__c11_atomic_fetch_or: case AtomicExpr::AO__c11_atomic_fetch_xor: @@ -4946,6 +4947,8 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, case AtomicExpr::AO__atomic_or_fetch: case AtomicExpr::AO__atomic_xor_fetch: case AtomicExpr::AO__atomic_nand_fetch: + Form = Arithmetic; + break; case AtomicExpr::AO__c11_atomic_fetch_min: case AtomicExpr::AO__c11_atomic_fetch_max: case AtomicExpr::AO__opencl_atomic_fetch_min: @@ -5038,10 +5041,24 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, // For an arithmetic operation, the implied arithmetic must be well-formed. if (Form == Arithmetic) { - // gcc does not enforce these rules for GNU atomics, but we do so for sanity. - if (IsAddSub && !ValType->isIntegerType() - && !ValType->isPointerType()) { - Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr) + // gcc does not enforce these rules for GNU atomics, but we do so for + // sanity. + auto IsAllowedValueType = [&](QualType ValType) { + if (ValType->isIntegerType()) + return true; + if (ValType->isPointerType()) + return true; + if (!ValType->isFloatingType()) + return false; + // LLVM Parser does not allow atomicrmw with x86_fp80 type. + if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) && + &Context.getTargetInfo().getLongDoubleFormat() == + &llvm::APFloat::x87DoubleExtended()) + return false; + return true; + }; + if (IsAddSub && !IsAllowedValueType(ValType)) { + Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_atomic_int_ptr_or_fp) << IsC11 << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); } @@ -5168,7 +5185,9 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, // passed by address. For the rest, GNU uses by-address and C11 uses // by-value. assert(Form != Load); - if (Form == Init || (Form == Arithmetic && ValType->isIntegerType())) + if (Form == Arithmetic && ValType->isPointerType()) + Ty = Context.getPointerDiffType(); + else if (Form == Init || Form == Arithmetic) Ty = ValType; else if (Form == Copy || Form == Xchg) { if (IsPassedByAddress) { @@ -5177,9 +5196,7 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, ExprRange.getBegin()); } Ty = ByValType; - } else if (Form == Arithmetic) - Ty = Context.getPointerDiffType(); - else { + } else { Expr *ValArg = APIOrderedArgs[i]; // The value pointer is always dereferenced, a nullptr is undefined. CheckNonNullArgument(*this, ValArg, ExprRange.getBegin()); |