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

Reply via email to