sepavloff created this revision.
sepavloff added reviewers: rjmccall, anemet, kpn, aaron.ballman, hfinkel.
Herald added a project: clang.

If the value of FPOption is modified, for example by using pragma
'clang fp', create calls to constrained fp intrinsics with metadata
arguments corresponding to the selected rounding mode and exception
behavior.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D66092

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/CodeGen/pragma-fp-2.cpp

Index: clang/test/CodeGen/pragma-fp-2.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/pragma-fp-2.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+void func_01(float x, float y) {
+#pragma clang fp rounding(upward) exceptions(maytrap)
+  float z = x + y;
+// CHECK-LABEL: _Z7func_01ff
+// CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.upward", metadata !"fpexcept.maytrap")
+}
+
+void func_02(float x, float y) {
+  float z = x + y;
+// CHECK-LABEL: _Z7func_02ff
+// CHECK: fadd float %0, %1
+}
+
+void func_03(float x, float y) {
+  float z1 = x + y;
+  {
+    #pragma clang fp rounding(downward) exceptions(strict)
+    float z2 = x - y;
+  }
+  float z3 = x * y;
+// CHECK-LABEL: _Z7func_03ff
+// CHECK: fadd float
+// CHECK: call float @llvm.experimental.constrained.fsub.f32({{.*}}, metadata !"round.downward", metadata !"fpexcept.strict")
+// CHECK: fmul float
+}
+
+void func_03a(float x, float y) {
+  float z1 = x + y;
+  {
+    #pragma clang fp rounding(downward) exceptions(strict)
+    float z2 = x - y;
+    {
+      #pragma clang fp rounding(upward) exceptions(maytrap)
+      float z2a = x * y;
+    }
+    float z2b = x + y;
+  }
+  float z3 = x * y;
+// CHECK-LABEL: _Z8func_03aff
+// CHECK: fadd
+// CHECK: call float @llvm.experimental.constrained.fsub.f32({{.*}}, metadata !"round.downward", metadata !"fpexcept.strict") 
+// CHECK: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.upward", metadata !"fpexcept.maytrap")
+// CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.downward", metadata !"fpexcept.strict")
+// CHECK: fmul
+}
+
+
+#pragma clang fp rounding(towardzero) exceptions(ignore)
+
+void func_04(float x, float y) {
+  float z = x + y;
+// CHECK-LABEL: _Z7func_04ff
+// CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+}
+
+void func_05(float x, float y) {
+  float z = x / y;
+// CHECK-LABEL: _Z7func_05ff
+// CHECK: call float @llvm.experimental.constrained.fdiv.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+}
+
+#pragma clang fp rounding(dynamic) exceptions(maytrap)
+
+void func_06(float x, float y) {
+  float z = x + y;
+// CHECK-LABEL: _Z7func_06ff
+// CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.dynamic", metadata !"fpexcept.maytrap")
+}
+
+#pragma clang fp rounding(tonearest) exceptions(ignore)
+
+void func_07(float x, float y) {
+  float z = x + y;
+// CHECK-LABEL: _Z7func_07ff
+// CHECK: fadd float
+}
+
Index: clang/lib/CodeGen/CGExprScalar.cpp
===================================================================
--- clang/lib/CodeGen/CGExprScalar.cpp
+++ clang/lib/CodeGen/CGExprScalar.cpp
@@ -140,6 +140,34 @@
     }
     return false;
   }
+
+  llvm::ConstrainedFPIntrinsic::RoundingMode getConstrainedRounding() const {
+    switch (FPFeatures.getRoundingMode()) {
+    case LangOptions::FPRoundingModeKind::ToNearest:
+      return llvm::ConstrainedFPIntrinsic::RoundingMode::rmToNearest;
+    case LangOptions::FPRoundingModeKind::Downward:
+      return llvm:: ConstrainedFPIntrinsic::RoundingMode::rmDownward;
+    case LangOptions::FPRoundingModeKind::Upward:
+      return llvm::ConstrainedFPIntrinsic::RoundingMode::rmUpward;
+    case LangOptions::FPRoundingModeKind::TowardZero:
+      return llvm::ConstrainedFPIntrinsic::RoundingMode::rmTowardZero;
+    case LangOptions::FPRoundingModeKind::Dynamic:
+      return llvm::ConstrainedFPIntrinsic::RoundingMode::rmDynamic;
+    }
+    return llvm::ConstrainedFPIntrinsic::RoundingMode::rmDynamic;
+  }
+
+  llvm::ConstrainedFPIntrinsic::ExceptionBehavior getConstrainedExcept() const {
+    switch (FPFeatures.getExceptionMode()) {
+    case LangOptions::FPExceptionModeKind::Ignore:
+      return llvm::ConstrainedFPIntrinsic::ExceptionBehavior::ebIgnore;
+    case LangOptions::FPExceptionModeKind::MayTrap:
+      return llvm::ConstrainedFPIntrinsic::ExceptionBehavior::ebMayTrap;
+    case LangOptions::FPExceptionModeKind::Strict:
+      return llvm::ConstrainedFPIntrinsic::ExceptionBehavior::ebStrict;
+    }
+    return llvm::ConstrainedFPIntrinsic::ExceptionBehavior::ebStrict;
+  }
 };
 
 static bool MustVisitNullValue(const Expr *E) {
@@ -728,6 +756,9 @@
       return EmitOverflowCheckedBinOp(Ops);
 
     if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
+      CGBuilderTy::FloatingPointStateSaver S(Builder,
+          Ops.FPFeatures.isFPConstrained(), Ops.getConstrainedExcept(),
+          Ops.getConstrainedRounding());
       Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul");
       return propagateFMFlags(V, Ops);
     }
@@ -3001,6 +3032,9 @@
   }
 
   if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
+    CGBuilderTy::FloatingPointStateSaver S(Builder,
+        Ops.FPFeatures.isFPConstrained(), Ops.getConstrainedExcept(),
+        Ops.getConstrainedRounding());
     llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
     if (CGF.getLangOpts().OpenCL &&
         !CGF.CGM.getCodeGenOpts().CorrectlyRoundedDivSqrt) {
@@ -3358,6 +3392,9 @@
     if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder))
       return FMulAdd;
 
+    CGBuilderTy::FloatingPointStateSaver S(Builder,
+        op.FPFeatures.isFPConstrained(), op.getConstrainedExcept(),
+        op.getConstrainedRounding());
     Value *V = Builder.CreateFAdd(op.LHS, op.RHS, "add");
     return propagateFMFlags(V, op);
   }
@@ -3502,6 +3539,9 @@
       // Try to form an fmuladd.
       if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true))
         return FMulAdd;
+      CGBuilderTy::FloatingPointStateSaver S(Builder,
+          op.FPFeatures.isFPConstrained(), op.getConstrainedExcept(),
+          op.getConstrainedRounding());
       Value *V = Builder.CreateFSub(op.LHS, op.RHS, "sub");
       return propagateFMFlags(V, op);
     }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to