[FPEnv] Tests for rounding properties of constant evalution
authorSerge Pavlov <sepavloff@gmail.com>
Fri, 23 Oct 2020 11:36:16 +0000 (18:36 +0700)
committerSerge Pavlov <sepavloff@gmail.com>
Thu, 29 Oct 2020 06:53:13 +0000 (13:53 +0700)
These are moved from D88498.

Differential Revision: https://reviews.llvm.org/D90026

clang/test/CodeGen/rounding-math.c [new file with mode: 0644]
clang/test/CodeGen/rounding-math.cpp [new file with mode: 0644]
clang/test/SemaCXX/rounding-math.cpp

diff --git a/clang/test/CodeGen/rounding-math.c b/clang/test/CodeGen/rounding-math.c
new file mode 100644 (file)
index 0000000..b2671db
--- /dev/null
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -S -emit-llvm -ffp-exception-behavior=strict -Wno-unknown-pragmas %s -o - | FileCheck %s
+// RUN: %clang_cc1 -S -emit-llvm -frounding-math -Wno-unknown-pragmas %s -o - | FileCheck %s
+
+float PR47807 = -8.6563630030e-03;
+
+// nextUp(1.F) == 0x1.000002p0F
+
+struct S {
+  float f;
+};
+
+static struct S var_01 = {0x1.000001p0};
+struct S *func_01() {
+  return &var_01;
+}
+
+struct S var_02 = {0x1.000001p0};
+
+struct S *func_03() {
+  static struct S var_03 = {0x1.000001p0};
+  return &var_03;
+}
+
+// CHECK: @var_01 = {{.*}} %struct.S { float 1.000000e+00 }
+// CHECK: @var_02 = {{.*}} %struct.S { float 1.000000e+00 }
+// CHECK: @func_03.var_03 = {{.*}} %struct.S { float 1.000000e+00 }
+
+#pragma STDC FENV_ROUND FE_UPWARD
+
+static struct S var_04 = {0x1.000001p0};
+struct S *func_04() {
+  return &var_04;
+}
+
+struct S var_05 = {0x1.000001p0};
+
+struct S *func_06() {
+  static struct S var_06 = {0x1.000001p0};
+  return &var_06;
+}
+
+// CHECK: @var_04 = {{.*}} %struct.S { float 0x3FF0000020000000 }
+// CHECK: @var_05 = {{.*}} %struct.S { float 0x3FF0000020000000 }
+// CHECK: @func_06.var_06 = {{.*}} %struct.S { float 0x3FF0000020000000 }
+
diff --git a/clang/test/CodeGen/rounding-math.cpp b/clang/test/CodeGen/rounding-math.cpp
new file mode 100644 (file)
index 0000000..c0ed9fc
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -S -emit-llvm -triple i386-linux -Wno-unknown-pragmas -frounding-math %s -o - | FileCheck %s
+
+constexpr float func_01(float x, float y) {
+  return x + y;
+}
+
+float V1 = func_01(1.0F, 0x0.000001p0F);
+float V2 = 1.0F + 0x0.000001p0F;
+float V3 = func_01(1.0F, 2.0F);
+
+// CHECK: @V1 = {{.*}}global float 1.000000e+00, align 4
+// CHECK: @V2 = {{.*}}global float 1.000000e+00, align 4
+// CHECK: @V3 = {{.*}}global float 3.000000e+00, align 4
index 3577d2f..867534e 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-linux -verify=norounding %s
-// RUN: %clang_cc1 -triple x86_64-linux -verify=rounding %s -frounding-math
+// RUN: %clang_cc1 -triple x86_64-linux -verify=norounding -Wno-unknown-pragmas %s
+// RUN: %clang_cc1 -triple x86_64-linux -verify=rounding %s -frounding-math -Wno-unknown-pragmas
 // rounding-no-diagnostics
 
 #define fold(x) (__builtin_constant_p(x) ? (x) : (x))
@@ -39,3 +39,40 @@ void g() {
 int *h() {
   return new int[int(-3 * (1.0 / 3.0))]; // norounding-error {{too large}}
 }
+
+
+// nextUp(1.F) == 0x1.000002p0F
+static_assert(1.0F + 0x0.000001p0F == 0x1.0p0F, "");
+
+char Arr01[1 + (1.0F + 0x0.000001p0F > 1.0F)];
+static_assert(sizeof(Arr01) == 1, "");
+
+struct S1 {
+  int : (1.0F + 0x0.000001p0F > 1.0F);
+  int f;
+};
+static_assert(sizeof(S1) == sizeof(int), "");
+
+#pragma STDC FENV_ROUND FE_UPWARD
+static_assert(1.0F + 0x0.000001p0F == 0x1.000002p0F, "");
+
+char Arr01u[1 + (1.0F + 0x0.000001p0F > 1.0F)];
+static_assert(sizeof(Arr01u) == 2, "");
+
+struct S1u {
+  int : (1.0F + 0x0.000001p0F > 1.0F);
+  int f;
+};
+static_assert(sizeof(S1u) > sizeof(int), "");
+
+#pragma STDC FENV_ROUND FE_DOWNWARD
+static_assert(1.0F + 0x0.000001p0F == 1.0F, "");
+
+char Arr01d[1 + (1.0F + 0x0.000001p0F > 1.0F)];
+static_assert(sizeof(Arr01d) == 1, "");
+
+struct S1d {
+  int : (1.0F + 0x0.000001p0F > 1.0F);
+  int f;
+};
+static_assert(sizeof(S1d) == sizeof(int), "");