llvm: Accept new LLVM lifetime format

LLVM removed the size parameter from the lifetime format.
Tolerate not having that size parameter.
This commit is contained in:
Matthew Maurer 2025-08-08 17:38:03 +00:00
parent 2886b36df4
commit 258915a555
8 changed files with 42 additions and 38 deletions

View file

@ -1686,7 +1686,11 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
return;
}
self.call_intrinsic(intrinsic, &[self.val_ty(ptr)], &[self.cx.const_u64(size), ptr]);
if crate::llvm_util::get_version() >= (22, 0, 0) {
self.call_intrinsic(intrinsic, &[self.val_ty(ptr)], &[ptr]);
} else {
self.call_intrinsic(intrinsic, &[self.val_ty(ptr)], &[self.cx.const_u64(size), ptr]);
}
}
}
impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {

View file

@ -55,10 +55,10 @@ extern "C" {
pub unsafe fn rust_to_c_increases_alignment(x: Align1) {
// i686-linux: start:
// i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca [48 x i8], align 4
// i686-linux-NEXT: call void @llvm.lifetime.start.p0(i64 48, ptr {{.*}}[[ALLOCA]])
// i686-linux-NEXT: call void @llvm.lifetime.start.p0({{(i64 48, )?}}ptr {{.*}}[[ALLOCA]])
// i686-linux-NEXT: call void @llvm.memcpy.{{.+}}(ptr {{.*}}align 4 {{.*}}[[ALLOCA]], ptr {{.*}}align 1 {{.*}}%x
// i686-linux-NEXT: call void @extern_c_align1({{.+}} [[ALLOCA]])
// i686-linux-NEXT: call void @llvm.lifetime.end.p0(i64 48, ptr {{.*}}[[ALLOCA]])
// i686-linux-NEXT: call void @llvm.lifetime.end.p0({{(i64 48, )?}}ptr {{.*}}[[ALLOCA]])
// x86_64-linux: start:
// x86_64-linux-NEXT: call void @extern_c_align1

View file

@ -16,14 +16,14 @@ use minicore::*;
// CHECK-NEXT: start:
// CHECK-NEXT: [[B:%.*]] = alloca
// CHECK-NEXT: [[A:%.*]] = alloca
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4096, ptr [[A]])
// CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 4096, )?}}ptr [[A]])
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 4096, i1 false)
// CHECK-NEXT: call void %h(ptr {{.*}} [[A]])
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4096, ptr [[A]])
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4096, ptr [[B]])
// CHECK-NEXT: call void @llvm.lifetime.end.p0({{(i64 4096, )?}}ptr [[A]])
// CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 4096, )?}}ptr [[B]])
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[B]], ptr align 4 {{.*}}, i32 4096, i1 false)
// CHECK-NEXT: call void %h(ptr {{.*}} [[B]])
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4096, ptr [[B]])
// CHECK-NEXT: call void @llvm.lifetime.end.p0({{(i64 4096, )?}}ptr [[B]])
#[no_mangle]
pub fn const_indirect(h: extern "C" fn([u32; 1024])) {
const C: [u32; 1024] = [0; 1024];
@ -42,12 +42,12 @@ pub struct Str {
// CHECK-LABEL: define void @immediate_indirect(ptr {{.*}}%s.0, i32 {{.*}}%s.1, ptr {{.*}}%g)
// CHECK-NEXT: start:
// CHECK-NEXT: [[A:%.*]] = alloca
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[A]])
// CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr [[A]])
// CHECK-NEXT: store ptr %s.0, ptr [[A]]
// CHECK-NEXT: [[B:%.]] = getelementptr inbounds i8, ptr [[A]], i32 4
// CHECK-NEXT: store i32 %s.1, ptr [[B]]
// CHECK-NEXT: call void %g(ptr {{.*}} [[A]])
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[A]])
// CHECK-NEXT: call void @llvm.lifetime.end.p0({{(i64 8, )?}}ptr [[A]])
#[no_mangle]
pub fn immediate_indirect(s: Str, g: extern "C" fn(Str)) {
g(s);
@ -58,10 +58,10 @@ pub fn immediate_indirect(s: Str, g: extern "C" fn(Str)) {
// CHECK-LABEL: define void @align_indirect(ptr{{.*}} align 1{{.*}} %a, ptr{{.*}} %fun)
// CHECK-NEXT: start:
// CHECK-NEXT: [[A:%.*]] = alloca [1024 x i8], align 4
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 1024, ptr [[A]])
// CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 1024, )?}}ptr [[A]])
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 1 %a, i32 1024, i1 false)
// CHECK-NEXT: call void %fun(ptr {{.*}} [[A]])
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 1024, ptr [[A]])
// CHECK-NEXT: call void @llvm.lifetime.end.p0({{(i64 1024, )?}}ptr [[A]])
#[no_mangle]
pub fn align_indirect(a: [u8; 1024], fun: extern "C" fn([u8; 1024])) {
fun(a);

View file

@ -97,10 +97,10 @@ pub extern "C" fn float_ptr_same_lanes(v: f64x2) -> PtrX2 {
// CHECK-NOT: alloca
// CHECK: %[[TEMP:.+]] = alloca [16 x i8]
// CHECK-NOT: alloca
// CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.start.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: store <2 x double> %v, ptr %[[TEMP]]
// CHECK: %[[RET:.+]] = load <2 x ptr>, ptr %[[TEMP]]
// CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.end.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: ret <2 x ptr> %[[RET]]
unsafe { transmute(v) }
}
@ -111,10 +111,10 @@ pub extern "C" fn ptr_float_same_lanes(v: PtrX2) -> f64x2 {
// CHECK-NOT: alloca
// CHECK: %[[TEMP:.+]] = alloca [16 x i8]
// CHECK-NOT: alloca
// CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.start.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: store <2 x ptr> %v, ptr %[[TEMP]]
// CHECK: %[[RET:.+]] = load <2 x double>, ptr %[[TEMP]]
// CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.end.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: ret <2 x double> %[[RET]]
unsafe { transmute(v) }
}
@ -125,10 +125,10 @@ pub extern "C" fn int_ptr_same_lanes(v: i64x2) -> PtrX2 {
// CHECK-NOT: alloca
// CHECK: %[[TEMP:.+]] = alloca [16 x i8]
// CHECK-NOT: alloca
// CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.start.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: store <2 x i64> %v, ptr %[[TEMP]]
// CHECK: %[[RET:.+]] = load <2 x ptr>, ptr %[[TEMP]]
// CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.end.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: ret <2 x ptr> %[[RET]]
unsafe { transmute(v) }
}
@ -139,10 +139,10 @@ pub extern "C" fn ptr_int_same_lanes(v: PtrX2) -> i64x2 {
// CHECK-NOT: alloca
// CHECK: %[[TEMP:.+]] = alloca [16 x i8]
// CHECK-NOT: alloca
// CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.start.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: store <2 x ptr> %v, ptr %[[TEMP]]
// CHECK: %[[RET:.+]] = load <2 x i64>, ptr %[[TEMP]]
// CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.end.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: ret <2 x i64> %[[RET]]
unsafe { transmute(v) }
}
@ -153,10 +153,10 @@ pub extern "C" fn float_ptr_widen(v: f32x4) -> PtrX2 {
// CHECK-NOT: alloca
// CHECK: %[[TEMP:.+]] = alloca [16 x i8]
// CHECK-NOT: alloca
// CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.start.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: store <4 x float> %v, ptr %[[TEMP]]
// CHECK: %[[RET:.+]] = load <2 x ptr>, ptr %[[TEMP]]
// CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.end.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: ret <2 x ptr> %[[RET]]
unsafe { transmute(v) }
}
@ -167,10 +167,10 @@ pub extern "C" fn int_ptr_widen(v: i32x4) -> PtrX2 {
// CHECK-NOT: alloca
// CHECK: %[[TEMP:.+]] = alloca [16 x i8]
// CHECK-NOT: alloca
// CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.start.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: store <4 x i32> %v, ptr %[[TEMP]]
// CHECK: %[[RET:.+]] = load <2 x ptr>, ptr %[[TEMP]]
// CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.end.p0({{(i64 16, )?}}ptr %[[TEMP]])
// CHECK: ret <2 x ptr> %[[RET]]
unsafe { transmute(v) }
}

View file

@ -192,12 +192,12 @@ pub unsafe fn check_byte_from_bool(x: bool) -> u8 {
#[no_mangle]
pub unsafe fn check_to_pair(x: u64) -> Option<i32> {
// CHECK: %[[TEMP:.+]] = alloca [8 x i8], align 8
// CHECK: call void @llvm.lifetime.start.p0(i64 8, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %[[TEMP]])
// CHECK: store i64 %x, ptr %[[TEMP]], align 8
// CHECK: %[[PAIR0:.+]] = load i32, ptr %[[TEMP]], align 8
// CHECK: %[[PAIR1P:.+]] = getelementptr inbounds i8, ptr %[[TEMP]], i64 4
// CHECK: %[[PAIR1:.+]] = load i32, ptr %[[PAIR1P]], align 4
// CHECK: call void @llvm.lifetime.end.p0(i64 8, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.end.p0({{(i64 8, )?}}ptr %[[TEMP]])
// CHECK: insertvalue {{.+}}, i32 %[[PAIR0]], 0
// CHECK: insertvalue {{.+}}, i32 %[[PAIR1]], 1
transmute(x)
@ -207,12 +207,12 @@ pub unsafe fn check_to_pair(x: u64) -> Option<i32> {
#[no_mangle]
pub unsafe fn check_from_pair(x: Option<i32>) -> u64 {
// CHECK: %[[TEMP:.+]] = alloca [8 x i8], align 8
// CHECK: call void @llvm.lifetime.start.p0(i64 8, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %[[TEMP]])
// CHECK: store i32 %x.0, ptr %[[TEMP]], align 8
// CHECK: %[[PAIR1P:.+]] = getelementptr inbounds i8, ptr %[[TEMP]], i64 4
// CHECK: store i32 %x.1, ptr %[[PAIR1P]], align 4
// CHECK: %[[R:.+]] = load i64, ptr %[[TEMP]], align 8
// CHECK: call void @llvm.lifetime.end.p0(i64 8, ptr %[[TEMP]])
// CHECK: call void @llvm.lifetime.end.p0({{(i64 8, )?}}ptr %[[TEMP]])
// CHECK: ret i64 %[[R]]
transmute(x)
}

View file

@ -19,6 +19,6 @@ pub fn outer_function(x: S, y: S) -> usize {
// CHECK: [[spill:%.*]] = alloca
// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds i8, ptr [[spill]]
// CHECK-NOT: [[load:%.*]] = load ptr, ptr
// CHECK: call void @llvm.lifetime.start{{.*}}({{.*}}, ptr [[spill]])
// CHECK: call void @llvm.lifetime.start{{.*}}({{(.*, )?}}ptr [[spill]])
// CHECK: [[inner:%.*]] = getelementptr inbounds i8, ptr [[spill]]
// CHECK: call void @llvm.memcpy{{.*}}(ptr {{align .*}} [[inner]], ptr {{align .*}} %x

View file

@ -8,27 +8,27 @@ pub fn test() {
let a = 0u8;
&a; // keep variable in an alloca
// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, ptr %a)
// CHECK: call void @llvm.lifetime.start{{.*}}({{(i[0-9 ]+, )?}}ptr %a)
{
let b = &Some(a);
&b; // keep variable in an alloca
// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, {{.*}})
// CHECK: call void @llvm.lifetime.start{{.*}}({{(i[0-9 ]+, )?}}{{.*}})
// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, {{.*}})
// CHECK: call void @llvm.lifetime.start{{.*}}({{(i[0-9 ]+, )?}}{{.*}})
// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, {{.*}})
// CHECK: call void @llvm.lifetime.end{{.*}}({{(i[0-9 ]+, )?}}{{.*}})
// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, {{.*}})
// CHECK: call void @llvm.lifetime.end{{.*}}({{(i[0-9 ]+, )?}}{{.*}})
}
let c = 1u8;
&c; // keep variable in an alloca
// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, ptr %c)
// CHECK: call void @llvm.lifetime.start{{.*}}({{(i[0-9 ]+, )?}}ptr %c)
// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, ptr %c)
// CHECK: call void @llvm.lifetime.end{{.*}}({{(i[0-9 ]+, )?}}ptr %c)
// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, ptr %a)
// CHECK: call void @llvm.lifetime.end{{.*}}({{(i[0-9 ]+, )?}}ptr %a)
}

View file

@ -23,7 +23,7 @@ extern "Rust" {
#[no_mangle]
pub fn test_uninhabited_ret_by_ref() {
// CHECK: %_1 = alloca [24 x i8], align {{8|4}}
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_1)
// CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 24, )?}}ptr nonnull %_1)
// CHECK-NEXT: call void @opaque({{.*}} sret([24 x i8]) {{.*}} %_1) #2
// CHECK-NEXT: unreachable
unsafe {
@ -35,7 +35,7 @@ pub fn test_uninhabited_ret_by_ref() {
#[no_mangle]
pub fn test_uninhabited_ret_by_ref_with_arg(rsi: u32) {
// CHECK: %_2 = alloca [24 x i8], align {{8|4}}
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_2)
// CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 24, )?}}ptr nonnull %_2)
// CHECK-NEXT: call void @opaque_with_arg({{.*}} sret([24 x i8]) {{.*}} %_2, i32 noundef %rsi) #2
// CHECK-NEXT: unreachable
unsafe {