[clang] [Clang] Honor '#pragma STDC FENV_ROUND' in __builtin_store_half/halff (PR #173821)
Wenju He via cfe-commits
cfe-commits at lists.llvm.org
Sat Jan 3 20:59:46 PST 2026
https://github.com/wenju-he updated https://github.com/llvm/llvm-project/pull/173821
>From 84478d7b427d32c5b9f24fc1f2b8e1d957563a96 Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Mon, 29 Dec 2025 06:19:00 +0100
Subject: [PATCH 1/2] [Clang] Honor '#pragma STDC FENV_ROUND' in
__builtin_store_half/halff
Before this change, constrained fptrunc for __builtin_store_half/halff
always used round.tonearest, ignoring the active pragma STDC FENV_ROUND.
This PR guards builtin emission with CGFPOptionsRAII so the current
rounding mode is propagated to the generated constrained intrinsic.
---
clang/lib/CodeGen/CGBuiltin.cpp | 1 +
...builtin-store-half-rounding-constrained.cl | 21 +++++++++++++++++++
2 files changed, 22 insertions(+)
create mode 100644 clang/test/CodeGenOpenCL/builtin-store-half-rounding-constrained.cl
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d3abf6d2a1f2d..0f9bed130a3b0 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -6199,6 +6199,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
}
case Builtin::BI__builtin_store_half:
case Builtin::BI__builtin_store_halff: {
+ CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
Value *Val = EmitScalarExpr(E->getArg(0));
Address Address = EmitPointerWithAlignment(E->getArg(1));
Value *HalfVal = Builder.CreateFPTrunc(Val, Builder.getHalfTy());
diff --git a/clang/test/CodeGenOpenCL/builtin-store-half-rounding-constrained.cl b/clang/test/CodeGenOpenCL/builtin-store-half-rounding-constrained.cl
new file mode 100644
index 0000000000000..a9334d22fe05f
--- /dev/null
+++ b/clang/test/CodeGenOpenCL/builtin-store-half-rounding-constrained.cl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -cl-std=cl3.0 -emit-llvm -o - -triple x86_64-unknown-unknown | FileCheck %s
+
+// CHECK-LABEL: @test_store_float(
+// CHECK: [[TMP0:%.*]] = tail call half @llvm.experimental.constrained.fptrunc.f16.f32(float {{.*}}, metadata !"round.upward", metadata !"fpexcept.ignore")
+// CHECK-NEXT: store half [[TMP0]], ptr {{.*}}, align 2
+// CHECK-NEXT: ret void
+//
+__kernel void test_store_float(float foo, __global half* bar) {
+ #pragma STDC FENV_ROUND FE_UPWARD
+ __builtin_store_halff(foo, bar);
+}
+
+// CHECK-LABEL: @test_store_double(
+// CHECK: [[TMP0:%.*]] = tail call half @llvm.experimental.constrained.fptrunc.f16.f64(double {{.*}}, metadata !"round.downward", metadata !"fpexcept.ignore")
+// CHECK-NEXT: store half [[TMP0]], ptr {{.*}}, align 2
+// CHECK-NEXT: ret void
+//
+__kernel void test_store_double(double foo, __global half* bar) {
+ #pragma STDC FENV_ROUND FE_DOWNWARD
+ __builtin_store_half(foo, bar);
+}
>From 5e6e9e30828888cba97010127e796364c245d238 Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Sun, 4 Jan 2026 05:55:40 +0100
Subject: [PATCH 2/2] add -disable-llvm-passes
---
.../builtin-store-half-rounding-constrained.cl | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/test/CodeGenOpenCL/builtin-store-half-rounding-constrained.cl b/clang/test/CodeGenOpenCL/builtin-store-half-rounding-constrained.cl
index a9334d22fe05f..ba3b3165e325a 100644
--- a/clang/test/CodeGenOpenCL/builtin-store-half-rounding-constrained.cl
+++ b/clang/test/CodeGenOpenCL/builtin-store-half-rounding-constrained.cl
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 %s -cl-std=cl3.0 -emit-llvm -o - -triple x86_64-unknown-unknown | FileCheck %s
+// RUN: %clang_cc1 %s -cl-std=cl3.0 -triple x86_64-unknown-unknown -disable-llvm-passes -emit-llvm -o - | FileCheck %s
// CHECK-LABEL: @test_store_float(
-// CHECK: [[TMP0:%.*]] = tail call half @llvm.experimental.constrained.fptrunc.f16.f32(float {{.*}}, metadata !"round.upward", metadata !"fpexcept.ignore")
+// CHECK: [[TMP0:%.*]] = call half @llvm.experimental.constrained.fptrunc.f16.f32(float {{.*}}, metadata !"round.upward", metadata !"fpexcept.ignore")
// CHECK-NEXT: store half [[TMP0]], ptr {{.*}}, align 2
// CHECK-NEXT: ret void
//
@@ -11,7 +11,7 @@ __kernel void test_store_float(float foo, __global half* bar) {
}
// CHECK-LABEL: @test_store_double(
-// CHECK: [[TMP0:%.*]] = tail call half @llvm.experimental.constrained.fptrunc.f16.f64(double {{.*}}, metadata !"round.downward", metadata !"fpexcept.ignore")
+// CHECK: [[TMP0:%.*]] = call half @llvm.experimental.constrained.fptrunc.f16.f64(double {{.*}}, metadata !"round.downward", metadata !"fpexcept.ignore")
// CHECK-NEXT: store half [[TMP0]], ptr {{.*}}, align 2
// CHECK-NEXT: ret void
//
More information about the cfe-commits
mailing list