Don't treat dependent types as having a copy value representation. (#6055)

Add `Dependent` value and initializing representations for types whose
representations are unknown because they are dependent. When generating
SemIR in such cases, use a worst-case initializing representation that
both provides a destination address and also propagates a potential
result value.

Use this to fix incorrect lowering and lowering crashes for specific
functions involving generic types that don't use a copy value
representation.

In lowering, be careful to distinguish between whether the initializing
representation for the generic return type uses a return slot (which
affects whether the SemIR declaration and call have one) and whether the
initializing representation for the specific return type uses a return
slot (which affects whether the LLVM IR declaration and call have one).
This commit is contained in:
Richard Smith
2025-09-15 23:59:00 +00:00
committed by GitHub
parent ca40e9d693
commit b44ba47cf3
53 changed files with 1375 additions and 670 deletions
+14 -8
View File
@@ -357,6 +357,8 @@ auto FileContext::BuildFunctionTypeInfo(const SemIR::Function& function,
return {.type = llvm::FunctionType::get(
llvm::Type::getVoidTy(llvm_context()),
/*isVarArg=*/false)};
case SemIR::ValueRepr::Dependent:
CARBON_FATAL("Lowering function with dependent parameter type");
case SemIR::ValueRepr::None:
break;
case SemIR::ValueRepr::Copy:
@@ -630,10 +632,9 @@ auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id,
function_lowering.SetLocal(param_id, param_value);
};
// The subset of call_param_ids that is already in the order that the LLVM
// calling convention expects.
llvm::ArrayRef<SemIR::InstId> sequential_param_ids;
// Lower the return slot parameter.
if (declaration_function.return_slot_pattern_id.has_value()) {
auto call_param_id = call_param_ids.consume_back();
// The LLVM calling convention has the return slot first rather than last.
// Note that this queries whether there is a return slot at the LLVM level,
// whereas `function.return_slot_pattern_id.has_value()` queries whether
@@ -641,14 +642,19 @@ auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id,
if (SemIR::ReturnTypeInfo::ForFunction(sem_ir(), declaration_function,
specific_id)
.has_return_slot()) {
lower_param(call_param_ids.back());
lower_param(call_param_id);
} else {
// The return slot might still be mentioned as a destination location, but
// shouldn't actually be used for anything, so we can use a poison value
// for it.
function_lowering.SetLocal(call_param_id,
llvm::PoisonValue::get(llvm::PointerType::get(
llvm_context(), /*AddressSpace=*/0)));
}
sequential_param_ids = call_param_ids.drop_back();
} else {
sequential_param_ids = call_param_ids;
}
for (auto param_id : sequential_param_ids) {
// Lower the remaining call parameters.
for (auto param_id : call_param_ids) {
lower_param(param_id);
}