Skip to content

Commit feaed8c

Browse files
committed
AI said to do this. I do not understand it yet. It likey does not work
1 parent e5caf4b commit feaed8c

File tree

1 file changed

+62
-4
lines changed

1 file changed

+62
-4
lines changed

crates/rustc_codegen_nvvm/src/builder.rs

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -430,11 +430,69 @@ impl<'ll, 'tcx, 'a> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
430430

431431
fn load(&mut self, ty: &'ll Type, ptr: &'ll Value, align: Align) -> &'ll Value {
432432
trace!("Load {ty:?} {:?}", ptr);
433-
let ptr = self.pointercast(ptr, self.cx.type_ptr_to(ty));
433+
// `ty` is the LLVM type of the data we want to load from memory (e.g., i64).
434+
// `ptr` is the LLVM value representing the memory address (e.g., could be an
435+
// i8* or already an i64*).
436+
437+
let original_ptr_llty = self.cx.val_ty(ptr);
438+
439+
// For LLVMBuildLoad in LLVM 7, the pointer operand must be PointeeType*, and
440+
// PointeeType is what will be loaded. So, `ptr` must be cast to `ty*`.
441+
let required_ptr_llty_for_load = self.cx.type_ptr_to(ty);
442+
443+
trace!(
444+
"Builder::load: Type to load: {:?}, Original ptr type: {:?}, Required ptr type for load: {:?}, align={:?}",
445+
ty,
446+
original_ptr_llty,
447+
required_ptr_llty_for_load,
448+
align.bytes()
449+
);
450+
451+
// Sanity check: ptr must be a pointer type.
452+
assert_eq!(
453+
self.cx.type_kind(original_ptr_llty),
454+
TypeKind::Pointer,
455+
"Attempting to load from a non-pointer LLVM value. Original type: {:?}. Required load type: {:?}",
456+
original_ptr_llty,
457+
ty
458+
);
459+
460+
let final_ptr_for_llvm_load = if original_ptr_llty == required_ptr_llty_for_load {
461+
// The pointer is already correctly typed (e.g., loading i64 from an i64*).
462+
ptr
463+
} else {
464+
// The pointer type needs adjustment (e.g., ptr is an i8*, but we need to load an i64).
465+
// We must bitcast ptr to required_ptr_llty_for_load (e.g., i64*).
466+
debug!(
467+
"Builder::load: Pointer type mismatch. \
468+
Type to load: {:?}, Original pointer type: {:?}, Required pointer type for load: {:?}. \
469+
Injecting bitcast for pointer operand.",
470+
ty, original_ptr_llty, required_ptr_llty_for_load
471+
);
472+
self.bitcast(ptr, required_ptr_llty_for_load)
473+
};
474+
475+
// Now, final_ptr_for_llvm_load is guaranteed to be of type `ty*`.
476+
// The LLVM 7 `LLVMBuildLoad` C-API infers the type of the value to be loaded
477+
// from the pointee type of its pointer argument.
434478
unsafe {
435-
let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, UNNAMED);
436-
llvm::LLVMSetAlignment(load, align.bytes() as c_uint);
437-
load
479+
let load_instr = llvm::LLVMBuildLoad(self.llbuilder, final_ptr_for_llvm_load, UNNAMED);
480+
481+
// Sanity check: the type of the loaded value should match `ty`.
482+
let actual_loaded_llty = self.cx.val_ty(load_instr);
483+
if actual_loaded_llty != ty {
484+
bug!(
485+
"Builder::load: LLVMBuildLoad produced a value of type ({:?}) which does not match the expected `ty` parameter ({:?}). \
486+
Pointer type passed to LLVMBuildLoad was: {:?}, after casting from original: {:?}.",
487+
actual_loaded_llty,
488+
ty,
489+
final_ptr_for_llvm_load,
490+
original_ptr_llty
491+
);
492+
}
493+
494+
llvm::LLVMSetAlignment(load_instr, align.bytes() as c_uint);
495+
load_instr
438496
}
439497
}
440498

0 commit comments

Comments
 (0)