|  | ; 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 datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" | 
|  | target triple = "wasm32-unknown-unknown" | 
|  |  | 
|  | ; 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, [4 x i8], double }> | 
|  | ; CHECK: %double_i32.vararg = type <{ double, i32 }> | 
|  | ; CHECK: %i32_libcS.vararg = type <{ i32, ptr }> | 
|  | ; CHECK: %libcS_i32.vararg = type <{ ptr, i32 }> | 
|  | ; CHECK: %i32_v4f32.vararg = type <{ i32, [12 x i8], <4 x float> }> | 
|  | ; CHECK: %v4f32_i32.vararg = type <{ <4 x float>, i32 }> | 
|  | ; CHECK: %i32_v8f32.vararg = type <{ i32, [28 x i8], <8 x float> }> | 
|  | ; CHECK: %v8f32_i32.vararg = type <{ <8 x float>, i32 }> | 
|  | ; CHECK: %i32_v16f32.vararg = type <{ i32, [60 x i8], <16 x float> }> | 
|  | ; CHECK: %v16f32_i32.vararg = type <{ <16 x float>, i32 }> | 
|  | ; CHECK: %i32_v32f32.vararg = type <{ i32, [124 x i8], <32 x float> }> | 
|  | ; CHECK: %v32f32_i32.vararg = type <{ <32 x float>, i32 }> | 
|  | ; CHECK: %fptr_single_i32.vararg = type <{ i32 }> | 
|  | ; CHECK: %fptr_libcS.vararg = type <{ ptr }> | 
|  |  | 
|  | %struct.libcS = type { i8, i16, i32, i32, float, double } | 
|  |  | 
|  | @vararg_ptr = hidden global ptr @vararg, align 4 | 
|  |  | 
|  | define hidden void @copy(ptr noundef %va) { | 
|  | ; CHECK-LABEL: define {{[^@]+}}@copy(ptr noundef %va) { | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    %va.addr = alloca ptr, align 4 | 
|  | ; CHECK-NEXT:    %cp = alloca ptr, align 4 | 
|  | ; CHECK-NEXT:    store ptr %va, ptr %va.addr, align 4 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr nonnull %cp) | 
|  | ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr %cp, ptr %va.addr, i32 4, i1 false) | 
|  | ; CHECK-NEXT:    %0 = load ptr, ptr %cp, align 4 | 
|  | ; CHECK-NEXT:    call void @valist(ptr noundef %0) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr nonnull %cp) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | %va.addr = alloca ptr, align 4 | 
|  | %cp = alloca ptr, align 4 | 
|  | store ptr %va, ptr %va.addr, align 4 | 
|  | call void @llvm.lifetime.start.p0(ptr nonnull %cp) | 
|  | call void @llvm.va_copy.p0(ptr nonnull %cp, ptr nonnull %va.addr) | 
|  | %0 = load ptr, ptr %cp, align 4 | 
|  | call void @valist(ptr noundef %0) | 
|  | call void @llvm.lifetime.end.p0(ptr nonnull %cp) | 
|  | ret void | 
|  | } | 
|  |  | 
|  | declare void @llvm.lifetime.start.p0(ptr nocapture) | 
|  |  | 
|  | declare void @llvm.va_copy.p0(ptr, ptr) | 
|  |  | 
|  | declare void @valist(ptr noundef) | 
|  |  | 
|  | declare void @llvm.lifetime.end.p0(ptr nocapture) | 
|  |  | 
|  | define hidden void @start_once(...) { | 
|  | ; CHECK-LABEL: define {{[^@]+}}@start_once(ptr %varargs) { | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    %s = alloca ptr, align 4 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr nonnull %s) | 
|  | ; CHECK-NEXT:    store ptr %varargs, ptr %s, align 4 | 
|  | ; CHECK-NEXT:    %0 = load ptr, ptr %s, align 4 | 
|  | ; CHECK-NEXT:    call void @valist(ptr noundef %0) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr nonnull %s) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | %s = alloca ptr, align 4 | 
|  | call void @llvm.lifetime.start.p0(ptr nonnull %s) | 
|  | call void @llvm.va_start.p0(ptr nonnull %s) | 
|  | %0 = load ptr, ptr %s, align 4 | 
|  | call void @valist(ptr noundef %0) | 
|  | call void @llvm.va_end.p0(ptr %s) | 
|  | call void @llvm.lifetime.end.p0(ptr nonnull %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 4 | 
|  | ; CHECK-NEXT:    %s1 = alloca ptr, align 4 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr nonnull %s0) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr nonnull %s1) | 
|  | ; CHECK-NEXT:    store ptr %varargs, ptr %s0, align 4 | 
|  | ; CHECK-NEXT:    %0 = load ptr, ptr %s0, align 4 | 
|  | ; CHECK-NEXT:    call void @valist(ptr noundef %0) | 
|  | ; CHECK-NEXT:    store ptr %varargs, ptr %s1, align 4 | 
|  | ; CHECK-NEXT:    %1 = load ptr, ptr %s1, align 4 | 
|  | ; CHECK-NEXT:    call void @valist(ptr noundef %1) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr nonnull %s1) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr nonnull %s0) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | %s0 = alloca ptr, align 4 | 
|  | %s1 = alloca ptr, align 4 | 
|  | call void @llvm.lifetime.start.p0(ptr nonnull %s0) | 
|  | call void @llvm.lifetime.start.p0(ptr nonnull %s1) | 
|  | call void @llvm.va_start.p0(ptr nonnull %s0) | 
|  | %0 = load ptr, ptr %s0, align 4 | 
|  | call void @valist(ptr noundef %0) | 
|  | call void @llvm.va_end.p0(ptr %s0) | 
|  | call void @llvm.va_start.p0(ptr nonnull %s1) | 
|  | %1 = load ptr, ptr %s1, align 4 | 
|  | call void @valist(ptr noundef %1) | 
|  | call void @llvm.va_end.p0(ptr %s1) | 
|  | call void @llvm.lifetime.end.p0(ptr nonnull %s1) | 
|  | call void @llvm.lifetime.end.p0(ptr nonnull %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 16 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store i32 %x, ptr %0, align 4 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | tail call void (...) @vararg(i32 noundef %x) | 
|  | ret void | 
|  | } | 
|  |  | 
|  | declare 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 16 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_double.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store double %x, ptr %0, align 8 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 16 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_v4f32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store <4 x float> %x, ptr %0, align 16 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 32 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_v8f32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store <8 x float> %x, ptr %0, align 32 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 64 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_v16f32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store <16 x float> %x, ptr %0, align 64 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 128 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_v32f32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store <32 x float> %x, ptr %0, align 128 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 16 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_double.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store i32 %x, ptr %0, align 4 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_double.vararg, ptr %vararg_buffer, i32 0, i32 2 | 
|  | ; CHECK-NEXT:    store double %y, ptr %1, align 8 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 16 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %double_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store double %x, ptr %0, align 8 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %double_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 | 
|  | ; CHECK-NEXT:    store i32 %y, ptr %1, align 4 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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, ptr noundef byval(%struct.libcS) align 8 %y) { | 
|  | ; CHECK-LABEL: define {{[^@]+}}@i32_libcS(i32 noundef %x, ptr noundef byval(%struct.libcS) align 8 %y) { | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    %IndirectAlloca = alloca %struct.libcS, align 8 | 
|  | ; CHECK-NEXT:    %vararg_buffer = alloca %i32_libcS.vararg, align 16 | 
|  | ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr %IndirectAlloca, ptr %y, i64 24, i1 false) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_libcS.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store i32 %x, ptr %0, align 4 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_libcS.vararg, ptr %vararg_buffer, i32 0, i32 1 | 
|  | ; CHECK-NEXT:    store ptr %IndirectAlloca, ptr %1, align 4 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | tail call void (...) @vararg(i32 noundef %x, ptr noundef nonnull byval(%struct.libcS) align 8 %y) | 
|  | ret void | 
|  | } | 
|  |  | 
|  | define hidden void @libcS_i32(ptr noundef byval(%struct.libcS) align 8 %x, i32 noundef %y) { | 
|  | ; CHECK-LABEL: define {{[^@]+}}@libcS_i32(ptr noundef byval(%struct.libcS) align 8 %x, i32 noundef %y) { | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    %IndirectAlloca = alloca %struct.libcS, align 8 | 
|  | ; CHECK-NEXT:    %vararg_buffer = alloca %libcS_i32.vararg, align 16 | 
|  | ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr %IndirectAlloca, ptr %x, i64 24, i1 false) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %libcS_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store ptr %IndirectAlloca, ptr %0, align 4 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %libcS_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 | 
|  | ; CHECK-NEXT:    store i32 %y, ptr %1, align 4 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | tail call void (...) @vararg(ptr noundef nonnull byval(%struct.libcS) align 8 %x, 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 16 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_v4f32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store i32 %x, ptr %0, align 4 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_v4f32.vararg, ptr %vararg_buffer, i32 0, i32 2 | 
|  | ; CHECK-NEXT:    store <4 x float> %y, ptr %1, align 16 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 16 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %v4f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store <4 x float> %x, ptr %0, align 16 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %v4f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 | 
|  | ; CHECK-NEXT:    store i32 %y, ptr %1, align 4 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 32 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_v8f32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store i32 %x, ptr %0, align 4 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_v8f32.vararg, ptr %vararg_buffer, i32 0, i32 2 | 
|  | ; CHECK-NEXT:    store <8 x float> %y, ptr %1, align 32 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 32 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %v8f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store <8 x float> %x, ptr %0, align 32 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %v8f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 | 
|  | ; CHECK-NEXT:    store i32 %y, ptr %1, align 4 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 64 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_v16f32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store i32 %x, ptr %0, align 4 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_v16f32.vararg, ptr %vararg_buffer, i32 0, i32 2 | 
|  | ; CHECK-NEXT:    store <16 x float> %y, ptr %1, align 64 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 64 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %v16f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store <16 x float> %x, ptr %0, align 64 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %v16f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 | 
|  | ; CHECK-NEXT:    store i32 %y, ptr %1, align 4 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 128 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_v32f32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store i32 %x, ptr %0, align 4 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_v32f32.vararg, ptr %vararg_buffer, i32 0, i32 2 | 
|  | ; CHECK-NEXT:    store <32 x float> %y, ptr %1, align 128 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 128 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %v32f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store <32 x float> %x, ptr %0, align 128 | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %v32f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 | 
|  | ; CHECK-NEXT:    store i32 %y, ptr %1, align 4 | 
|  | ; CHECK-NEXT:    call void @vararg(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %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 16 | 
|  | ; CHECK-NEXT:    %0 = load volatile ptr, ptr @vararg_ptr, align 4 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %fptr_single_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store i32 %x, ptr %1, align 4 | 
|  | ; CHECK-NEXT:    call void %0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | %0 = load volatile ptr, ptr @vararg_ptr, align 4 | 
|  | tail call void (...) %0(i32 noundef %x) | 
|  | ret void | 
|  | } | 
|  |  | 
|  | define hidden void @fptr_libcS(ptr noundef byval(%struct.libcS) align 8 %x) { | 
|  | ; CHECK-LABEL: define {{[^@]+}}@fptr_libcS(ptr noundef byval(%struct.libcS) align 8 %x) { | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    %IndirectAlloca = alloca %struct.libcS, align 8 | 
|  | ; CHECK-NEXT:    %vararg_buffer = alloca %fptr_libcS.vararg, align 16 | 
|  | ; CHECK-NEXT:    %0 = load volatile ptr, ptr @vararg_ptr, align 4 | 
|  | ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr %IndirectAlloca, ptr %x, i64 24, i1 false) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %fptr_libcS.vararg, ptr %vararg_buffer, i32 0, i32 0 | 
|  | ; CHECK-NEXT:    store ptr %IndirectAlloca, ptr %1, align 4 | 
|  | ; CHECK-NEXT:    call void %0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr %vararg_buffer) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | %0 = load volatile ptr, ptr @vararg_ptr, align 4 | 
|  | tail call void (...) %0(ptr noundef nonnull byval(%struct.libcS) align 8 %x) | 
|  | ret void | 
|  | } | 
|  |  |