1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: -p --function-signature 2; RUN: opt -S --passes=expand-variadics --expand-variadics-override=lowering < %s | FileCheck %s 3; REQUIRES: webassembly-registered-target 4target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" 5target triple = "wasm32-unknown-unknown" 6 7; Check the variables are lowered to the locations this target expects 8 9; The types show the call frames 10; CHECK: %single_i32.vararg = type <{ i32 }> 11; CHECK: %single_double.vararg = type <{ double }> 12; CHECK: %single_v4f32.vararg = type <{ <4 x float> }> 13; CHECK: %single_v8f32.vararg = type <{ <8 x float> }> 14; CHECK: %single_v16f32.vararg = type <{ <16 x float> }> 15; CHECK: %single_v32f32.vararg = type <{ <32 x float> }> 16; CHECK: %i32_double.vararg = type <{ i32, [4 x i8], double }> 17; CHECK: %double_i32.vararg = type <{ double, i32 }> 18; CHECK: %i32_libcS.vararg = type <{ i32, ptr }> 19; CHECK: %libcS_i32.vararg = type <{ ptr, i32 }> 20; CHECK: %i32_v4f32.vararg = type <{ i32, [12 x i8], <4 x float> }> 21; CHECK: %v4f32_i32.vararg = type <{ <4 x float>, i32 }> 22; CHECK: %i32_v8f32.vararg = type <{ i32, [28 x i8], <8 x float> }> 23; CHECK: %v8f32_i32.vararg = type <{ <8 x float>, i32 }> 24; CHECK: %i32_v16f32.vararg = type <{ i32, [60 x i8], <16 x float> }> 25; CHECK: %v16f32_i32.vararg = type <{ <16 x float>, i32 }> 26; CHECK: %i32_v32f32.vararg = type <{ i32, [124 x i8], <32 x float> }> 27; CHECK: %v32f32_i32.vararg = type <{ <32 x float>, i32 }> 28; CHECK: %fptr_single_i32.vararg = type <{ i32 }> 29; CHECK: %fptr_libcS.vararg = type <{ ptr }> 30 31%struct.libcS = type { i8, i16, i32, i32, float, double } 32 33@vararg_ptr = hidden global ptr @vararg, align 4 34 35define hidden void @copy(ptr noundef %va) { 36; CHECK-LABEL: define {{[^@]+}}@copy(ptr noundef %va) { 37; CHECK-NEXT: entry: 38; CHECK-NEXT: %va.addr = alloca ptr, align 4 39; CHECK-NEXT: %cp = alloca ptr, align 4 40; CHECK-NEXT: store ptr %va, ptr %va.addr, align 4 41; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %cp) 42; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr %cp, ptr %va.addr, i32 4, i1 false) 43; CHECK-NEXT: %0 = load ptr, ptr %cp, align 4 44; CHECK-NEXT: call void @valist(ptr noundef %0) 45; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %cp) 46; CHECK-NEXT: ret void 47; 48entry: 49 %va.addr = alloca ptr, align 4 50 %cp = alloca ptr, align 4 51 store ptr %va, ptr %va.addr, align 4 52 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %cp) 53 call void @llvm.va_copy.p0(ptr nonnull %cp, ptr nonnull %va.addr) 54 %0 = load ptr, ptr %cp, align 4 55 call void @valist(ptr noundef %0) 56 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %cp) 57 ret void 58} 59 60declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) 61 62declare void @llvm.va_copy.p0(ptr, ptr) 63 64declare void @valist(ptr noundef) 65 66declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) 67 68define hidden void @start_once(...) { 69; CHECK-LABEL: define {{[^@]+}}@start_once(ptr %varargs) { 70; CHECK-NEXT: entry: 71; CHECK-NEXT: %s = alloca ptr, align 4 72; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %s) 73; CHECK-NEXT: store ptr %varargs, ptr %s, align 4 74; CHECK-NEXT: %0 = load ptr, ptr %s, align 4 75; CHECK-NEXT: call void @valist(ptr noundef %0) 76; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %s) 77; CHECK-NEXT: ret void 78; 79entry: 80 %s = alloca ptr, align 4 81 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %s) 82 call void @llvm.va_start.p0(ptr nonnull %s) 83 %0 = load ptr, ptr %s, align 4 84 call void @valist(ptr noundef %0) 85 call void @llvm.va_end.p0(ptr %s) 86 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %s) 87 ret void 88} 89 90declare void @llvm.va_start.p0(ptr) 91 92declare void @llvm.va_end.p0(ptr) 93 94define hidden void @start_twice(...) { 95; CHECK-LABEL: define {{[^@]+}}@start_twice(ptr %varargs) { 96; CHECK-NEXT: entry: 97; CHECK-NEXT: %s0 = alloca ptr, align 4 98; CHECK-NEXT: %s1 = alloca ptr, align 4 99; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %s0) 100; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %s1) 101; CHECK-NEXT: store ptr %varargs, ptr %s0, align 4 102; CHECK-NEXT: %0 = load ptr, ptr %s0, align 4 103; CHECK-NEXT: call void @valist(ptr noundef %0) 104; CHECK-NEXT: store ptr %varargs, ptr %s1, align 4 105; CHECK-NEXT: %1 = load ptr, ptr %s1, align 4 106; CHECK-NEXT: call void @valist(ptr noundef %1) 107; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %s1) 108; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %s0) 109; CHECK-NEXT: ret void 110; 111entry: 112 %s0 = alloca ptr, align 4 113 %s1 = alloca ptr, align 4 114 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %s0) 115 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %s1) 116 call void @llvm.va_start.p0(ptr nonnull %s0) 117 %0 = load ptr, ptr %s0, align 4 118 call void @valist(ptr noundef %0) 119 call void @llvm.va_end.p0(ptr %s0) 120 call void @llvm.va_start.p0(ptr nonnull %s1) 121 %1 = load ptr, ptr %s1, align 4 122 call void @valist(ptr noundef %1) 123 call void @llvm.va_end.p0(ptr %s1) 124 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %s1) 125 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %s0) 126 ret void 127} 128 129define hidden void @single_i32(i32 noundef %x) { 130; CHECK-LABEL: define {{[^@]+}}@single_i32(i32 noundef %x) { 131; CHECK-NEXT: entry: 132; CHECK-NEXT: %vararg_buffer = alloca %single_i32.vararg, align 16 133; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr %vararg_buffer) 134; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 135; CHECK-NEXT: store i32 %x, ptr %0, align 4 136; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 137; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr %vararg_buffer) 138; CHECK-NEXT: ret void 139; 140entry: 141 tail call void (...) @vararg(i32 noundef %x) 142 ret void 143} 144 145declare void @vararg(...) 146 147define hidden void @single_double(double noundef %x) { 148; CHECK-LABEL: define {{[^@]+}}@single_double(double noundef %x) { 149; CHECK-NEXT: entry: 150; CHECK-NEXT: %vararg_buffer = alloca %single_double.vararg, align 16 151; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr %vararg_buffer) 152; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_double.vararg, ptr %vararg_buffer, i32 0, i32 0 153; CHECK-NEXT: store double %x, ptr %0, align 8 154; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 155; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr %vararg_buffer) 156; CHECK-NEXT: ret void 157; 158entry: 159 tail call void (...) @vararg(double noundef %x) 160 ret void 161} 162 163define hidden void @single_v4f32(<4 x float> noundef %x) { 164; CHECK-LABEL: define {{[^@]+}}@single_v4f32(<4 x float> noundef %x) { 165; CHECK-NEXT: entry: 166; CHECK-NEXT: %vararg_buffer = alloca %single_v4f32.vararg, align 16 167; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr %vararg_buffer) 168; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_v4f32.vararg, ptr %vararg_buffer, i32 0, i32 0 169; CHECK-NEXT: store <4 x float> %x, ptr %0, align 16 170; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 171; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr %vararg_buffer) 172; CHECK-NEXT: ret void 173; 174entry: 175 tail call void (...) @vararg(<4 x float> noundef %x) 176 ret void 177} 178 179define hidden void @single_v8f32(<8 x float> noundef %x) { 180; CHECK-LABEL: define {{[^@]+}}@single_v8f32(<8 x float> noundef %x) { 181; CHECK-NEXT: entry: 182; CHECK-NEXT: %vararg_buffer = alloca %single_v8f32.vararg, align 32 183; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr %vararg_buffer) 184; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_v8f32.vararg, ptr %vararg_buffer, i32 0, i32 0 185; CHECK-NEXT: store <8 x float> %x, ptr %0, align 32 186; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 187; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr %vararg_buffer) 188; CHECK-NEXT: ret void 189; 190entry: 191 tail call void (...) @vararg(<8 x float> noundef %x) 192 ret void 193} 194 195define hidden void @single_v16f32(<16 x float> noundef %x) { 196; CHECK-LABEL: define {{[^@]+}}@single_v16f32(<16 x float> noundef %x) { 197; CHECK-NEXT: entry: 198; CHECK-NEXT: %vararg_buffer = alloca %single_v16f32.vararg, align 64 199; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 64, ptr %vararg_buffer) 200; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_v16f32.vararg, ptr %vararg_buffer, i32 0, i32 0 201; CHECK-NEXT: store <16 x float> %x, ptr %0, align 64 202; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 203; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 64, ptr %vararg_buffer) 204; CHECK-NEXT: ret void 205; 206entry: 207 tail call void (...) @vararg(<16 x float> noundef %x) 208 ret void 209} 210 211define hidden void @single_v32f32(<32 x float> noundef %x) { 212; CHECK-LABEL: define {{[^@]+}}@single_v32f32(<32 x float> noundef %x) { 213; CHECK-NEXT: entry: 214; CHECK-NEXT: %vararg_buffer = alloca %single_v32f32.vararg, align 128 215; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 128, ptr %vararg_buffer) 216; CHECK-NEXT: %0 = getelementptr inbounds nuw %single_v32f32.vararg, ptr %vararg_buffer, i32 0, i32 0 217; CHECK-NEXT: store <32 x float> %x, ptr %0, align 128 218; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 219; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 128, ptr %vararg_buffer) 220; CHECK-NEXT: ret void 221; 222entry: 223 tail call void (...) @vararg(<32 x float> noundef %x) 224 ret void 225} 226 227define hidden void @i32_double(i32 noundef %x, double noundef %y) { 228; CHECK-LABEL: define {{[^@]+}}@i32_double(i32 noundef %x, double noundef %y) { 229; CHECK-NEXT: entry: 230; CHECK-NEXT: %vararg_buffer = alloca %i32_double.vararg, align 16 231; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr %vararg_buffer) 232; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_double.vararg, ptr %vararg_buffer, i32 0, i32 0 233; CHECK-NEXT: store i32 %x, ptr %0, align 4 234; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_double.vararg, ptr %vararg_buffer, i32 0, i32 2 235; CHECK-NEXT: store double %y, ptr %1, align 8 236; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 237; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr %vararg_buffer) 238; CHECK-NEXT: ret void 239; 240entry: 241 tail call void (...) @vararg(i32 noundef %x, double noundef %y) 242 ret void 243} 244 245define hidden void @double_i32(double noundef %x, i32 noundef %y) { 246; CHECK-LABEL: define {{[^@]+}}@double_i32(double noundef %x, i32 noundef %y) { 247; CHECK-NEXT: entry: 248; CHECK-NEXT: %vararg_buffer = alloca %double_i32.vararg, align 16 249; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 12, ptr %vararg_buffer) 250; CHECK-NEXT: %0 = getelementptr inbounds nuw %double_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 251; CHECK-NEXT: store double %x, ptr %0, align 8 252; CHECK-NEXT: %1 = getelementptr inbounds nuw %double_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 253; CHECK-NEXT: store i32 %y, ptr %1, align 4 254; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 255; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 12, ptr %vararg_buffer) 256; CHECK-NEXT: ret void 257; 258entry: 259 tail call void (...) @vararg(double noundef %x, i32 noundef %y) 260 ret void 261} 262 263define hidden void @i32_libcS(i32 noundef %x, ptr noundef byval(%struct.libcS) align 8 %y) { 264; CHECK-LABEL: define {{[^@]+}}@i32_libcS(i32 noundef %x, ptr noundef byval(%struct.libcS) align 8 %y) { 265; CHECK-NEXT: entry: 266; CHECK-NEXT: %IndirectAlloca = alloca %struct.libcS, align 8 267; CHECK-NEXT: %vararg_buffer = alloca %i32_libcS.vararg, align 16 268; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr %IndirectAlloca, ptr %y, i64 24, i1 false) 269; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr %vararg_buffer) 270; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_libcS.vararg, ptr %vararg_buffer, i32 0, i32 0 271; CHECK-NEXT: store i32 %x, ptr %0, align 4 272; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_libcS.vararg, ptr %vararg_buffer, i32 0, i32 1 273; CHECK-NEXT: store ptr %IndirectAlloca, ptr %1, align 4 274; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 275; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr %vararg_buffer) 276; CHECK-NEXT: ret void 277; 278entry: 279 tail call void (...) @vararg(i32 noundef %x, ptr noundef nonnull byval(%struct.libcS) align 8 %y) 280 ret void 281} 282 283define hidden void @libcS_i32(ptr noundef byval(%struct.libcS) align 8 %x, i32 noundef %y) { 284; CHECK-LABEL: define {{[^@]+}}@libcS_i32(ptr noundef byval(%struct.libcS) align 8 %x, i32 noundef %y) { 285; CHECK-NEXT: entry: 286; CHECK-NEXT: %IndirectAlloca = alloca %struct.libcS, align 8 287; CHECK-NEXT: %vararg_buffer = alloca %libcS_i32.vararg, align 16 288; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr %IndirectAlloca, ptr %x, i64 24, i1 false) 289; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr %vararg_buffer) 290; CHECK-NEXT: %0 = getelementptr inbounds nuw %libcS_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 291; CHECK-NEXT: store ptr %IndirectAlloca, ptr %0, align 4 292; CHECK-NEXT: %1 = getelementptr inbounds nuw %libcS_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 293; CHECK-NEXT: store i32 %y, ptr %1, align 4 294; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 295; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr %vararg_buffer) 296; CHECK-NEXT: ret void 297; 298entry: 299 tail call void (...) @vararg(ptr noundef nonnull byval(%struct.libcS) align 8 %x, i32 noundef %y) 300 ret void 301} 302 303define hidden void @i32_v4f32(i32 noundef %x, <4 x float> noundef %y) { 304; CHECK-LABEL: define {{[^@]+}}@i32_v4f32(i32 noundef %x, <4 x float> noundef %y) { 305; CHECK-NEXT: entry: 306; CHECK-NEXT: %vararg_buffer = alloca %i32_v4f32.vararg, align 16 307; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr %vararg_buffer) 308; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_v4f32.vararg, ptr %vararg_buffer, i32 0, i32 0 309; CHECK-NEXT: store i32 %x, ptr %0, align 4 310; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_v4f32.vararg, ptr %vararg_buffer, i32 0, i32 2 311; CHECK-NEXT: store <4 x float> %y, ptr %1, align 16 312; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 313; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr %vararg_buffer) 314; CHECK-NEXT: ret void 315; 316entry: 317 tail call void (...) @vararg(i32 noundef %x, <4 x float> noundef %y) 318 ret void 319} 320 321define hidden void @v4f32_i32(<4 x float> noundef %x, i32 noundef %y) { 322; CHECK-LABEL: define {{[^@]+}}@v4f32_i32(<4 x float> noundef %x, i32 noundef %y) { 323; CHECK-NEXT: entry: 324; CHECK-NEXT: %vararg_buffer = alloca %v4f32_i32.vararg, align 16 325; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 20, ptr %vararg_buffer) 326; CHECK-NEXT: %0 = getelementptr inbounds nuw %v4f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 327; CHECK-NEXT: store <4 x float> %x, ptr %0, align 16 328; CHECK-NEXT: %1 = getelementptr inbounds nuw %v4f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 329; CHECK-NEXT: store i32 %y, ptr %1, align 4 330; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 331; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 20, ptr %vararg_buffer) 332; CHECK-NEXT: ret void 333; 334entry: 335 tail call void (...) @vararg(<4 x float> noundef %x, i32 noundef %y) 336 ret void 337} 338 339define hidden void @i32_v8f32(i32 noundef %x, <8 x float> noundef %y) { 340; CHECK-LABEL: define {{[^@]+}}@i32_v8f32(i32 noundef %x, <8 x float> noundef %y) { 341; CHECK-NEXT: entry: 342; CHECK-NEXT: %vararg_buffer = alloca %i32_v8f32.vararg, align 32 343; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 64, ptr %vararg_buffer) 344; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_v8f32.vararg, ptr %vararg_buffer, i32 0, i32 0 345; CHECK-NEXT: store i32 %x, ptr %0, align 4 346; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_v8f32.vararg, ptr %vararg_buffer, i32 0, i32 2 347; CHECK-NEXT: store <8 x float> %y, ptr %1, align 32 348; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 349; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 64, ptr %vararg_buffer) 350; CHECK-NEXT: ret void 351; 352entry: 353 tail call void (...) @vararg(i32 noundef %x, <8 x float> noundef %y) 354 ret void 355} 356 357define hidden void @v8f32_i32(<8 x float> noundef %x, i32 noundef %y) { 358; CHECK-LABEL: define {{[^@]+}}@v8f32_i32(<8 x float> noundef %x, i32 noundef %y) { 359; CHECK-NEXT: entry: 360; CHECK-NEXT: %vararg_buffer = alloca %v8f32_i32.vararg, align 32 361; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 36, ptr %vararg_buffer) 362; CHECK-NEXT: %0 = getelementptr inbounds nuw %v8f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 363; CHECK-NEXT: store <8 x float> %x, ptr %0, align 32 364; CHECK-NEXT: %1 = getelementptr inbounds nuw %v8f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 365; CHECK-NEXT: store i32 %y, ptr %1, align 4 366; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 367; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 36, ptr %vararg_buffer) 368; CHECK-NEXT: ret void 369; 370entry: 371 tail call void (...) @vararg(<8 x float> noundef %x, i32 noundef %y) 372 ret void 373} 374 375define hidden void @i32_v16f32(i32 noundef %x, <16 x float> noundef %y) { 376; CHECK-LABEL: define {{[^@]+}}@i32_v16f32(i32 noundef %x, <16 x float> noundef %y) { 377; CHECK-NEXT: entry: 378; CHECK-NEXT: %vararg_buffer = alloca %i32_v16f32.vararg, align 64 379; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 128, ptr %vararg_buffer) 380; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_v16f32.vararg, ptr %vararg_buffer, i32 0, i32 0 381; CHECK-NEXT: store i32 %x, ptr %0, align 4 382; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_v16f32.vararg, ptr %vararg_buffer, i32 0, i32 2 383; CHECK-NEXT: store <16 x float> %y, ptr %1, align 64 384; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 385; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 128, ptr %vararg_buffer) 386; CHECK-NEXT: ret void 387; 388entry: 389 tail call void (...) @vararg(i32 noundef %x, <16 x float> noundef %y) 390 ret void 391} 392 393define hidden void @v16f32_i32(<16 x float> noundef %x, i32 noundef %y) { 394; CHECK-LABEL: define {{[^@]+}}@v16f32_i32(<16 x float> noundef %x, i32 noundef %y) { 395; CHECK-NEXT: entry: 396; CHECK-NEXT: %vararg_buffer = alloca %v16f32_i32.vararg, align 64 397; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 68, ptr %vararg_buffer) 398; CHECK-NEXT: %0 = getelementptr inbounds nuw %v16f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 399; CHECK-NEXT: store <16 x float> %x, ptr %0, align 64 400; CHECK-NEXT: %1 = getelementptr inbounds nuw %v16f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 401; CHECK-NEXT: store i32 %y, ptr %1, align 4 402; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 403; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 68, ptr %vararg_buffer) 404; CHECK-NEXT: ret void 405; 406entry: 407 tail call void (...) @vararg(<16 x float> noundef %x, i32 noundef %y) 408 ret void 409} 410 411define hidden void @i32_v32f32(i32 noundef %x, <32 x float> noundef %y) { 412; CHECK-LABEL: define {{[^@]+}}@i32_v32f32(i32 noundef %x, <32 x float> noundef %y) { 413; CHECK-NEXT: entry: 414; CHECK-NEXT: %vararg_buffer = alloca %i32_v32f32.vararg, align 128 415; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 256, ptr %vararg_buffer) 416; CHECK-NEXT: %0 = getelementptr inbounds nuw %i32_v32f32.vararg, ptr %vararg_buffer, i32 0, i32 0 417; CHECK-NEXT: store i32 %x, ptr %0, align 4 418; CHECK-NEXT: %1 = getelementptr inbounds nuw %i32_v32f32.vararg, ptr %vararg_buffer, i32 0, i32 2 419; CHECK-NEXT: store <32 x float> %y, ptr %1, align 128 420; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 421; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 256, ptr %vararg_buffer) 422; CHECK-NEXT: ret void 423; 424entry: 425 tail call void (...) @vararg(i32 noundef %x, <32 x float> noundef %y) 426 ret void 427} 428 429define hidden void @v32f32_i32(<32 x float> noundef %x, i32 noundef %y) { 430; CHECK-LABEL: define {{[^@]+}}@v32f32_i32(<32 x float> noundef %x, i32 noundef %y) { 431; CHECK-NEXT: entry: 432; CHECK-NEXT: %vararg_buffer = alloca %v32f32_i32.vararg, align 128 433; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 132, ptr %vararg_buffer) 434; CHECK-NEXT: %0 = getelementptr inbounds nuw %v32f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 435; CHECK-NEXT: store <32 x float> %x, ptr %0, align 128 436; CHECK-NEXT: %1 = getelementptr inbounds nuw %v32f32_i32.vararg, ptr %vararg_buffer, i32 0, i32 1 437; CHECK-NEXT: store i32 %y, ptr %1, align 4 438; CHECK-NEXT: call void @vararg(ptr %vararg_buffer) 439; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 132, ptr %vararg_buffer) 440; CHECK-NEXT: ret void 441; 442entry: 443 tail call void (...) @vararg(<32 x float> noundef %x, i32 noundef %y) 444 ret void 445} 446 447define hidden void @fptr_single_i32(i32 noundef %x) { 448; CHECK-LABEL: define {{[^@]+}}@fptr_single_i32(i32 noundef %x) { 449; CHECK-NEXT: entry: 450; CHECK-NEXT: %vararg_buffer = alloca %fptr_single_i32.vararg, align 16 451; CHECK-NEXT: %0 = load volatile ptr, ptr @vararg_ptr, align 4 452; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr %vararg_buffer) 453; CHECK-NEXT: %1 = getelementptr inbounds nuw %fptr_single_i32.vararg, ptr %vararg_buffer, i32 0, i32 0 454; CHECK-NEXT: store i32 %x, ptr %1, align 4 455; CHECK-NEXT: call void %0(ptr %vararg_buffer) 456; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr %vararg_buffer) 457; CHECK-NEXT: ret void 458; 459entry: 460 %0 = load volatile ptr, ptr @vararg_ptr, align 4 461 tail call void (...) %0(i32 noundef %x) 462 ret void 463} 464 465define hidden void @fptr_libcS(ptr noundef byval(%struct.libcS) align 8 %x) { 466; CHECK-LABEL: define {{[^@]+}}@fptr_libcS(ptr noundef byval(%struct.libcS) align 8 %x) { 467; CHECK-NEXT: entry: 468; CHECK-NEXT: %IndirectAlloca = alloca %struct.libcS, align 8 469; CHECK-NEXT: %vararg_buffer = alloca %fptr_libcS.vararg, align 16 470; CHECK-NEXT: %0 = load volatile ptr, ptr @vararg_ptr, align 4 471; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr %IndirectAlloca, ptr %x, i64 24, i1 false) 472; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr %vararg_buffer) 473; CHECK-NEXT: %1 = getelementptr inbounds nuw %fptr_libcS.vararg, ptr %vararg_buffer, i32 0, i32 0 474; CHECK-NEXT: store ptr %IndirectAlloca, ptr %1, align 4 475; CHECK-NEXT: call void %0(ptr %vararg_buffer) 476; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr %vararg_buffer) 477; CHECK-NEXT: ret void 478; 479entry: 480 %0 = load volatile ptr, ptr @vararg_ptr, align 4 481 tail call void (...) %0(ptr noundef nonnull byval(%struct.libcS) align 8 %x) 482 ret void 483} 484 485