mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
* Optimize vector load / store. Fixes to alignment. Support typedef with `@simd` and `@align` #2543. Update vector ABI #2542 * Fix alignment issue with indirect arguments.
273 lines
6.6 KiB
Plaintext
273 lines
6.6 KiB
Plaintext
// #target: macos-x64
|
|
// #opt: --x86cpu=avx1
|
|
module test;
|
|
|
|
typedef Mm256 = float[<8>] @simd;
|
|
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)
|
|
|
|
typedef Mm128 = float[<4>] @simd;
|
|
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);
|
|
}
|
|
|
|
|
|
typedef Vec46 = float[<2>] @simd;
|
|
extern fn void f46(Vec46 a, Vec46 b, Vec46 c, Vec46 d, Vec46 e, Vec46 f, Vec46 g, Vec46 h, Vec46 i, Vec46 j);
|
|
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); }
|
|
|
|
extern fn void test49_helper(double, ...);
|
|
fn void test49(double d, double e) { test49_helper(d, e); }
|
|
|
|
struct Complex { double i; double c; }
|
|
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, (Complex) { 0, 1.0 });
|
|
}
|
|
|
|
extern fn void test54_helper(Mm256, ...);
|
|
Mm256 x54;
|
|
fn void test54()
|
|
{
|
|
test54_helper(x54, x54, 1.0, 1.0, 1.0, 1.0, 1.0, (Complex) { 0, 1.0 });
|
|
test54_helper(x54, x54, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, (Complex) { 0, 1.0 });
|
|
}
|
|
|
|
typedef Mm512 = float[<16>] @simd;
|
|
struct St512
|
|
{
|
|
Mm512 m;
|
|
}
|
|
|
|
St512 x55;
|
|
Mm512 x56;
|
|
|
|
extern fn void f55(St512 x);
|
|
|
|
extern fn void f56(Mm512 x);
|
|
fn void f57() { f55(x55); f56(x56); }
|
|
|
|
struct Two256
|
|
{
|
|
Mm256 m;
|
|
Mm256 n;
|
|
}
|
|
|
|
extern fn void f58(Two256 s);
|
|
fn void f59(Two256 s)
|
|
{
|
|
f58(s);
|
|
}
|
|
|
|
struct Atwo256
|
|
{
|
|
Mm256[2] array;
|
|
}
|
|
|
|
struct SAtwo256
|
|
{
|
|
Atwo256 x;
|
|
}
|
|
|
|
extern fn void f60(SAtwo256 s);
|
|
fn void f61(SAtwo256 s)
|
|
{
|
|
f60(s);
|
|
}
|
|
|
|
|
|
/* #expect: test.ll
|
|
|
|
|
|
declare void @f38(<8 x float>) #0
|
|
|
|
; Function Attrs:
|
|
declare void @f37(<8 x float>) #0
|
|
|
|
; Function Attrs:
|
|
define void @test.f39() #0 {
|
|
entry:
|
|
%0 = load <8 x float>, ptr @test.x38, align 32
|
|
call void @f38(<8 x float> %0)
|
|
%1 = load <8 x float>, ptr @test.x37, align 32
|
|
call void @f37(<8 x float> %1)
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
declare void @func40(ptr byval(%Two128) align 16) #0
|
|
|
|
; Function Attrs:
|
|
define void @test.func41(ptr byval(%Two128) align 16 %0) #0 {
|
|
entry:
|
|
call void @func40(ptr byval(%Two128) align 16 %0)
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
declare void @func42(ptr byval(%Sa) align 16) #0
|
|
|
|
; Function Attrs:
|
|
define void @test.func43(ptr byval(%Sa) align 16 %0) #0 {
|
|
entry:
|
|
call void @func42(ptr byval(%Sa) align 16 %0)
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
declare void @f46(double, double, double, double, double, double, double, double, ptr byval(<2 x float>) align 8, ptr byval(<2 x float>) align 8) #0
|
|
|
|
; Function Attrs:
|
|
define void @test.test46() #0 {
|
|
entry:
|
|
%x = alloca <2 x float>, align 8
|
|
store <2 x float> <float 1.000000e+00, float 2.000000e+00>, ptr %x, align 8
|
|
%0 = load double, ptr %x, align 8
|
|
%1 = load double, ptr %x, align 8
|
|
%2 = load double, ptr %x, align 8
|
|
%3 = load double, ptr %x, align 8
|
|
%4 = load double, ptr %x, align 8
|
|
%5 = load double, ptr %x, align 8
|
|
%6 = load double, ptr %x, align 8
|
|
%7 = load double, ptr %x, align 8
|
|
call void @f46(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, ptr byval(<2 x float>) align 8 %x, ptr byval(<2 x float>) align 8 %x)
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
declare void @f47(i32, i32, i32, i32, i32, i32, i32) #0
|
|
|
|
; Function Attrs:
|
|
define void @test.test47(i32 %0, i32 %1) #0 {
|
|
entry:
|
|
%b = alloca %Vec47, align 4
|
|
store i32 %1, ptr %b, align 4
|
|
%2 = load i32, ptr %b, align 4
|
|
call void @f47(i32 %0, i32 %0, i32 %0, i32 %0, i32 %0, i32 %0, i32 %2)
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
declare void @test49_helper(double, ...) #0
|
|
|
|
; Function Attrs:
|
|
define void @test.test49(double %0, double %1) #0 {
|
|
entry:
|
|
call void (double, ...) @test49_helper(double %0, double %1)
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
declare void @test52_helper(i32, ...) #0
|
|
|
|
; Function Attrs:
|
|
define void @test.test52() #0 {
|
|
entry:
|
|
%literal = alloca %Complex, align 8
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal, ptr align 8 @.__const, i32 16, i1 false)
|
|
%0 = load <8 x float>, ptr @test.x52, align 32
|
|
%lo = load double, ptr %literal, align 8
|
|
%ptradd = getelementptr inbounds i8, ptr %literal, i64 8
|
|
%hi = load double, ptr %ptradd, align 8
|
|
call void (i32, ...) @test52_helper(i32 0, <8 x float> %0, 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 %lo, double %hi)
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
declare void @test54_helper(<8 x float>, ...) #0
|
|
|
|
; Function Attrs:
|
|
define void @test.test54() #0 {
|
|
entry:
|
|
%literal = alloca %Complex, align 8
|
|
%literal1 = alloca %Complex, align 8
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal, ptr align 8 @.__const.6, i32 16, i1 false)
|
|
%0 = load <8 x float>, ptr @test.x54, align 32
|
|
%1 = load <8 x float>, ptr @test.x54, align 32
|
|
%lo = load double, ptr %literal, align 8
|
|
%ptradd = getelementptr inbounds i8, ptr %literal, i64 8
|
|
%hi = load double, ptr %ptradd, align 8
|
|
call void (<8 x float>, ...) @test54_helper(<8 x float> %0, <8 x float> %1, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double %lo, double %hi)
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal1, ptr align 8 @.__const.7, i32 16, i1 false)
|
|
%2 = load <8 x float>, ptr @test.x54, align 32
|
|
%3 = load <8 x float>, ptr @test.x54, align 32
|
|
call void (<8 x float>, ...) @test54_helper(<8 x float> %2, <8 x float> %3, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, ptr byval(%Complex) align 8 %literal1)
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
declare void @f55(ptr byval(%St512) align 64) #0
|
|
|
|
; Function Attrs:
|
|
declare void @f56(ptr byval(<16 x float>) align 64) #0
|
|
|
|
; Function Attrs:
|
|
define void @test.f57() #0 {
|
|
entry:
|
|
call void @f55(ptr byval(%St512) align 64 @test.x55)
|
|
call void @f56(ptr byval(<16 x float>) align 64 @test.x56)
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
declare void @f58(ptr byval(%Two256) align 32) #0
|
|
|
|
; Function Attrs:
|
|
define void @test.f59(ptr byval(%Two256) align 32 %0) #0 {
|
|
entry:
|
|
call void @f58(ptr byval(%Two256) align 32 %0)
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
declare void @f60(ptr byval(%SAtwo256) align 32) #0
|
|
|
|
; Function Attrs:
|
|
define void @test.f61(ptr byval(%SAtwo256) align 32 %0) #0 {
|
|
entry:
|
|
call void @f60(ptr byval(%SAtwo256) align 32 %0)
|
|
ret void
|
|
} |