Skip to content

Commit ce75414

Browse files
committed
Add check_load to ensure load operations have correct pointer types
Similar to check_store, we need to ensure that load operations also have the correct pointer types for LLVM 7. This adds check_load which bitcasts pointers to match the type being loaded, fixing potential type mismatches in both regular and volatile loads.
1 parent b89e3d5 commit ce75414

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

crates/rustc_codegen_nvvm/src/builder.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,8 @@ 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+
// For LLVM 7, ensure the pointer type matches what we're loading
434+
let ptr = self.check_load(ty, ptr);
434435
unsafe {
435436
let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, UNNAMED);
436437
llvm::LLVMSetAlignment(load, align.bytes() as c_uint);
@@ -440,7 +441,8 @@ impl<'ll, 'tcx, 'a> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
440441

441442
fn volatile_load(&mut self, ty: &'ll Type, ptr: &'ll Value) -> &'ll Value {
442443
trace!("Volatile load `{:?}`", ptr);
443-
let ptr = self.pointercast(ptr, self.cx.type_ptr_to(ty));
444+
// For LLVM 7, ensure the pointer type matches what we're loading
445+
let ptr = self.check_load(ty, ptr);
444446
unsafe {
445447
let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, UNNAMED);
446448
llvm::LLVMSetVolatile(load, llvm::True);
@@ -1188,6 +1190,34 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
11881190

11891191
fn noundef_metadata(&mut self, _load: &'ll Value) {}
11901192

1193+
fn check_load(&mut self, ty: &'ll Type, ptr: &'ll Value) -> &'ll Value {
1194+
// For LLVM 7, ensure the pointer type matches what we're loading
1195+
let ptr_ty = self.cx.val_ty(ptr);
1196+
1197+
// Check if this is a pointer type
1198+
if self.cx.type_kind(ptr_ty) != TypeKind::Pointer {
1199+
return ptr;
1200+
}
1201+
1202+
// Get what the pointer points to
1203+
let pointee_ty = self.cx.element_type(ptr_ty);
1204+
1205+
// If types match, no conversion needed
1206+
if pointee_ty == ty {
1207+
return ptr;
1208+
}
1209+
1210+
// We need to bitcast the pointer to the correct type
1211+
let needed_ptr_ty = self.cx.type_ptr_to(ty);
1212+
trace!(
1213+
"check_load: bitcasting pointer from {:?} (pointing to {:?}) to {:?} (pointing to {:?})",
1214+
ptr_ty, pointee_ty, needed_ptr_ty, ty
1215+
);
1216+
1217+
// Use direct LLVM bitcast
1218+
unsafe { llvm::LLVMBuildBitCast(self.llbuilder, ptr, needed_ptr_ty, unnamed()) }
1219+
}
1220+
11911221
fn check_store(&mut self, val: &'ll Value, ptr: &'ll Value) -> &'ll Value {
11921222
// In LLVM 7, we need to ensure the pointer type matches what we're storing
11931223
let val_ty = self.cx.val_ty(val);

0 commit comments

Comments
 (0)