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
