[clang] [CIR] Fix const-array lowering for long double (PR #203617)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 12 12:55:10 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: adams381
<details>
<summary>Changes</summary>
A global array constant of `long double` crashes CIR's lowering to LLVM.
`getZeroInitFromType<APFloat>` in LoweringHelpers seeds a zero-filled vector
for the const-array path but only handled `SingleType`/`DoubleType`, asserting
"only float and double supported" on every other CIR floating-point type. The
const-array dispatch already routes any `cir::FPTypeInterface` element type into
`getZeroInitFromType<APFloat>`, so `long double` (`x86_fp80`) hit the assert even
though classic codegen lowers it fine. The SingleSource ieee-copysign2 test
exercises exactly this.
The fix derives the zero from the element type's APFloat semantics via
`cir::FPTypeInterface::getFloatSemantics()`, the same construction `FPAttr::getZero`
uses, which covers float, double, long double, FP128, half, and bfloat. The test
pins all of those against classic codegen output.
---
Full diff: https://github.com/llvm/llvm-project/pull/203617.diff
2 Files Affected:
- (modified) clang/lib/CIR/Lowering/LoweringHelpers.cpp (+2-10)
- (added) clang/test/CIR/CodeGen/const-array-floating-point.c (+30)
``````````diff
diff --git a/clang/lib/CIR/Lowering/LoweringHelpers.cpp b/clang/lib/CIR/Lowering/LoweringHelpers.cpp
index b903560ada18f..92e64e188633e 100644
--- a/clang/lib/CIR/Lowering/LoweringHelpers.cpp
+++ b/clang/lib/CIR/Lowering/LoweringHelpers.cpp
@@ -58,16 +58,8 @@ template <> mlir::APInt getZeroInitFromType(mlir::Type ty) {
}
template <> mlir::APFloat getZeroInitFromType(mlir::Type ty) {
- assert((mlir::isa<cir::SingleType, cir::DoubleType>(ty)) &&
- "only float and double supported");
-
- if (ty.isF32() || mlir::isa<cir::SingleType>(ty))
- return mlir::APFloat(0.f);
-
- if (ty.isF64() || mlir::isa<cir::DoubleType>(ty))
- return mlir::APFloat(0.0);
-
- llvm_unreachable("NYI");
+ auto fpTy = mlir::cast<cir::FPTypeInterface>(ty);
+ return mlir::APFloat::getZero(fpTy.getFloatSemantics());
}
/// \param attr the ConstArrayAttr to convert
diff --git a/clang/test/CIR/CodeGen/const-array-floating-point.c b/clang/test/CIR/CodeGen/const-array-floating-point.c
new file mode 100644
index 0000000000000..e09f7c2e83dfc
--- /dev/null
+++ b/clang/test/CIR/CodeGen/const-array-floating-point.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
+
+long double ld_arr[3] = {1.0, -2.0, 0.0};
+long double ld_zero[4] = {0};
+__float128 q_arr[3] = {1.0, -2.0, 0.0};
+_Float16 h_arr[3] = {1.0, -2.0, 0.0};
+__bf16 bf_arr[3] = {1.0, -2.0, 0.0};
+float f_arr[3] = {1.0, -2.0, 0.0};
+double d_arr[3] = {1.0, -2.0, 0.0};
+
+// CIR-DAG: cir.global external @ld_arr = #cir.const_array<[#cir.fp<1.000000e+00> : !cir.long_double<!cir.f80>, #cir.fp<-2.000000e+00> : !cir.long_double<!cir.f80>, #cir.fp<0.000000e+00> : !cir.long_double<!cir.f80>]> : !cir.array<!cir.long_double<!cir.f80> x 3>
+// CIR-DAG: cir.global external @ld_zero = #cir.zero : !cir.array<!cir.long_double<!cir.f80> x 4>
+// CIR-DAG: cir.global external @q_arr = #cir.const_array<[#cir.fp<1.000000e+00> : !cir.f128, #cir.fp<-2.000000e+00> : !cir.f128, #cir.fp<0.000000e+00> : !cir.f128]> : !cir.array<!cir.f128 x 3>
+// CIR-DAG: cir.global external @h_arr = #cir.const_array<[#cir.fp<1.000000e+00> : !cir.f16, #cir.fp<-2.000000e+00> : !cir.f16, #cir.fp<0.000000e+00> : !cir.f16]> : !cir.array<!cir.f16 x 3>
+// CIR-DAG: cir.global external @bf_arr = #cir.const_array<[#cir.fp<1.000000e+00> : !cir.bf16, #cir.fp<-2.000000e+00> : !cir.bf16, #cir.fp<0.000000e+00> : !cir.bf16]> : !cir.array<!cir.bf16 x 3>
+// CIR-DAG: cir.global external @f_arr = #cir.const_array<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<-2.000000e+00> : !cir.float, #cir.fp<0.000000e+00> : !cir.float]> : !cir.array<!cir.float x 3>
+// CIR-DAG: cir.global external @d_arr = #cir.const_array<[#cir.fp<1.000000e+00> : !cir.double, #cir.fp<-2.000000e+00> : !cir.double, #cir.fp<0.000000e+00> : !cir.double]> : !cir.array<!cir.double x 3>
+
+// LLVM-DAG: @ld_arr = global [3 x x86_fp80] [x86_fp80 1.000000e+00, x86_fp80 -2.000000e+00, x86_fp80 0.000000e+00]
+// LLVM-DAG: @ld_zero = global [4 x x86_fp80] zeroinitializer
+// LLVM-DAG: @q_arr = global [3 x fp128] [fp128 1.000000e+00, fp128 -2.000000e+00, fp128 0.000000e+00]
+// LLVM-DAG: @h_arr = global [3 x half] [half 1.000000e+00, half -2.000000e+00, half 0.000000e+00]
+// LLVM-DAG: @bf_arr = global [3 x bfloat] [bfloat 1.000000e+00, bfloat -2.000000e+00, bfloat 0.000000e+00]
+// LLVM-DAG: @f_arr = global [3 x float] [float 1.000000e+00, float -2.000000e+00, float 0.000000e+00]
+// LLVM-DAG: @d_arr = global [3 x double] [double 1.000000e+00, double -2.000000e+00, double 0.000000e+00]
``````````
</details>
https://github.com/llvm/llvm-project/pull/203617
More information about the cfe-commits
mailing list