https://github.com/adams381 created 
https://github.com/llvm/llvm-project/pull/203617

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.


>From 94e605989c97ea1cab0aaa9eec0ef83640446c8b Mon Sep 17 00:00:00 2001
From: Adam Smith <[email protected]>
Date: Fri, 12 Jun 2026 12:41:55 -0700
Subject: [PATCH] [CIR] Fix const-array lowering for long double

The const-array lowering path in LoweringHelpers seeds a zero-filled
vector via getZeroInitFromType<APFloat> before writing the element
values, but that helper only handled cir::SingleType and cir::DoubleType
and asserted ("only float and double supported") on every other CIR
floating-point type.  A global array constant of long double (x86_fp80)
therefore crashed in CIR->LLVM lowering, even though classic codegen
lowers it without trouble (the SingleSource ieee-copysign2 case declares
exactly such an array).

Drive the zero from the element type's APFloat semantics through
cir::FPTypeInterface::getFloatSemantics(), the same way FPAttr::getZero
builds its value.  This covers float, double, long double, FP128, half,
and bfloat in one place.  The cast is unconditional because the only
caller reaches this helper through an isa<cir::FPTypeInterface> dispatch.
---
 clang/lib/CIR/Lowering/LoweringHelpers.cpp    | 12 ++------
 .../CIR/CodeGen/const-array-floating-point.c  | 30 +++++++++++++++++++
 2 files changed, 32 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/const-array-floating-point.c

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]

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to