| // RUN: %clang_cc1 -fexperimental-strict-floating-point -ffp-exception-behavior=strict -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,STRICT %s |
| // RUN: %clang_cc1 -fexperimental-strict-floating-point -frounding-math -ffp-exception-behavior=strict -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,STRICT-RND %s |
| // RUN: %clang_cc1 -fexperimental-strict-floating-point -ffp-exception-behavior=strict -triple %itanium_abi_triple -emit-llvm %s -o - -fms-extensions -DMS | FileCheck --check-prefixes=CHECK,STRICT %s |
| // RUN: %clang_cc1 -fexperimental-strict-floating-point -frounding-math -ffp-exception-behavior=strict -triple %itanium_abi_triple -emit-llvm %s -o - -fms-extensions -DMS | FileCheck --check-prefixes=CHECK,STRICT-RND %s |
| // RUN: %clang_cc1 -fexperimental-strict-floating-point -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,DEFAULT %s |
| // RUN: %clang_cc1 -fexperimental-strict-floating-point -frounding-math -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,DEFAULT-RND %s |
| |
| float func_00(float x, float y) { |
| return x + y; |
| } |
| // CHECK-LABEL: @func_00 |
| // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") |
| // STRICT-RND: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| // DEFAULT-RND: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.ignore") |
| // DEFAULT: fadd float |
| |
| |
| #ifdef MS |
| #pragma fenv_access (on) |
| #else |
| #pragma STDC FENV_ACCESS ON |
| #endif |
| |
| float func_01(float x, float y) { |
| return x + y; |
| } |
| // CHECK-LABEL: @func_01 |
| // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| |
| |
| float func_02(float x, float y) { |
| #pragma float_control(except, off) |
| #pragma STDC FENV_ACCESS OFF |
| return x + y; |
| } |
| // CHECK-LABEL: @func_02 |
| // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore") |
| |
| |
| float func_03(float x, float y) { |
| return x + y; |
| } |
| // CHECK-LABEL: @func_03 |
| // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| |
| |
| #ifdef MS |
| #pragma fenv_access (off) |
| #else |
| #pragma STDC FENV_ACCESS OFF |
| #endif |
| |
| float func_04(float x, float y) { |
| #pragma float_control(except, off) |
| return x + y; |
| } |
| // CHECK-LABEL: @func_04 |
| // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore") |
| // DEFAULT: fadd float |
| |
| |
| float func_04a(float x, float y) { |
| #pragma float_control(except, on) |
| return x + y; |
| } |
| // CHECK-LABEL: @func_04a |
| // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") |
| |
| |
| float func_05(float x, float y) { |
| #pragma STDC FENV_ACCESS ON |
| return x + y; |
| } |
| // CHECK-LABEL: @func_05 |
| // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| |
| |
| float func_06(float x, float y) { |
| #pragma float_control(except, off) |
| return x + y; |
| } |
| // CHECK-LABEL: @func_06 |
| // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore") |
| // DEFAULT: fadd float |
| |
| |
| float func_07(float x, float y) { |
| x -= y; |
| if (x) { |
| #pragma STDC FENV_ACCESS ON |
| y *= 2.0F; |
| } |
| return y + 4.0F; |
| } |
| // CHECK-LABEL: @func_07 |
| // STRICT: call float @llvm.experimental.constrained.fsub.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") |
| // STRICT: call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") |
| // DEFAULT: call float @llvm.experimental.constrained.fsub.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore") |
| // DEFAULT: call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| // DEFAULT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore") |
| |
| |
| float func_08(float x, float y) { |
| #pragma STDC FENV_ROUND FE_UPWARD |
| #pragma STDC FENV_ACCESS ON |
| return x + y; |
| } |
| // CHECK-LABEL: @func_08 |
| // CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.upward", metadata !"fpexcept.strict") |
| |
| |
| float func_09(float x, float y) { |
| #pragma STDC FENV_ROUND FE_TONEAREST |
| #pragma STDC FENV_ACCESS ON |
| return x + y; |
| } |
| // CHECK-LABEL: @func_09 |
| // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") |
| |
| |
| float func_10(float x, float y) { |
| #pragma STDC FENV_ROUND FE_TONEAREST |
| #pragma clang fp exceptions(ignore) |
| #pragma STDC FENV_ACCESS ON |
| return x + y; |
| } |
| // CHECK-LABEL: @func_10 |
| // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore") |
| |
| |
| float func_11(float x, float y) { |
| #pragma STDC FENV_ROUND FE_TONEAREST |
| #pragma clang fp exceptions(ignore) |
| #pragma STDC FENV_ACCESS OFF |
| return x + y; |
| } |
| // CHECK-LABEL: @func_11 |
| // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore") |
| // DEFAULT: fadd float |
| |
| |
| float func_12(float x, float y) { |
| #pragma clang fp exceptions(maytrap) |
| #pragma STDC FENV_ACCESS ON |
| return x + y; |
| } |
| // CHECK-LABEL: @func_12 |
| // CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.dynamic", metadata !"fpexcept.maytrap") |
| |
| |
| float func_13(float x, float y) { |
| #pragma clang fp exceptions(maytrap) |
| #pragma STDC FENV_ROUND FE_UPWARD |
| #pragma STDC FENV_ACCESS ON |
| return x + y; |
| } |
| // CHECK-LABEL: @func_13 |
| // CHECK: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.upward", metadata !"fpexcept.maytrap") |
| |
| |
| float func_14(float x, float y, float z) { |
| #pragma STDC FENV_ACCESS ON |
| float res = x * y; |
| { |
| #pragma STDC FENV_ACCESS OFF |
| return res + z; |
| } |
| } |
| // CHECK-LABEL: @func_14 |
| // STRICT: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| // STRICT: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") |
| // DEFAULT: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| // DEFAULT: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore") |
| |
| |
| float func_15(float x, float y, float z) { |
| #pragma STDC FENV_ROUND FE_TOWARDZERO |
| #pragma STDC FENV_ACCESS ON |
| float res = x * y; |
| { |
| #pragma STDC FENV_ACCESS OFF |
| return res + z; |
| } |
| } |
| // CHECK-LABEL: @func_15 |
| // STRICT: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.strict") |
| // STRICT: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.strict") |
| // DEFAULT: call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.strict") |
| // DEFAULT: call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore") |
| |
| |
| float func_16(float x, float y) { |
| x -= y; |
| { |
| #pragma STDC FENV_ROUND FE_TONEAREST |
| #pragma STDC FENV_ACCESS ON |
| y *= 2.0F; |
| } |
| { |
| #pragma STDC FENV_ACCESS ON |
| return y + 4.0F; |
| } |
| } |
| // CHECK-LABEL: @func_16 |
| // STRICT: call float @llvm.experimental.constrained.fsub.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") |
| // STRICT: call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") |
| // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| // DEFAULT: call float @llvm.experimental.constrained.fsub.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore") |
| // DEFAULT: call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") |
| // DEFAULT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| |
| |
| float func_17(float x, float y) { |
| #pragma STDC FENV_ROUND FE_DYNAMIC |
| #pragma STDC FENV_ACCESS ON |
| return x + y; |
| } |
| // CHECK-LABEL: @func_17 |
| // CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| |
| |
| float func_18(float x, float y) { |
| #pragma STDC FENV_ROUND FE_DYNAMIC |
| return x + y; |
| } |
| // CHECK-LABEL: @func_18 |
| // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") |
| // DEFAULT: fadd float |
| |
| #pragma STDC FENV_ACCESS ON |
| float func_19(float x, float y) { |
| return x + y; |
| } |
| // CHECK-LABEL: @func_19 |
| // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") |
| |
| #pragma STDC FENV_ACCESS OFF |
| float func_20(float x, float y) { |
| return x + y; |
| } |
| // CHECK-LABEL: @func_20 |
| // STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") |
| // DEFAULT: fadd float |