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