mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 16:01:05 +01:00
Propagate Carbon type alignments into LLVM IR. (#7290)
Use the Carbon-computed alignment for allocas, loads, stores, and memcpys. Previously we used whatever LLVM felt like giving us, which would result in ABI mismatches and runtime crashes due to misalignment when creating objects of imported C++ class types, as well as resulting in some surprising choices like `(i32, i32)` and `()` having 8-byte alignment instead of 4 and 1, respectively.
This commit is contained in:
@@ -201,7 +201,7 @@ auto FunctionContext::MakeSyntheticBlock() -> llvm::BasicBlock* {
|
||||
return synthetic_block_;
|
||||
}
|
||||
|
||||
auto FunctionContext::CreateAlloca(llvm::Type* type, const llvm::Twine& name)
|
||||
auto FunctionContext::CreateAlloca(TypeInFile type, const llvm::Twine& name)
|
||||
-> llvm::AllocaInst* {
|
||||
// Position the first alloca right before the start of the executable code in
|
||||
// the function.
|
||||
@@ -221,9 +221,8 @@ auto FunctionContext::CreateAlloca(llvm::Type* type, const llvm::Twine& name)
|
||||
builder().SetCurrentDebugLocation(debug_loc);
|
||||
|
||||
// Create an alloca for this variable in the entry block.
|
||||
// TODO: Compute alignment of the type, which may be greater than the
|
||||
// alignment computed by LLVM.
|
||||
alloca = builder().CreateAlloca(type, /*ArraySize=*/nullptr, name);
|
||||
alloca = builder().CreateAlloca(GetType(type), /*ArraySize=*/nullptr, name);
|
||||
alloca->setAlignment(GetAlignment(type));
|
||||
}
|
||||
|
||||
// Create a lifetime start intrinsic here to indicate where its scope really
|
||||
@@ -345,9 +344,11 @@ auto FunctionContext::LoadObject(TypeInFile type, llvm::Value* addr,
|
||||
auto* llvm_type = GetType(type);
|
||||
auto* load_type = GetWidenedMemoryType(llvm_type);
|
||||
|
||||
// TODO: Include alias and alignment information.
|
||||
llvm::Value* value = builder().CreateLoad(load_type, addr, name);
|
||||
// TODO: Include alias information.
|
||||
auto* load = builder().CreateLoad(load_type, addr, name);
|
||||
load->setAlignment(GetAlignment(type));
|
||||
|
||||
llvm::Value* value = load;
|
||||
if (load_type != llvm_type) {
|
||||
value = builder().CreateTrunc(value, llvm_type);
|
||||
}
|
||||
@@ -356,7 +357,6 @@ auto FunctionContext::LoadObject(TypeInFile type, llvm::Value* addr,
|
||||
|
||||
auto FunctionContext::StoreObject(TypeInFile type, llvm::Value* value,
|
||||
llvm::Value* addr) -> void {
|
||||
// TODO: Include alias and alignment information.
|
||||
auto* llvm_type = GetType(type);
|
||||
CARBON_CHECK(value->getType() == llvm_type);
|
||||
|
||||
@@ -367,7 +367,9 @@ auto FunctionContext::StoreObject(TypeInFile type, llvm::Value* value,
|
||||
value = builder().CreateZExt(value, store_type);
|
||||
}
|
||||
|
||||
builder().CreateStore(value, addr);
|
||||
// TODO: Include alias information.
|
||||
auto* store = builder().CreateStore(value, addr);
|
||||
store->setAlignment(GetAlignment(type));
|
||||
}
|
||||
|
||||
auto FunctionContext::CopyValue(TypeInFile type, SemIR::InstId source_id,
|
||||
@@ -394,9 +396,7 @@ auto FunctionContext::CopyObject(TypeInFile type, SemIR::InstId source_id,
|
||||
SemIR::InstId dest_id) -> void {
|
||||
const auto& layout = llvm_module().getDataLayout();
|
||||
auto* llvm_type = GetType(type);
|
||||
// TODO: Compute known alignment of the source and destination, which may
|
||||
// be greater than the alignment computed by LLVM.
|
||||
auto align = layout.getABITypeAlign(llvm_type);
|
||||
auto align = GetAlignment(type);
|
||||
|
||||
// TODO: Attach !tbaa.struct metadata indicating which portions of the
|
||||
// type we actually need to copy and which are padding.
|
||||
|
||||
Reference in New Issue
Block a user