Repository: shader-slang/slang
File: source/slang/slang-ir-legalize-empty-array.cpp (C++)

Code before:
            // operand and produces a result value for the inst.
            [&](IRGetElement* getElement)
            {
                const auto base = getElement->getBase();
                return hasEmptyArrayType(base) ? builder.emitPoison(getElement->getDataType())
                                               : nullptr;
            },
            [&](IRGetElementPtr* gep)
            {
                const auto base = gep->getBase();
                return hasEmptyArrayPtrType(gep) || hasEmptyArrayPtrType(base) ||
                               as<IRUndefined>(base)
                           ? builder.emitPoison(gep->getDataType())
                           : nullptr;
            },
            [&](IRFieldAddress* gep)
            {
                const auto base = gep->getBase();
                return hasEmptyArrayPtrType(gep) || as<IRUndefined>(base)
                           ? builder.emitPoison(gep->getDataType())
                           : nullptr;
            },
            [&](IRLoad* load)
            {
                return as<IRUndefined>(load->getOperand(0))
                           ? builder.emitPoison(load->getDataType())
                           : nullptr;
            },
            [&](IRImageLoad* load)
            {
                return as<IRUndefined>(load->getOperand(0))
                           ? builder.emitPoison(load->getDataType())
                           : nullptr;
            },
            [&](IRStore* store)
            {
                if (as<IRUndefined>(store->getPtr()))
                    store->removeAndDeallocate();
                return nullptr;
            },
            [&](IRAtomicStore* store)
            {
                if (as<IRUndefined>(store->getPtr()))
                    store->removeAndDeallocate();
                return nullptr;
            },
            [&](IRImageStore* store)
            {
                if (as<IRUndefined>(store->getImage()))
                    store->removeAndDeallocate();
                return nullptr;

Review comment (suggestion):
we might need a general comment on this function to explain why emitting `emitPoison` for all the cases here.

Code after:
        //   (undefined) value. Note that they do not yield `LoadFromUninitializedMemory`
        //   because there is no guarantee that there would be anything in the
        //   memory corresponding to an index into an empty array.
        //
        // * Instructions that would try to read from an undefined pointer,
        //   buffer, image, etc. yield `poison`.
        //
        // * Instructions that would try to write to an undefined pointer,
        //   buffer, image, etc. are skipped (the behavior is undefined, so
        //   "do nothing" is a valid choice for the behavior, which has the
        //   nice side effect of potentially rendering other code redundant).
        //

        IRInst* replacement = nullptr;

        IRBuilder builder(module);
        builder.setInsertBefore(inst);
        replacement = instMatch<IRInst*>(
            inst,
            nullptr,
            // The following match instructions which take a 0-sized array as an
            // operand and produces a result value for the inst.
            [&](IRGetElement* getElement)
            {
                const auto base = getElement->getBase();
                return hasEmptyArrayType(base) ? builder.emitPoison(getElement->getDataType())
                                               : nullptr;
            },
            [&](IRGetElementPtr* gep)
            {
                const auto base = gep->getBase();
                return hasEmptyArrayPtrType(gep) || hasEmptyArrayPtrType(base) ||
                               as<IRUndefined>(base)
                           ? builder.emitPoison(gep->getDataType())
                           : nullptr;
            },
            [&](IRFieldAddress* gep)
            {
                const auto base = gep->getBase();
                return hasEmptyArrayPtrType(gep) || as<IRUndefined>(base)
                           ? builder.emitPoison(gep->getDataType())
                           : nullptr;
            },
            [&](IRLoad* load)
            {
                return as<IRUndefined>(load->getOperand(0))
                           ? builder.emitPoison(load->getDataType())
                           : nullptr;
            },
            [&](IRImageLoad* load)
            {