xref: /llvm-project/llvm/test/Transforms/ExpandVariadics/intrinsics.ll (revision 8516f54e6a984a79d1a988ec66a414b5cfbd7ec7)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -mtriple=wasm32-unknown-unknown -S --passes=expand-variadics --expand-variadics-override=optimize < %s | FileCheck %s -check-prefixes=CHECK,OPT
3; RUN: opt -mtriple=wasm32-unknown-unknown -S --passes=expand-variadics --expand-variadics-override=lowering < %s | FileCheck %s -check-prefixes=CHECK,ABI
4; REQUIRES: webassembly-registered-target
5
6declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
7
8declare void @llvm.va_copy.p0(ptr, ptr)
9
10declare void @valist(ptr noundef)
11
12declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
13
14declare void @llvm.va_start.p0(ptr)
15
16declare void @llvm.va_end.p0(ptr)
17
18
19define void @start_once(...) {
20; OPT-LABEL: @start_once(
21; OPT-NEXT:  entry:
22; OPT-NEXT:    [[VA_START:%.*]] = alloca ptr, align 4
23; OPT-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[VA_START]])
24; OPT-NEXT:    call void @llvm.va_start.p0(ptr [[VA_START]])
25; OPT-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[VA_START]], align 4
26; OPT-NEXT:    call void @start_once.valist(ptr [[TMP0]])
27; OPT-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[VA_START]])
28; OPT-NEXT:    ret void
29;
30; ABI-LABEL: @start_once(
31; ABI-NEXT:  entry:
32; ABI-NEXT:    [[S:%.*]] = alloca ptr, align 4
33; ABI-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[S]])
34; ABI-NEXT:    store ptr [[VARARGS:%.*]], ptr [[S]], align 4
35; ABI-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[S]], align 4
36; ABI-NEXT:    call void @valist(ptr noundef [[TMP0]])
37; ABI-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[S]])
38; ABI-NEXT:    ret void
39;
40entry:
41  %s = alloca ptr, align 4
42  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %s)
43  call void @llvm.va_start.p0(ptr nonnull %s)
44  %0 = load ptr, ptr %s, align 4
45  call void @valist(ptr noundef %0)
46  call void @llvm.va_end.p0(ptr %s)
47  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %s)
48  ret void
49}
50
51
52define void @start_twice(...) {
53; OPT-LABEL: @start_twice(
54; OPT-NEXT:  entry:
55; OPT-NEXT:    [[VA_START:%.*]] = alloca ptr, align 4
56; OPT-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[VA_START]])
57; OPT-NEXT:    call void @llvm.va_start.p0(ptr [[VA_START]])
58; OPT-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[VA_START]], align 4
59; OPT-NEXT:    call void @start_twice.valist(ptr [[TMP0]])
60; OPT-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[VA_START]])
61; OPT-NEXT:    ret void
62;
63; ABI-LABEL: @start_twice(
64; ABI-NEXT:  entry:
65; ABI-NEXT:    [[S0:%.*]] = alloca ptr, align 4
66; ABI-NEXT:    [[S1:%.*]] = alloca ptr, align 4
67; ABI-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[S0]])
68; ABI-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[S1]])
69; ABI-NEXT:    store ptr [[VARARGS:%.*]], ptr [[S0]], align 4
70; ABI-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[S0]], align 4
71; ABI-NEXT:    call void @valist(ptr noundef [[TMP0]])
72; ABI-NEXT:    store ptr [[VARARGS]], ptr [[S1]], align 4
73; ABI-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[S1]], align 4
74; ABI-NEXT:    call void @valist(ptr noundef [[TMP1]])
75; ABI-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[S1]])
76; ABI-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[S0]])
77; ABI-NEXT:    ret void
78;
79entry:
80  %s0 = alloca ptr, align 4
81  %s1 = alloca ptr, align 4
82  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %s0)
83  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %s1)
84  call void @llvm.va_start.p0(ptr nonnull %s0)
85  %0 = load ptr, ptr %s0, align 4
86  call void @valist(ptr noundef %0)
87  call void @llvm.va_end.p0(ptr %s0)
88  call void @llvm.va_start.p0(ptr nonnull %s1)
89  %1 = load ptr, ptr %s1, align 4
90  call void @valist(ptr noundef %1)
91  call void @llvm.va_end.p0(ptr %s1)
92  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %s1)
93  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %s0)
94  ret void
95}
96
97define void @copy(ptr noundef %va) {
98; CHECK-LABEL: @copy(
99; CHECK-NEXT:  entry:
100; CHECK-NEXT:    [[VA_ADDR:%.*]] = alloca ptr, align 4
101; CHECK-NEXT:    [[CP:%.*]] = alloca ptr, align 4
102; CHECK-NEXT:    store ptr [[VA:%.*]], ptr [[VA_ADDR]], align 4
103; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[CP]])
104; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[CP]], ptr [[VA_ADDR]], i32 4, i1 false)
105; CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[CP]], align 4
106; CHECK-NEXT:    call void @valist(ptr noundef [[TMP0]])
107; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[CP]])
108; CHECK-NEXT:    ret void
109;
110entry:
111  %va.addr = alloca ptr, align 4
112  %cp = alloca ptr, align 4
113  store ptr %va, ptr %va.addr, align 4
114  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %cp)
115  call void @llvm.va_copy.p0(ptr nonnull %cp, ptr nonnull %va.addr)
116  %0 = load ptr, ptr %cp, align 4
117  call void @valist(ptr noundef %0)
118  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %cp)
119  ret void
120}
121