[AMDGPU][True16][CodeGen] true16 codegen pattern for v_med3_u/i16 (#121850)
[llvm-project.git] / clang / test / CodeGenCXX / inline-then-fold-variadics.cpp
blob4aa79a28dd7d3d0a6e060a1d8b96d8e72b065bc3
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature
2 // REQUIRES: webassembly-registered-target
4 // Simple calls to known variadic functions that are completely elided when
5 // optimisations are on This is a functional check that the expand-variadic pass
6 // is consistent with clang's va_arg handling
8 // When expand-variadics is added to the default pipeline, clang -O1 will
9 // suffice here -Wno-varargs avoids warning second argument to 'va_start' is not
10 // the last named parameter
12 // RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -Wno-varargs -O1 -emit-llvm -o - | opt - -S --passes='module(expand-variadics,default<O1>)' --expand-variadics-override=optimize -o - | FileCheck %s
14 #include <stdarg.h>
15 #include <stdint.h>
17 template <typename X, typename Y> static X first(...) {
18 va_list va;
19 __builtin_va_start(va, 0);
20 X r = va_arg(va, X);
21 va_end(va);
22 return r;
25 template <typename X, typename Y> static Y second(...) {
26 va_list va;
27 __builtin_va_start(va, 0);
28 va_arg(va, X);
29 Y r = va_arg(va, Y);
30 va_end(va);
31 return r;
34 extern "C" {
36 // CHECK-LABEL: define {{[^@]+}}@first_pair_i32
37 // CHECK-SAME: (i32 noundef returned [[X:%.*]], i32 noundef [[Y:%.*]])
38 // CHECK-NEXT: entry:
39 // CHECK-NEXT: ret i32 [[X]]
41 int first_pair_i32(int x, int y) { return first<int, int>(x, y); }
43 // CHECK-LABEL: define {{[^@]+}}@second_pair_i32
44 // CHECK-SAME: (i32 noundef [[X:%.*]], i32 noundef returned [[Y:%.*]])
45 // CHECK-NEXT: entry:
46 // CHECK-NEXT: ret i32 [[Y]]
48 int second_pair_i32(int x, int y) { return second<int, int>(x, y); }
50 // CHECK-LABEL: define {{[^@]+}}@first_pair_f64
51 // CHECK-SAME: (double noundef returned [[X:%.*]], double noundef [[Y:%.*]])
52 // CHECK-NEXT: entry:
53 // CHECK-NEXT: ret double [[X]]
55 double first_pair_f64(double x, double y) {
56 return first<double, double>(x, y);
59 // CHECK-LABEL: define {{[^@]+}}@second_pair_f64
60 // CHECK-SAME: (double noundef [[X:%.*]], double noundef returned [[Y:%.*]])
61 // CHECK-NEXT: entry:
62 // CHECK-NEXT: ret double [[Y]]
64 double second_pair_f64(double x, double y) {
65 return second<double, double>(x, y);
69 extern "C" {
71 // CHECK-LABEL: define {{[^@]+}}@first_i32_f64
72 // CHECK-SAME: (i32 noundef returned [[X:%.*]], double noundef [[Y:%.*]])
73 // CHECK-NEXT: entry:
74 // CHECK-NEXT: ret i32 [[X]]
76 int first_i32_f64(int x, double y) { return first<int, double>(x, y); }
78 // CHECK-LABEL: define {{[^@]+}}@second_i32_f64
79 // CHECK-SAME: (i32 noundef [[X:%.*]], double noundef returned [[Y:%.*]])
80 // CHECK-NEXT: entry:
81 // CHECK-NEXT: ret double [[Y]]
83 double second_i32_f64(int x, double y) { return second<int, double>(x, y); }
85 // CHECK-LABEL: define {{[^@]+}}@first_f64_i32
86 // CHECK-SAME: (double noundef returned [[X:%.*]], i32 noundef [[Y:%.*]])
87 // CHECK-NEXT: entry:
88 // CHECK-NEXT: ret double [[X]]
90 double first_f64_i32(double x, int y) { return first<double, int>(x, y); }
92 // CHECK-LABEL: define {{[^@]+}}@second_f64_i32
93 // CHECK-SAME: (double noundef [[X:%.*]], i32 noundef returned [[Y:%.*]])
94 // CHECK-NEXT: entry:
95 // CHECK-NEXT: ret i32 [[Y]]
97 int second_f64_i32(double x, int y) { return second<double, int>(x, y); }
100 extern "C" {
101 typedef uint64_t ulong2 __attribute__((__vector_size__(16), __aligned__(16)));
103 // CHECK-LABEL: define {{[^@]+}}@first_i32_ulong2
104 // CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]])
105 // CHECK-NEXT: entry:
106 // CHECK-NEXT: ret i32 [[X]]
108 int first_i32_ulong2(int x, ulong2 *y) { return first<int, ulong2>(x, *y); }
110 // CHECK-LABEL: define {{[^@]+}}@second_i32_ulong2
111 // CHECK-SAME: (i32 noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]], ptr nocapture noundef writeonly initializes((0, 16)) [[R:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
112 // CHECK-NEXT: entry:
113 // CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[Y]], align 16, !tbaa [[TBAA2:![0-9]+]]
114 // CHECK-NEXT: store <2 x i64> [[TMP0]], ptr [[R]], align 16, !tbaa [[TBAA2]]
115 // CHECK-NEXT: ret void
117 void second_i32_ulong2(int x, ulong2 *y, ulong2 *r) {
118 *r = second<int, ulong2>(x, *y);
121 // CHECK-LABEL: define {{[^@]+}}@first_ulong2_i32
122 // CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef [[Y:%.*]], ptr nocapture noundef writeonly initializes((0, 16)) [[R:%.*]]) local_unnamed_addr #[[ATTR1]] {
123 // CHECK-NEXT: entry:
124 // CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[X]], align 16, !tbaa [[TBAA2]]
125 // CHECK-NEXT: store <2 x i64> [[TMP0]], ptr [[R]], align 16, !tbaa [[TBAA2]]
126 // CHECK-NEXT: ret void
128 void first_ulong2_i32(ulong2 *x, int y, ulong2 *r) {
129 *r = first<ulong2, int>(*x, y);
132 // CHECK-LABEL: define {{[^@]+}}@second_ulong2_i32
133 // CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]])
134 // CHECK-NEXT: entry:
135 // CHECK-NEXT: ret i32 [[Y]]
137 int second_ulong2_i32(ulong2 *x, int y) { return second<ulong2, int>(*x, y); }
140 // ascending alignment
141 typedef struct {
142 char c;
143 short s;
144 int i;
145 long l;
146 float f;
147 double d;
148 } asc;
150 extern "C" {
152 // CHECK-LABEL: define {{[^@]+}}@first_i32_asc
153 // CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]])
154 // CHECK-NEXT: entry:
155 // CHECK-NEXT: ret i32 [[X]]
157 int first_i32_asc(int x, asc *y) { return first<int, asc>(x, *y); }
159 // CHECK-LABEL: define {{[^@]+}}@second_i32_asc
160 // CHECK-SAME: (i32 noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]], ptr nocapture noundef writeonly initializes((0, 24)) [[R:%.*]]) local_unnamed_addr #[[ATTR1]] {
161 // CHECK-NEXT: entry:
162 // CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(24) [[R]], ptr noundef nonnull align 1 dereferenceable(24) [[Y]], i32 24, i1 false)
163 // CHECK-NEXT: ret void
165 void second_i32_asc(int x, asc *y, asc *r) { *r = second<int, asc>(x, *y); }
167 // CHECK-LABEL: define {{[^@]+}}@first_asc_i32
168 // CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef [[Y:%.*]], ptr nocapture noundef writeonly initializes((0, 24)) [[R:%.*]]) local_unnamed_addr #[[ATTR1]] {
169 // CHECK-NEXT: entry:
170 // CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(24) [[R]], ptr noundef nonnull align 1 dereferenceable(24) [[X]], i32 24, i1 false)
171 // CHECK-NEXT: ret void
173 void first_asc_i32(asc *x, int y, asc *r) { *r = first<asc, int>(*x, y); }
175 // CHECK-LABEL: define {{[^@]+}}@second_asc_i32
176 // CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]])
177 // CHECK-NEXT: entry:
178 // CHECK-NEXT: ret i32 [[Y]]
180 int second_asc_i32(asc *x, int y) { return second<asc, int>(*x, y); }