[clang] [clang] Allow `pragma float_control(precise, *)` to... (PR #105912)

Egor Chesakov via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 5 10:09:27 PDT 2024


================
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -disable-llvm-passes -emit-llvm -menable-no-infs -fapprox-func\
+// RUN: -funsafe-math-optimizations -fno-signed-zeros -mreassociate -freciprocal-math\
+// RUN: -ffp-contract=fast -ffast-math %s -o - | FileCheck %s
+
+float test_precise_off_select(int c) {
+#pragma float_control(precise, off)
+  return c ? 0.0f : 1.0f;
+}
+
+// CHECK-LABEL: test_precise_off_select
+// CHECK: select fast i1 {{%.+}}, float 0.000000e+00, float 1.000000e+00
+
+float test_precise_off_phi(int c, float t, float f) {
+#pragma float_control(precise, off)
+    return c ? t : f;
+}
+
+// CHECK-LABEL: test_precise_off_phi
+// CHECK: phi fast float [ {{%.+}}, {{%.+}} ], [ {{%.+}}, {{%.+}} ]
+
+float test_precise_on_select(int c) {
+#pragma float_control(precise, on)
+    return c ? 0.0f : 1.0f;
+}
+
+// CHECK-LABEL: test_precise_on_select
+// CHECK: select i1 {{%.+}}, float 0.000000e+00, float 1.000000e+00
+
+float test_precise_on_phi(int c, float t, float f) {
+#pragma float_control(precise, on)
+  return c ? t : f;
+}
+
----------------
echesakov wrote:

For "vector case" do you mean something along the lines of

```c
typedef float float2 __attribute__((ext_vector_type(2)));
typedef int int2 __attribute__((ext_vector_type(2)));

float2 foo(int2 c, float2 t, float2 f) {
#pragma float_control(precise, off)
    return c ? t : f;
}
```

In this case, the expression would be codegen-d to a sequence of bitwise operations and these are not affected by fast-math flags

```llvm
; Function Attrs: noinline nounwind optnone
define <2 x float> @foo(<2 x i32> noundef %c, <2 x float> noundef %t, <2 x float> noundef %f) #0 {
entry:
  %c.addr = alloca <2 x i32>, align 8
  %t.addr = alloca <2 x float>, align 8
  %f.addr = alloca <2 x float>, align 8
  store <2 x i32> %c, ptr %c.addr, align 8
  store <2 x float> %t, ptr %t.addr, align 8
  store <2 x float> %f, ptr %f.addr, align 8
  %0 = load <2 x i32>, ptr %c.addr, align 8
  %1 = load <2 x float>, ptr %t.addr, align 8
  %2 = load <2 x float>, ptr %f.addr, align 8
  %3 = icmp slt <2 x i32> %0, zeroinitializer
  %sext = sext <2 x i1> %3 to <2 x i32>
  %4 = xor <2 x i32> %sext, <i32 -1, i32 -1>
  %5 = bitcast <2 x float> %2 to <2 x i32>
  %6 = bitcast <2 x float> %1 to <2 x i32>
  %7 = and <2 x i32> %5, %4
  %8 = and <2 x i32> %6, %sext
  %cond = or <2 x i32> %7, %8
  %9 = bitcast <2 x i32> %cond to <2 x float>
  ret <2 x float> %9
}
```

Not really sure what I will be testing here?

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


More information about the cfe-commits mailing list