[llvm] [SPIRV] Add legalization pass for zero-size arrays (PR #172367)
Steven Perron via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 16 10:36:44 PST 2025
================
@@ -0,0 +1,334 @@
+//===- SPIRVLegalizeZeroSizeArrays.cpp - Legalize zero-size arrays -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// SPIR-V does not support zero-size arrays unless it is within a shader. This
+// pass legalizes zero-size arrays ([0 x T]) in unsupported cases.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SPIRVLegalizeZeroSizeArrays.h"
+#include "SPIRV.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/InstVisitor.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/TargetParser/Triple.h"
+
+#define DEBUG_TYPE "spirv-legalize-zero-size-arrays"
+
+using namespace llvm;
+
+namespace {
+
+bool hasZeroSizeArray(const Type *Ty) {
+ if (const ArrayType *ArrTy = dyn_cast<ArrayType>(Ty)) {
+ if (ArrTy->getNumElements() == 0)
+ return true;
+ return hasZeroSizeArray(ArrTy->getElementType());
+ }
+
+ if (const StructType *StructTy = dyn_cast<StructType>(Ty)) {
+ for (Type *ElemTy : StructTy->elements()) {
+ if (hasZeroSizeArray(ElemTy))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+class SPIRVLegalizeZeroSizeArraysImpl
+ : public InstVisitor<SPIRVLegalizeZeroSizeArraysImpl> {
+ friend class InstVisitor<SPIRVLegalizeZeroSizeArraysImpl>;
+
+public:
+ bool runOnModule(Module &M);
+
+ // TODO: Handle GEP, PHI
+ void visitAllocaInst(AllocaInst &AI);
+ void visitLoadInst(LoadInst &LI);
+ void visitStoreInst(StoreInst &SI);
+ void visitSelectInst(SelectInst &Sel);
+ void visitExtractValueInst(ExtractValueInst &EVI);
+ void visitInsertValueInst(InsertValueInst &IVI);
+
+private:
+ Type *legalizeType(Type *Ty);
+ Constant *legalizeConstant(Constant *C);
+
+ DenseMap<Type *, Type *> TypeMap;
+ DenseMap<GlobalVariable *, GlobalVariable *> GlobalMap;
+ SmallVector<Instruction *, 16> ToErase;
+ bool Modified = false;
+};
+
+class SPIRVLegalizeZeroSizeArraysLegacy : public ModulePass {
+public:
+ static char ID;
+ SPIRVLegalizeZeroSizeArraysLegacy() : ModulePass(ID) {}
+ StringRef getPassName() const override {
+ return "SPIRV Legalize Zero-Size Arrays";
+ }
+ bool runOnModule(Module &M) override {
+ SPIRVLegalizeZeroSizeArraysImpl Impl;
+ return Impl.runOnModule(M);
+ }
+};
+
+Type *SPIRVLegalizeZeroSizeArraysImpl::legalizeType(Type *Ty) {
+ auto It = TypeMap.find(Ty);
+ if (It != TypeMap.end())
+ return It->second;
+
+ Type *LegalizedTy = Ty;
+
+ if (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty)) {
+ if (ArrTy->getNumElements() == 0) {
+ LegalizedTy = PointerType::getUnqual(Ty->getContext());
----------------
s-perron wrote:
This is not a obvious change. Add a comment to explain what is going on.
https://github.com/llvm/llvm-project/pull/172367
More information about the llvm-commits
mailing list