
Now that #149310 has restricted lifetime intrinsics to only work on allocas, we can also drop the explicit size argument. Instead, the size is implied by the alloca. This removes the ability to only mark a prefix of an alloca alive/dead. We never used that capability, so we should remove the need to handle that possibility everywhere (though many key places, including stack coloring, did not actually respect this).
542 lines
28 KiB
LLVM
542 lines
28 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: -p --function-signature
|
|
; RUN: opt -S --passes=expand-variadics --expand-variadics-override=lowering < %s | FileCheck %s
|
|
target triple = "amdgcn-amd-amdhsa"
|
|
|
|
; Check the variables are lowered to the locations this target expects
|
|
|
|
; The types show the call frames
|
|
; CHECK: %single_i32.vararg = type <{ i32 }>
|
|
; CHECK: %single_double.vararg = type <{ double }>
|
|
; CHECK: %single_v4f32.vararg = type <{ <4 x float> }>
|
|
; CHECK: %single_v8f32.vararg = type <{ <8 x float> }>
|
|
; CHECK: %single_v16f32.vararg = type <{ <16 x float> }>
|
|
; CHECK: %single_v32f32.vararg = type <{ <32 x float> }>
|
|
; CHECK: %i32_double.vararg = type <{ i32, double }>
|
|
; CHECK: %double_i32.vararg = type <{ double, i32 }>
|
|
; CHECK: %i32_libcS.vararg = type <{ i32, %struct.libcS }>
|
|
; CHECK: %libcS_i32.vararg = type <{ %struct.libcS, i32 }>
|
|
; CHECK: %i32_v4f32.vararg = type <{ i32, <4 x float> }>
|
|
; CHECK: %v4f32_i32.vararg = type <{ <4 x float>, i32 }>
|
|
; CHECK: %i32_v8f32.vararg = type <{ i32, <8 x float> }>
|
|
; CHECK: %v8f32_i32.vararg = type <{ <8 x float>, i32 }>
|
|
; CHECK: %i32_v16f32.vararg = type <{ i32, <16 x float> }>
|
|
; CHECK: %v16f32_i32.vararg = type <{ <16 x float>, i32 }>
|
|
; CHECK: %i32_v32f32.vararg = type <{ i32, <32 x float> }>
|
|
; CHECK: %v32f32_i32.vararg = type <{ <32 x float>, i32 }>
|
|
; CHECK: %fptr_single_i32.vararg = type <{ i32 }>
|
|
; CHECK: %fptr_libcS.vararg = type <{ %struct.libcS }>
|
|
|
|
%struct.libcS = type { i8, i16, i32, i64, float, double }
|
|
|
|
@vararg_ptr = hidden addrspace(1) global ptr @vararg, align 8
|
|
|
|
define hidden void @copy(ptr noundef %va) {
|
|
; CHECK-LABEL: define {{[^@]+}}@copy(ptr noundef %va) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %va.addr = alloca ptr, align 8, addrspace(5)
|
|
; CHECK-NEXT: %cp = alloca ptr, align 8, addrspace(5)
|
|
; CHECK-NEXT: %va.addr.ascast = addrspacecast ptr addrspace(5) %va.addr to ptr
|
|
; CHECK-NEXT: %cp.ascast = addrspacecast ptr addrspace(5) %cp to ptr
|
|
; CHECK-NEXT: store ptr %va, ptr addrspace(5) %va.addr, align 8
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %cp)
|
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr %cp.ascast, ptr %va.addr.ascast, i32 8, i1 false)
|
|
; CHECK-NEXT: %0 = load ptr, ptr addrspace(5) %cp, align 8
|
|
; CHECK-NEXT: call void @valist(ptr noundef %0)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %cp)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%va.addr = alloca ptr, align 8, addrspace(5)
|
|
%cp = alloca ptr, align 8, addrspace(5)
|
|
%va.addr.ascast = addrspacecast ptr addrspace(5) %va.addr to ptr
|
|
%cp.ascast = addrspacecast ptr addrspace(5) %cp to ptr
|
|
store ptr %va, ptr addrspace(5) %va.addr, align 8
|
|
call void @llvm.lifetime.start.p5(ptr addrspace(5) %cp)
|
|
call void @llvm.va_copy.p0(ptr %cp.ascast, ptr nonnull %va.addr.ascast)
|
|
%0 = load ptr, ptr addrspace(5) %cp, align 8
|
|
call void @valist(ptr noundef %0)
|
|
call void @llvm.lifetime.end.p5(ptr addrspace(5) %cp)
|
|
ret void
|
|
}
|
|
|
|
declare void @llvm.lifetime.start.p5(ptr addrspace(5) nocapture)
|
|
|
|
declare void @llvm.va_copy.p0(ptr, ptr)
|
|
|
|
declare hidden void @valist(ptr noundef)
|
|
|
|
declare void @llvm.lifetime.end.p5(ptr addrspace(5) nocapture)
|
|
|
|
define hidden void @start_once(...) {
|
|
; CHECK-LABEL: define {{[^@]+}}@start_once(ptr %varargs) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %s = alloca ptr, align 8, addrspace(5)
|
|
; CHECK-NEXT: %s.ascast = addrspacecast ptr addrspace(5) %s to ptr
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %s)
|
|
; CHECK-NEXT: store ptr %varargs, ptr %s.ascast, align 8
|
|
; CHECK-NEXT: %0 = load ptr, ptr addrspace(5) %s, align 8
|
|
; CHECK-NEXT: call void @valist(ptr noundef %0)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %s)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%s = alloca ptr, align 8, addrspace(5)
|
|
%s.ascast = addrspacecast ptr addrspace(5) %s to ptr
|
|
call void @llvm.lifetime.start.p5(ptr addrspace(5) %s)
|
|
call void @llvm.va_start.p0(ptr %s.ascast)
|
|
%0 = load ptr, ptr addrspace(5) %s, align 8
|
|
call void @valist(ptr noundef %0)
|
|
call void @llvm.va_end.p0(ptr %s.ascast)
|
|
call void @llvm.lifetime.end.p5(ptr addrspace(5) %s)
|
|
ret void
|
|
}
|
|
|
|
declare void @llvm.va_start.p0(ptr)
|
|
|
|
declare void @llvm.va_end.p0(ptr)
|
|
|
|
define hidden void @start_twice(...) {
|
|
; CHECK-LABEL: define {{[^@]+}}@start_twice(ptr %varargs) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %s0 = alloca ptr, align 8, addrspace(5)
|
|
; CHECK-NEXT: %s1 = alloca ptr, align 8, addrspace(5)
|
|
; CHECK-NEXT: %s0.ascast = addrspacecast ptr addrspace(5) %s0 to ptr
|
|
; CHECK-NEXT: %s1.ascast = addrspacecast ptr addrspace(5) %s1 to ptr
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %s0)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %s1)
|
|
; CHECK-NEXT: store ptr %varargs, ptr %s0.ascast, align 8
|
|
; CHECK-NEXT: %0 = load ptr, ptr addrspace(5) %s0, align 8
|
|
; CHECK-NEXT: call void @valist(ptr noundef %0)
|
|
; CHECK-NEXT: store ptr %varargs, ptr %s1.ascast, align 8
|
|
; CHECK-NEXT: %1 = load ptr, ptr addrspace(5) %s1, align 8
|
|
; CHECK-NEXT: call void @valist(ptr noundef %1)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %s1)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %s0)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%s0 = alloca ptr, align 8, addrspace(5)
|
|
%s1 = alloca ptr, align 8, addrspace(5)
|
|
%s0.ascast = addrspacecast ptr addrspace(5) %s0 to ptr
|
|
%s1.ascast = addrspacecast ptr addrspace(5) %s1 to ptr
|
|
call void @llvm.lifetime.start.p5(ptr addrspace(5) %s0)
|
|
call void @llvm.lifetime.start.p5(ptr addrspace(5) %s1)
|
|
call void @llvm.va_start.p0(ptr %s0.ascast)
|
|
%0 = load ptr, ptr addrspace(5) %s0, align 8
|
|
call void @valist(ptr noundef %0)
|
|
call void @llvm.va_end.p0(ptr %s0.ascast)
|
|
call void @llvm.va_start.p0(ptr %s1.ascast)
|
|
%1 = load ptr, ptr addrspace(5) %s1, align 8
|
|
call void @valist(ptr noundef %1)
|
|
call void @llvm.va_end.p0(ptr %s1.ascast)
|
|
call void @llvm.lifetime.end.p5(ptr addrspace(5) %s1)
|
|
call void @llvm.lifetime.end.p5(ptr addrspace(5) %s0)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @single_i32(i32 noundef %x) {
|
|
; CHECK-LABEL: define {{[^@]+}}@single_i32(i32 noundef %x) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %single_i32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store i32 %x, ptr addrspace(5) %0, align 4
|
|
; CHECK-NEXT: %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %1)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(i32 noundef %x)
|
|
ret void
|
|
}
|
|
|
|
declare hidden void @vararg(...)
|
|
|
|
define hidden void @single_double(double noundef %x) {
|
|
; CHECK-LABEL: define {{[^@]+}}@single_double(double noundef %x) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %single_double.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_double.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store double %x, ptr addrspace(5) %0, align 8
|
|
; CHECK-NEXT: %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %1)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(double noundef %x)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @single_v4f32(<4 x float> noundef %x) {
|
|
; CHECK-LABEL: define {{[^@]+}}@single_v4f32(<4 x float> noundef %x) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %single_v4f32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_v4f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store <4 x float> %x, ptr addrspace(5) %0, align 16
|
|
; CHECK-NEXT: %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %1)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(<4 x float> noundef %x)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @single_v8f32(<8 x float> noundef %x) {
|
|
; CHECK-LABEL: define {{[^@]+}}@single_v8f32(<8 x float> noundef %x) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %single_v8f32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_v8f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store <8 x float> %x, ptr addrspace(5) %0, align 32
|
|
; CHECK-NEXT: %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %1)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(<8 x float> noundef %x)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @single_v16f32(<16 x float> noundef %x) {
|
|
; CHECK-LABEL: define {{[^@]+}}@single_v16f32(<16 x float> noundef %x) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %single_v16f32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_v16f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store <16 x float> %x, ptr addrspace(5) %0, align 64
|
|
; CHECK-NEXT: %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %1)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(<16 x float> noundef %x)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @single_v32f32(<32 x float> noundef %x) {
|
|
; CHECK-LABEL: define {{[^@]+}}@single_v32f32(<32 x float> noundef %x) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %single_v32f32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_v32f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store <32 x float> %x, ptr addrspace(5) %0, align 128
|
|
; CHECK-NEXT: %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %1)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(<32 x float> noundef %x)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @i32_double(i32 noundef %x, double noundef %y) {
|
|
; CHECK-LABEL: define {{[^@]+}}@i32_double(i32 noundef %x, double noundef %y) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %i32_double.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_double.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store i32 %x, ptr addrspace(5) %0, align 4
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_double.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store double %y, ptr addrspace(5) %1, align 8
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(i32 noundef %x, double noundef %y)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @double_i32(double noundef %x, i32 noundef %y) {
|
|
; CHECK-LABEL: define {{[^@]+}}@double_i32(double noundef %x, i32 noundef %y) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %double_i32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %double_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store double %x, ptr addrspace(5) %0, align 8
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %double_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store i32 %y, ptr addrspace(5) %1, align 4
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(double noundef %x, i32 noundef %y)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @i32_libcS(i32 noundef %x, i8 %y.coerce0, i16 %y.coerce1, i32 %y.coerce2, i64 %y.coerce3, float %y.coerce4, double %y.coerce5) {
|
|
; CHECK-LABEL: define {{[^@]+}}@i32_libcS(i32 noundef %x, i8 %y.coerce0, i16 %y.coerce1, i32 %y.coerce2, i64 %y.coerce3, float %y.coerce4, double %y.coerce5) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %i32_libcS.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: %.fca.0.insert = insertvalue %struct.libcS poison, i8 %y.coerce0, 0
|
|
; CHECK-NEXT: %.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %y.coerce1, 1
|
|
; CHECK-NEXT: %.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %y.coerce2, 2
|
|
; CHECK-NEXT: %.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %y.coerce3, 3
|
|
; CHECK-NEXT: %.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %y.coerce4, 4
|
|
; CHECK-NEXT: %.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %y.coerce5, 5
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_libcS.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store i32 %x, ptr addrspace(5) %0, align 4
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_libcS.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store %struct.libcS %.fca.5.insert, ptr addrspace(5) %1, align 8
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%.fca.0.insert = insertvalue %struct.libcS poison, i8 %y.coerce0, 0
|
|
%.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %y.coerce1, 1
|
|
%.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %y.coerce2, 2
|
|
%.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %y.coerce3, 3
|
|
%.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %y.coerce4, 4
|
|
%.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %y.coerce5, 5
|
|
tail call void (...) @vararg(i32 noundef %x, %struct.libcS %.fca.5.insert)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @libcS_i32(i8 %x.coerce0, i16 %x.coerce1, i32 %x.coerce2, i64 %x.coerce3, float %x.coerce4, double %x.coerce5, i32 noundef %y) {
|
|
; CHECK-LABEL: define {{[^@]+}}@libcS_i32(i8 %x.coerce0, i16 %x.coerce1, i32 %x.coerce2, i64 %x.coerce3, float %x.coerce4, double %x.coerce5, i32 noundef %y) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %libcS_i32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: %.fca.0.insert = insertvalue %struct.libcS poison, i8 %x.coerce0, 0
|
|
; CHECK-NEXT: %.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %x.coerce1, 1
|
|
; CHECK-NEXT: %.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %x.coerce2, 2
|
|
; CHECK-NEXT: %.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %x.coerce3, 3
|
|
; CHECK-NEXT: %.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %x.coerce4, 4
|
|
; CHECK-NEXT: %.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %x.coerce5, 5
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %libcS_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store %struct.libcS %.fca.5.insert, ptr addrspace(5) %0, align 8
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %libcS_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store i32 %y, ptr addrspace(5) %1, align 4
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%.fca.0.insert = insertvalue %struct.libcS poison, i8 %x.coerce0, 0
|
|
%.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %x.coerce1, 1
|
|
%.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %x.coerce2, 2
|
|
%.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %x.coerce3, 3
|
|
%.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %x.coerce4, 4
|
|
%.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %x.coerce5, 5
|
|
tail call void (...) @vararg(%struct.libcS %.fca.5.insert, i32 noundef %y)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @i32_v4f32(i32 noundef %x, <4 x float> noundef %y) {
|
|
; CHECK-LABEL: define {{[^@]+}}@i32_v4f32(i32 noundef %x, <4 x float> noundef %y) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %i32_v4f32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_v4f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store i32 %x, ptr addrspace(5) %0, align 4
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_v4f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store <4 x float> %y, ptr addrspace(5) %1, align 16
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(i32 noundef %x, <4 x float> noundef %y)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @v4f32_i32(<4 x float> noundef %x, i32 noundef %y) {
|
|
; CHECK-LABEL: define {{[^@]+}}@v4f32_i32(<4 x float> noundef %x, i32 noundef %y) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %v4f32_i32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %v4f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store <4 x float> %x, ptr addrspace(5) %0, align 16
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %v4f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store i32 %y, ptr addrspace(5) %1, align 4
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(<4 x float> noundef %x, i32 noundef %y)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @i32_v8f32(i32 noundef %x, <8 x float> noundef %y) {
|
|
; CHECK-LABEL: define {{[^@]+}}@i32_v8f32(i32 noundef %x, <8 x float> noundef %y) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %i32_v8f32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_v8f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store i32 %x, ptr addrspace(5) %0, align 4
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_v8f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store <8 x float> %y, ptr addrspace(5) %1, align 32
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(i32 noundef %x, <8 x float> noundef %y)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @v8f32_i32(<8 x float> noundef %x, i32 noundef %y) {
|
|
; CHECK-LABEL: define {{[^@]+}}@v8f32_i32(<8 x float> noundef %x, i32 noundef %y) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %v8f32_i32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %v8f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store <8 x float> %x, ptr addrspace(5) %0, align 32
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %v8f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store i32 %y, ptr addrspace(5) %1, align 4
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(<8 x float> noundef %x, i32 noundef %y)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @i32_v16f32(i32 noundef %x, <16 x float> noundef %y) {
|
|
; CHECK-LABEL: define {{[^@]+}}@i32_v16f32(i32 noundef %x, <16 x float> noundef %y) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %i32_v16f32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_v16f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store i32 %x, ptr addrspace(5) %0, align 4
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_v16f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store <16 x float> %y, ptr addrspace(5) %1, align 64
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(i32 noundef %x, <16 x float> noundef %y)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @v16f32_i32(<16 x float> noundef %x, i32 noundef %y) {
|
|
; CHECK-LABEL: define {{[^@]+}}@v16f32_i32(<16 x float> noundef %x, i32 noundef %y) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %v16f32_i32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %v16f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store <16 x float> %x, ptr addrspace(5) %0, align 64
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %v16f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store i32 %y, ptr addrspace(5) %1, align 4
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(<16 x float> noundef %x, i32 noundef %y)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @i32_v32f32(i32 noundef %x, <32 x float> noundef %y) {
|
|
; CHECK-LABEL: define {{[^@]+}}@i32_v32f32(i32 noundef %x, <32 x float> noundef %y) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %i32_v32f32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_v32f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store i32 %x, ptr addrspace(5) %0, align 4
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_v32f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store <32 x float> %y, ptr addrspace(5) %1, align 128
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(i32 noundef %x, <32 x float> noundef %y)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @v32f32_i32(<32 x float> noundef %x, i32 noundef %y) {
|
|
; CHECK-LABEL: define {{[^@]+}}@v32f32_i32(<32 x float> noundef %x, i32 noundef %y) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %v32f32_i32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %0 = getelementptr inbounds nuw %v32f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store <32 x float> %x, ptr addrspace(5) %0, align 128
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %v32f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
|
|
; CHECK-NEXT: store i32 %y, ptr addrspace(5) %1, align 4
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void @vararg(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
tail call void (...) @vararg(<32 x float> noundef %x, i32 noundef %y)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @fptr_single_i32(i32 noundef %x) {
|
|
; CHECK-LABEL: define {{[^@]+}}@fptr_single_i32(i32 noundef %x) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %fptr_single_i32.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: %0 = load volatile ptr, ptr addrspacecast (ptr addrspace(1) @vararg_ptr to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %fptr_single_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store i32 %x, ptr addrspace(5) %1, align 4
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void %0(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%0 = load volatile ptr, ptr addrspacecast (ptr addrspace(1) @vararg_ptr to ptr), align 8
|
|
tail call void (...) %0(i32 noundef %x)
|
|
ret void
|
|
}
|
|
|
|
define hidden void @fptr_libcS(i8 %x.coerce0, i16 %x.coerce1, i32 %x.coerce2, i64 %x.coerce3, float %x.coerce4, double %x.coerce5) {
|
|
; CHECK-LABEL: define {{[^@]+}}@fptr_libcS(i8 %x.coerce0, i16 %x.coerce1, i32 %x.coerce2, i64 %x.coerce3, float %x.coerce4, double %x.coerce5) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: %vararg_buffer = alloca %fptr_libcS.vararg, align 4, addrspace(5)
|
|
; CHECK-NEXT: %0 = load volatile ptr, ptr addrspacecast (ptr addrspace(1) @vararg_ptr to ptr), align 8
|
|
; CHECK-NEXT: %.fca.0.insert = insertvalue %struct.libcS poison, i8 %x.coerce0, 0
|
|
; CHECK-NEXT: %.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %x.coerce1, 1
|
|
; CHECK-NEXT: %.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %x.coerce2, 2
|
|
; CHECK-NEXT: %.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %x.coerce3, 3
|
|
; CHECK-NEXT: %.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %x.coerce4, 4
|
|
; CHECK-NEXT: %.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %x.coerce5, 5
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: %1 = getelementptr inbounds nuw %fptr_libcS.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
|
|
; CHECK-NEXT: store %struct.libcS %.fca.5.insert, ptr addrspace(5) %1, align 8
|
|
; CHECK-NEXT: %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
|
|
; CHECK-NEXT: call void %0(ptr %2)
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p5(ptr addrspace(5) %vararg_buffer)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%0 = load volatile ptr, ptr addrspacecast (ptr addrspace(1) @vararg_ptr to ptr), align 8
|
|
%.fca.0.insert = insertvalue %struct.libcS poison, i8 %x.coerce0, 0
|
|
%.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %x.coerce1, 1
|
|
%.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %x.coerce2, 2
|
|
%.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %x.coerce3, 3
|
|
%.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %x.coerce4, 4
|
|
%.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %x.coerce5, 5
|
|
tail call void (...) %0(%struct.libcS %.fca.5.insert)
|
|
ret void
|
|
}
|