[flang-commits] [flang] [flang] Fix ICE when lowering IBM vector() array through fir.box (PR #214219)
via flang-commits
flang-commits at lists.llvm.org
Wed Aug 5 05:46:06 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Daniel Chen (DanielCChen)
<details>
<summary>Changes</summary>
Fixes PR #<!-- -->214178
When compiling IBM vector extension types through a `fir.box` descriptor at `-O0`, the compiler crashed with two separate internal errors:
- `getTypeCode()` in `FIRType.cpp` hit `llvm_unreachable("unsupported type")`
- `getSizeAndTypeCode()` in `CodeGen.cpp` hit `fir::emitFatalError()`
Both functions failed because neither handled `fir::VectorType` as a `fir.box` element type.
This PR is to fix:
- `FIRType.cpp` — `getTypeCode()`: add a `fir::VectorType` check that returns `CFI_type_other`. IBM vector extension types have no ISO CFI type code; `CFI_type_other` is the standard fallback for non-interoperable types.
- `CodeGen.cpp` — `getSizeAndTypeCode()`: add a `fir::VectorType` branch that computes the stride via `genTypeStrideInBytes` (identical to the existing `fir::RecordType` branch), so `fir.embox` of `!fir.array<Nx!fir.vector<...>>` generates correct descriptor metadata.
---
Full diff: https://github.com/llvm/llvm-project/pull/214219.diff
3 Files Affected:
- (modified) flang/lib/Optimizer/CodeGen/CodeGen.cpp (+4)
- (modified) flang/lib/Optimizer/Dialect/FIRType.cpp (+5)
- (added) flang/test/Lower/PowerPC/ppc-vec-array-box.f90 (+34)
``````````diff
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 55c6afee45996..d0c6c3eb3520d 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -1820,6 +1820,10 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
return {genTypeStrideInBytes(loc, i64Ty, rewriter, ptrTy, dataLayout),
typeCodeVal};
}
+ if (mlir::isa<fir::VectorType>(boxEleTy))
+ return {genTypeStrideInBytes(loc, i64Ty, rewriter,
+ this->convertType(boxEleTy), dataLayout),
+ typeCodeVal};
if (mlir::isa<fir::RecordType>(boxEleTy))
return {genTypeStrideInBytes(loc, i64Ty, rewriter,
this->convertType(boxEleTy), dataLayout),
diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 178860239e17d..a6aab32d6af15 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -586,6 +586,11 @@ int getTypeCode(mlir::Type ty, const fir::KindMapping &kindMap) {
return CFI_type_cptr;
if (mlir::isa<fir::RecordType>(ty))
return CFI_type_struct;
+ // fir::VectorType is used in IBM Fortran vector() extension type as a
+ // fir.box element type. There is no CFI type for it; CFI_type_other is the
+ // standard fallback for non-interoperable types.
+ if (mlir::isa<fir::VectorType>(ty))
+ return CFI_type_other;
llvm_unreachable("unsupported type");
}
diff --git a/flang/test/Lower/PowerPC/ppc-vec-array-box.f90 b/flang/test/Lower/PowerPC/ppc-vec-array-box.f90
new file mode 100644
index 0000000000000..abcee8cff257a
--- /dev/null
+++ b/flang/test/Lower/PowerPC/ppc-vec-array-box.f90
@@ -0,0 +1,34 @@
+! RUN: %flang_fc1 -triple powerpc64-ibm-aix7.2.0.0 -emit-fir -o - %s | FileCheck %s --check-prefix=FIR
+! RUN: %flang_fc1 -triple powerpc64-ibm-aix7.2.0.0 -emit-llvm -O0 -o - %s | FileCheck %s --check-prefix=LLVMIR
+! REQUIRES: target=powerpc{{.*}}
+
+! Test that merge() on an array of IBM vector() type lowers correctly through
+! a fir.box descriptor at -O0.
+!
+! At -O0, HLFIR bufferization creates a temporary array and wraps it in a
+! fir.box<!fir.array<Nx!fir.vector<...>>>. Before the fix, both:
+! - getTypeCode() in FIRType.cpp hit llvm_unreachable("unsupported type")
+! - getSizeAndTypeCode() in CodeGen.cpp hit fir::emitFatalError(...)
+! because neither handled fir::VectorType as a fir.box element type.
+!
+! At -O3, hlfir::createInlineHLFIRCopy inlines the copy element-by-element,
+! avoiding the fir.box entirely, which is why -O3 always passed.
+
+subroutine vec_merge_array(va, vb, mask, res)
+ vector(integer(4)), intent(in) :: va(2), vb(2)
+ logical, intent(in) :: mask(2)
+ vector(integer(4)), intent(out) :: res(2)
+ res = merge(va, vb, mask)
+end subroutine
+
+! FIR-LABEL: func.func @_QPvec_merge_array
+
+! Verify the temporary array and its fir.embox are generated with
+! fir.vector<4:i32> as the element type — this is the type that previously
+! triggered the ICE in getTypeCode() and getSizeAndTypeCode().
+! FIR: fir.allocmem !fir.array<2x!fir.vector<4:i32>>
+! FIR: fir.embox {{.*}} : ({{.*}}!fir.array<2x!fir.vector<4:i32>>{{.*}}) -> !fir.box<!fir.array<2x!fir.vector<4:i32>>>
+
+! LLVMIR-LABEL: define void @vec_merge_array_
+! Verify CodeGen completes and produces correct vector stores.
+! LLVMIR: store <4 x i32>
``````````
</details>
https://github.com/llvm/llvm-project/pull/214219
More information about the flang-commits
mailing list