Don't use global initializer if type does not match

This was relying on the presence of a bitcast to avoid using the
constant global initializer for a load using a different type.
With opaque pointers, we need to check this explicitly.
This commit is contained in:
Nikita Popov 2022-02-21 11:11:48 +01:00
parent b2eba058e6
commit 373789b059

View File

@ -509,15 +509,20 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
OperandValue::Ref(place.llval, Some(llextra), place.align) OperandValue::Ref(place.llval, Some(llextra), place.align)
} else if place.layout.is_llvm_immediate() { } else if place.layout.is_llvm_immediate() {
let mut const_llval = None; let mut const_llval = None;
let llty = place.layout.llvm_type(self);
unsafe { unsafe {
if let Some(global) = llvm::LLVMIsAGlobalVariable(place.llval) { if let Some(global) = llvm::LLVMIsAGlobalVariable(place.llval) {
if llvm::LLVMIsGlobalConstant(global) == llvm::True { if llvm::LLVMIsGlobalConstant(global) == llvm::True {
const_llval = llvm::LLVMGetInitializer(global); if let Some(init) = llvm::LLVMGetInitializer(global) {
if self.val_ty(init) == llty {
const_llval = Some(init);
}
}
} }
} }
} }
let llval = const_llval.unwrap_or_else(|| { let llval = const_llval.unwrap_or_else(|| {
let load = self.load(place.layout.llvm_type(self), place.llval, place.align); let load = self.load(llty, place.llval, place.align);
if let abi::Abi::Scalar(scalar) = place.layout.abi { if let abi::Abi::Scalar(scalar) = place.layout.abi {
scalar_load_metadata(self, load, scalar, place.layout, Size::ZERO); scalar_load_metadata(self, load, scalar, place.layout, Size::ZERO);
} }