diff --git a/clang/test/CodeGen/rounding-math.c b/clang/test/CodeGen/rounding-math.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/rounding-math.c @@ -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 --- /dev/null +++ b/clang/test/CodeGen/rounding-math.cpp @@ -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 diff --git a/clang/test/SemaCXX/rounding-math.cpp b/clang/test/SemaCXX/rounding-math.cpp --- a/clang/test/SemaCXX/rounding-math.cpp +++ b/clang/test/SemaCXX/rounding-math.cpp @@ -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 @@ 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), "");