llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Usama Hameed (usama54321) <details> <summary>Changes</summary> FP pragma state only reached CodeGen via `FunctionDecl`, so `#pragma STDC FENV_ACCESS ON` was silently dropped over ObjC method and block bodies which causes an assertion failure. Attach the implicit `StrictFPAttr` to `ObjCMethodDecl` and `BlockDecl`. rdar://182750847 --- Full diff: https://github.com/llvm/llvm-project/pull/220427.diff 6 Files Affected: - (modified) clang/include/clang/Basic/Attr.td (+1-1) - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+1-1) - (modified) clang/lib/Sema/SemaDecl.cpp (+5-2) - (modified) clang/lib/Sema/SemaExpr.cpp (+4) - (added) clang/test/CodeGen/pragma-fenv_access-block.c (+15) - (added) clang/test/CodeGenObjC/pragma-fenv_access.m (+28) ``````````diff diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 8530216f2c214..659ed40dd90c5 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3413,7 +3413,7 @@ def StrictFP : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. // Function uses strict floating point operations. let Spellings = []; - let Subjects = SubjectList<[Function]>; + let Subjects = SubjectList<[Function, ObjCMethod, Block]>; let Documentation = [InternalOnly]; } diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 119aebb673789..b3ed7a72b0caa 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1094,7 +1094,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, ToConstrainedExceptMD(getLangOpts().getDefaultExceptionMode()); Builder.setDefaultConstrainedRounding(RM); Builder.setDefaultConstrainedExcept(FPExceptionBehavior); - if ((FD && (FD->UsesFPIntrin() || FD->hasAttr<StrictFPAttr>())) || + if ((FD && FD->UsesFPIntrin()) || (D && D->hasAttr<StrictFPAttr>()) || (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore || RM != llvm::RoundingMode::NearestTiesToEven))) { Builder.setIsFPConstrained(true); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 80f738d9076ff..0d00ea330e9bb 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -16808,8 +16808,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation, FunctionScopeInfo *FSI = getCurFunction(); FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr; - if (FSI->UsesFPIntrin && FD && !FD->hasAttr<StrictFPAttr>()) - FD->addAttr(StrictFPAttr::CreateImplicit(Context)); + if (FSI->UsesFPIntrin) { + Decl *StrictFPTarget = FD ? cast<Decl>(FD) : dcl; + if (StrictFPTarget && !StrictFPTarget->hasAttr<StrictFPAttr>()) + StrictFPTarget->addAttr(StrictFPAttr::CreateImplicit(Context)); + } SourceLocation AnalysisLoc; if (Body) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ad703248cf325..8f8439762b514 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -17142,6 +17142,10 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, maybeAddDeclWithEffects(BD); + // A block body parsed under a constrained FP environment must be strict-FP. + if (BSI->UsesFPIntrin && !BD->hasAttr<StrictFPAttr>()) + BD->addAttr(StrictFPAttr::CreateImplicit(Context)); + if (BSI->HasImplicitReturnType) deduceClosureReturnType(*BSI); diff --git a/clang/test/CodeGen/pragma-fenv_access-block.c b/clang/test/CodeGen/pragma-fenv_access-block.c new file mode 100644 index 0000000000000..f9a79267fd154 --- /dev/null +++ b/clang/test/CodeGen/pragma-fenv_access-block.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple arm64-apple-macosx -fblocks -emit-llvm -O0 -o - %s | FileCheck %s + +// A block body under an FP-affecting pragma must be emitted in strict-FP mode. + +#pragma STDC FENV_ACCESS ON + +// CHECK-LABEL: define internal float @__block_in_function_block_invoke +// CHECK-SAME: #[[ATTR:[0-9]+]] +// CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") +float block_in_function(float x, float y) { + float (^blk)(float, float) = ^float(float a, float b) { return a + b; }; + return blk(x, y); +} + +// CHECK: attributes #[[ATTR]] = {{.*}} strictfp diff --git a/clang/test/CodeGenObjC/pragma-fenv_access.m b/clang/test/CodeGenObjC/pragma-fenv_access.m new file mode 100644 index 0000000000000..d472eb90500c2 --- /dev/null +++ b/clang/test/CodeGenObjC/pragma-fenv_access.m @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple arm64-apple-macosx -emit-llvm -O0 -o - %s | FileCheck %s + +// An FP-affecting pragma in effect over an Objective-C method body must put that +// body into strict-FP mode, exactly as it does for a plain function body. + +#pragma STDC FENV_ACCESS ON + +__attribute__((objc_root_class)) +@interface Foo +@end + +@implementation Foo +// CHECK-LABEL: define internal float @"\01-[Foo add:with:]" +// CHECK-SAME: #[[ATTR:[0-9]+]] +// CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") +- (float)add:(float)a with:(float)b { + return a + b; +} +@end + +// CHECK-LABEL: define{{.*}} float @plain_function +// CHECK-SAME: #[[ATTR]] +// CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") +float plain_function(float a, float b) { + return a + b; +} + +// CHECK: attributes #[[ATTR]] = {{.*}} strictfp `````````` </details> https://github.com/llvm/llvm-project/pull/220427 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
