[clang] Implementation of '#pragma STDC FENV_ROUND' (PR #89617)
Joshua Cranmer via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 24 14:24:30 PDT 2024
================
@@ -0,0 +1,160 @@
+// RUN: %clang_cc1 -S -triple x86_64-linux-gnu -emit-llvm %s -o - | \
+// RUN: FileCheck %s --implicit-check-not "call void @llvm.set.rounding" --implicit-check-not "call i32 @llvm.get.rounding"
+
+float func_rz_ru(float w, float x, float y, float z) {
+ #pragma STDC FENV_ROUND FE_TOWARDZERO
+ float result = x * y;
+ {
+ #pragma STDC FENV_ROUND FE_UPWARD
+ result += z;
+ }
+ return result - w;
+}
+
+// CHECK-LABEL: @func_rz_ru
+// CHECK: call void @llvm.set.rounding(i32 0)
+// CHECK: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK: call void @llvm.set.rounding(i32 2)
+// CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.upward", metadata !"fpexcept.ignore")
+// CHECK: call void @llvm.set.rounding(i32 0)
+// CHECK: call float @llvm.experimental.constrained.fsub.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK: call void @llvm.set.rounding(i32 1)
+
+
+float func_rz_rz(float w, float x, float y, float z) {
+ #pragma STDC FENV_ROUND FE_TOWARDZERO
+ float result = x * y;
+ {
+ #pragma STDC FENV_ROUND FE_TOWARDZERO
+ result += z;
+ }
+ return result - w;
+}
+
+// CHECK-LABEL: @func_rz_rz
+// CHECK: call void @llvm.set.rounding(i32 0)
+// CHECK: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK: call float @llvm.experimental.constrained.fsub.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK: call void @llvm.set.rounding(i32 1)
+
+float func_rne_rne(float w, float x, float y, float z) {
+ #pragma STDC FENV_ROUND FE_TONEAREST
+ float result = x * y;
+ {
+ #pragma STDC FENV_ROUND FE_TONEAREST
+ result += z;
+ }
+ return result - w;
+}
+
+// CHECK-LABEL: @func_rne_rne
+// CHECK: fmul
+// CHECK: fadd
+// CHECK: fsub
+
+float func_rz_dyn_noacc(float w, float x, float y, float z) {
+ #pragma STDC FENV_ROUND FE_TOWARDZERO
+ float result = x * y;
+ {
+ #pragma STDC FENV_ROUND FE_DYNAMIC
+ result += z;
+ }
+ return result - w;
+}
+
+// CHECK-LABEL: @func_rz_dyn_noacc
+// CHECK: call void @llvm.set.rounding(i32 0)
+// CHECK: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK: call void @llvm.set.rounding(i32 1)
+// CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
----------------
jcranmer-intel wrote:
7.6.2p3:
> If the FE_DYNAMIC mode is specified and FENV_ACCESS is "off", the translator may assume that the default rounding mode is in effect.
https://github.com/llvm/llvm-project/pull/89617
More information about the cfe-commits
mailing list