Correctly call x64 varargs.

This commit is contained in:
Christoffer Lerno
2022-01-13 21:22:50 +01:00
parent 5683fe3f8c
commit eed5b7db54
19 changed files with 366 additions and 199 deletions

View File

@@ -58,6 +58,7 @@ class Issues:
self.files = []
self.errors = {}
self.warnings = {}
self.opts = []
def exit_error(self, message):
print('Error in file ' + self.sourcefile.filepath + ': ' + message)
@@ -109,7 +110,10 @@ class Issues:
target = " --target " + self.arch
if (self.debuginfo):
debug = "-g "
code = subprocess.run(self.conf.compiler + target + ' -O0 ' + debug + args, universal_newlines=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
opts = ""
for opt in self.opts:
opts += ' -' + opt
code = subprocess.run(self.conf.compiler + target + ' -O0 ' + opts + ' ' + debug + args, universal_newlines=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
os.chdir(self.conf.cwd)
if code.returncode != 0 and code.returncode != 1:
self.set_failed()
@@ -141,6 +145,9 @@ class Issues:
if (line.startswith("debuginfo:")):
self.debuginfo = line[10:].strip() == "yes"
return
if (line.startswith("opt:")):
self.opts.append(line[4:].strip())
return
if (line.startswith("target:")):
self.arch = line[7:].strip()
return

View File

@@ -0,0 +1,84 @@
// #target: x64-darwin
// #opt: mavx
module test;
define Mm256 = float[<8>];
struct St256 {
Mm256 m;
}
St256 x38;
Mm256 x37;
extern fn void f38(St256 x);
extern fn void f37(Mm256 x);
fn void f39() { f38(x38); f37(x37); }
// The two next tests make sure that the struct below is passed
// in the same way regardless of avx being used
// CHECK: declare void @func40(%struct.t128* byval(%struct.t128) align 16)
define Mm128 = float[<4>];
struct Two128 {
Mm128 m;
Mm128 n;
}
extern fn void func40(Two128 s);
fn void func41(Two128 s) {
func40(s);
}
struct Atwo128 {
Mm128[2] array;
}
struct Sa {
Atwo128 x;
}
extern fn void func42(Sa s);
fn void func43(Sa s) {
func42(s);
}
define Vec46 = float[<2>];
extern fn void f46(Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46);
fn void test46() { Vec46 x = {1,2}; f46(x,x,x,x,x,x,x,x,x,x); }
struct Vec47 { uint a; }
extern fn void f47(int,int,int,int,int,int,Vec47);
fn void test47(int a, Vec47 b) { f47(a, a, a, a, a, a, b); }
fn void test49_helper(double, ...);
fn void test49(double d, double e) { test49_helper(d, e); }
extern fn void test52_helper(int, ...);
Mm256 x52;
fn void test52() {
test52_helper(0, x52, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0);
}
/* #expect: test.ll
declare void @f38(<8 x float>)
declare void @f37(<8 x float>)
declare void @func40(%Two128* byval(%Two128) align 16)
define void @test.func41(%Two128* byval(%Two128) align 16 %0)
declare void @func42(%Sa* byval(%Sa) align 16)
define void @test.func43(%Sa* byval(%Sa) align 16 %0)
declare void @f46(double, double, double, double, double, double, double, double, <2 x float>* byval(<2 x float>) align 8, <2 x float>* byval(<2 x float>) align 8)
declare void @f47(i32, i32, i32, i32, i32, i32, i32)
declare void @test.test49_helper(double, ...)
define void @test.test49(double %0, double %1)
entry:
call void (double, ...) @test.test49_helper(double %0, double %1)
ret void
call void (i32, ...) @test52_helper(i32 0, <8 x float>* byval(<8 x float>) align 32 %indirectarg, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00)

View File

@@ -0,0 +1,55 @@
// #target: x64-darwin
// #opt: mno-avx
module test;
define Mm256 = float[<8>];
struct St256 {
Mm256 m;
}
St256 x38;
Mm256 x37;
extern fn void f38(St256 x);
extern fn void f37(Mm256 x);
fn void f39() { f38(x38); f37(x37); }
// The two next tests make sure that the struct below is passed
// in the same way regardless of avx being used
// CHECK: declare void @func40(%struct.t128* byval(%struct.t128) align 16)
define Mm128 = float[<4>];
struct Two128 {
Mm128 m;
Mm128 n;
}
extern fn void func40(Two128 s);
fn void func41(Two128 s) {
func40(s);
}
struct Atwo128 {
Mm128[2] array;
}
struct Sa {
Atwo128 x;
}
extern fn void func42(Sa s);
fn void func43(Sa s) {
func42(s);
}
/* #expect: test.ll
declare void @f38(%St256* byval(%St256) align 32)
declare void @f37(<8 x float>* byval(<8 x float>) align 32)
declare void @func40(%Two128* byval(%Two128) align 16)
define void @test.func41(%Two128* byval(%Two128) align 16 %0)
declare void @func42(%Sa* byval(%Sa) align 16)
define void @test.func43(%Sa* byval(%Sa) align 16 %0)

View File

@@ -64,6 +64,86 @@ fn float[<4>] f25(float[<4>] x) {
return x+x;
}
struct Foo26 {
int *x;
float *y;
}
fn Foo26 f26(Foo26 *p) {
return *p;
}
struct V4f32wrapper {
float[<4>] v;
}
fn V4f32wrapper f27(V4f32wrapper x) {
return x;
}
// PR22563 - We should unwrap simple structs and arrays to pass
// and return them in the appropriate vector registers if possible.
define V8f32 = float[<8>];
struct V8f32wrapper {
V8f32 v;
}
fn V8f32wrapper f27a(V8f32wrapper x) {
return x;
}
struct V8f32wrapper_wrapper {
V8f32[1] v;
}
fn V8f32wrapper_wrapper f27b(V8f32wrapper_wrapper x) {
return x;
}
struct F28c {
double x;
int y;
}
fn void f28(F28c c) {
}
struct Inner
{
double x;
int y;
}
struct F29a
{
Inner[1] c;
}
fn void f29a(F29a a) {
}
struct St0 {
char[8] f0; char f2; char f3; char f4; }
fn void f30(St0 p_4) {
}
struct F31foo { float a, b, c; }
fn float f31(F31foo x) {
return x.c;
}
define V1i64 = ulong[<1>];
fn V1i64 f34(V1i64 arg) { return arg; }
define V1i64_2 = uint[<2>];
fn V1i64_2 f35(V1i64_2 arg) { return arg+arg; }
define V2i32 = float[<2>];
fn V2i32 f36(V2i32 arg) { return arg; }
/* #expect: test.ll
define i32 @test.f12_0()
@@ -91,3 +171,15 @@ entry:
%fadd = fadd <4 x float> %0, %0
ret <4 x float> %fadd
}
define { i32*, float* } @test.f26(%Foo26* %0)
define <4 x float> @test.f27(<4 x float> %0)
define <8 x float> @test.f27a(<8 x float> %0)
define <8 x float> @test.f27b(<8 x float> %0)
define void @test.f28(double %0, i32 %1)
define void @test.f29a(double %0, i32 %1)
define void @test.f30(i64 %0, i24 %1)
define float @test.f31(<2 x float> %0, float %1)
define double @test.f34(double %0)
define double @test.f35(double %0)
define double @test.f36(double %0)