[clang] Implementation of '#pragma STDC FENV_ROUND' (PR #89617)

Zahira Ammarguellat via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 24 09:40:36 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")
----------------
zahiraam wrote:

Shouldn't the `result += z` be dynamic here?

https://github.com/llvm/llvm-project/pull/89617


More information about the cfe-commits mailing list