187 lines · cpp
1// RUN: %clang_cc1 -emit-llvm -triple i386-linux -std=c++2a -Wno-unknown-pragmas %s -o - | FileCheck %s2 3// nextUp(1.F) == 0x1.000002p0F4 5constexpr float add_round_down(float x, float y) {6 #pragma STDC FENV_ROUND FE_DOWNWARD7 float res = x;8 res += y;9 return res;10}11 12constexpr float add_round_up(float x, float y) {13 #pragma STDC FENV_ROUND FE_UPWARD14 float res = x;15 res += y;16 return res;17}18 19float V1 = add_round_down(1.0F, 0x0.000001p0F);20float V2 = add_round_up(1.0F, 0x0.000001p0F);21// CHECK: @V1 = {{.*}} float 1.000000e+0022// CHECK: @V2 = {{.*}} float 0x3FF000002000000023 24constexpr float add_cast_round_down(float x, double y) {25 #pragma STDC FENV_ROUND FE_DOWNWARD26 float res = x;27 res += y;28 return res;29}30 31constexpr float add_cast_round_up(float x, double y) {32 #pragma STDC FENV_ROUND FE_UPWARD33 float res = x;34 res += y;35 return res;36}37 38float V3 = add_cast_round_down(1.0F, 0x0.000001p0F);39float V4 = add_cast_round_up(1.0F, 0x0.000001p0F);40 41// CHECK: @V3 = {{.*}} float 1.000000e+0042// CHECK: @V4 = {{.*}} float 0x3FF000002000000043 44// The next three variables use the same function as initializer, only rounding45// modes differ.46 47float V5 = []() -> float {48 return [](float x, float y)->float {49 #pragma STDC FENV_ROUND FE_UPWARD50 return x + y;51 }([](float x, float y) -> float {52 #pragma STDC FENV_ROUND FE_UPWARD53 return x + y;54 }(1.0F, 0x0.000001p0F),55 0x0.000001p0F);56}();57// CHECK: @V5 = {{.*}} float 0x3FF000004000000058 59float V6 = []() -> float {60 return [](float x, float y)->float {61 #pragma STDC FENV_ROUND FE_DOWNWARD62 return x + y;63 }([](float x, float y) -> float {64 #pragma STDC FENV_ROUND FE_UPWARD65 return x + y;66 }(1.0F, 0x0.000001p0F),67 0x0.000001p0F);68}();69// CHECK: @V6 = {{.*}} float 0x3FF000002000000070 71float V7 = []() -> float {72 return [](float x, float y)->float {73 #pragma STDC FENV_ROUND FE_DOWNWARD74 return x + y;75 }([](float x, float y) -> float {76 #pragma STDC FENV_ROUND FE_DOWNWARD77 return x + y;78 }(1.0F, 0x0.000001p0F),79 0x0.000001p0F);80}();81// CHECK: @V7 = {{.*}} float 1.000000e+0082 83#pragma STDC FENV_ROUND FE_DYNAMIC84 85template<float V> struct L {86 constexpr L() : value(V) {}87 float value;88};89 90#pragma STDC FENV_ROUND FE_DOWNWARD91L<0.1F> val_d;92// CHECK: @val_d = {{.*}} { float 0x3FB9999980000000 }93 94#pragma STDC FENV_ROUND FE_UPWARD95L<0.1F> val_u;96// CHECK: @val_u = {{.*}} { float 0x3FB99999A0000000 }97 98 99// Check literals in macros.100 101#pragma STDC FENV_ROUND FE_DOWNWARD102#define CONSTANT_0_1 0.1F103 104#pragma STDC FENV_ROUND FE_UPWARD105float C1_ru = CONSTANT_0_1;106// CHECK: @C1_ru = {{.*}} float 0x3FB99999A0000000107 108#pragma STDC FENV_ROUND FE_DOWNWARD109float C1_rd = CONSTANT_0_1;110// CHECK: @C1_rd = {{.*}} float 0x3FB9999980000000111 112#pragma STDC FENV_ROUND FE_DOWNWARD113#define PRAGMA(x) _Pragma(#x)114#define CONSTANT_0_1_RM(v, rm) ([](){ PRAGMA(STDC FENV_ROUND rm); return v; }())115 116#pragma STDC FENV_ROUND FE_UPWARD117float C2_rd = CONSTANT_0_1_RM(0.1F, FE_DOWNWARD);118float C2_ru = CONSTANT_0_1_RM(0.1F, FE_UPWARD);119// CHECK: @C2_rd = {{.*}} float 0x3FB9999980000000120// CHECK: @C2_ru = {{.*}} float 0x3FB99999A0000000121 122#pragma STDC FENV_ROUND FE_DOWNWARD123float C3_rd = CONSTANT_0_1_RM(0.1F, FE_DOWNWARD);124float C3_ru = CONSTANT_0_1_RM(0.1F, FE_UPWARD);125// CHECK: @C3_rd = {{.*}} float 0x3FB9999980000000126// CHECK: @C3_ru = {{.*}} float 0x3FB99999A0000000127 128// Check literals in template instantiations.129 130#pragma STDC FENV_ROUND FE_DYNAMIC131 132template<typename T, T C>133constexpr T foo() {134 return C;135}136 137#pragma STDC FENV_ROUND FE_DOWNWARD138float var_d = foo<float, 0.1F>();139// CHECK: @var_d = {{.*}} float 0x3FB9999980000000140 141#pragma STDC FENV_ROUND FE_UPWARD142float var_u = foo<float, 0.1F>();143// CHECK: @var_u = {{.*}} float 0x3FB99999A0000000144 145#pragma STDC FENV_ROUND FE_DYNAMIC146 147template<typename T, T f> void foo2() {148 T Val = f;149}150 151void func_01() {152 #pragma STDC FENV_ROUND FE_DOWNWARD153 foo2<float, 0.1f>();154}155 156void func_02() {157 #pragma STDC FENV_ROUND FE_UPWARD158 foo2<float, 0.1f>();159}160 161// CHECK-LABEL: define {{.*}} void @_Z4foo2IfTnT_Lf3dccccccEEvv()162// CHECK: store float 0x3FB9999980000000, ptr163 164// CHECK-LABEL: define {{.*}} void @_Z4foo2IfTnT_Lf3dcccccdEEvv()165// CHECK: store float 0x3FB99999A0000000, ptr166 167 168#pragma STDC FENV_ROUND FE_DOWNWARD169template <int C>170float tfunc_01() {171 return 0.1F; // Must be 0x3FB9999980000000 in all instantiations.172}173template float tfunc_01<0>();174// CHECK-LABEL: define {{.*}} float @_Z8tfunc_01ILi0EEfv()175// CHECK: ret float 0x3FB9999980000000176 177#pragma STDC FENV_ROUND FE_UPWARD178template float tfunc_01<1>();179// CHECK-LABEL: define {{.*}} float @_Z8tfunc_01ILi1EEfv()180// CHECK: ret float 0x3FB9999980000000181 182template<> float tfunc_01<2>() {183 return 0.1F;184}185// CHECK-LABEL: define {{.*}} float @_Z8tfunc_01ILi2EEfv()186// CHECK: ret float 0x3FB99999A0000000187