Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
a07eb0ab
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a07eb0ab
编写于
5月 15, 2023
作者:
E
Erik Desjardins
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
implement vector-containing aggregate alignment for x86 darwin
上级
be1d4e3e
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
109 addition
and
31 deletion
+109
-31
compiler/rustc_target/src/abi/call/x86.rs
compiler/rustc_target/src/abi/call/x86.rs
+51
-31
tests/codegen/align-byval-vector.rs
tests/codegen/align-byval-vector.rs
+58
-0
未找到文件。
compiler/rustc_target/src/abi/call/x86.rs
浏览文件 @
a07eb0ab
use
crate
::
abi
::
call
::{
ArgAttribute
,
FnAbi
,
PassMode
,
Reg
,
RegKind
};
use
crate
::
abi
::{
A
lign
,
HasDataLayout
,
TyAbiInterface
};
use
crate
::
abi
::{
A
bi
,
Align
,
HasDataLayout
,
TyAbiInterface
,
TyAndLayout
};
use
crate
::
spec
::
HasTargetSpec
;
#[derive(PartialEq)]
...
...
@@ -53,38 +53,58 @@ pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, flavor: F
if
arg
.is_ignore
()
{
continue
;
}
if
!
arg
.layout
.is_aggregate
()
{
arg
.extend_integer_width_to
(
32
);
continue
;
}
// We need to compute the alignment of the `byval` argument. The rules can be found in
// `X86_32ABIInfo::getTypeStackAlignInBytes` in Clang's `TargetInfo.cpp`. Summarized here,
// they are:
//
// 1. If the natural alignment of the type is less than or equal to 4, the alignment is 4.
//
// 2. Otherwise, on Linux, the alignment of any vector type is the natural alignment.
// (This doesn't matter here because we ensure we have an aggregate with the check above.)
//
// 3. Otherwise, on Apple platforms, the alignment of anything that contains a vector type
// is 16.
//
// 4. If none of these conditions are true, the alignment is 4.
let
t
=
cx
.target_spec
();
let
align_4
=
Align
::
from_bytes
(
4
)
.unwrap
();
let
align_16
=
Align
::
from_bytes
(
16
)
.unwrap
();
let
byval_align
=
if
arg
.layout.align.abi
<
align_4
{
align_4
}
else
if
t
.is_like_osx
&&
arg
.layout.align.abi
>=
align_16
{
// FIXME(pcwalton): This is dubious--we should actually be looking inside the type to
// determine if it contains SIMD vector values--but I think it's fine?
align_16
}
else
{
align_4
};
if
arg
.layout
.is_aggregate
()
{
// We need to compute the alignment of the `byval` argument. The rules can be found in
// `X86_32ABIInfo::getTypeStackAlignInBytes` in Clang's `TargetInfo.cpp`. Summarized
// here, they are:
//
// 1. If the natural alignment of the type is <= 4, the alignment is 4.
//
// 2. Otherwise, on Linux, the alignment of any vector type is the natural alignment.
// This doesn't matter here because we only pass aggregates via `byval`, not vectors.
//
// 3. Otherwise, on Apple platforms, the alignment of anything that contains a vector
// type is 16.
//
// 4. If none of these conditions are true, the alignment is 4.
fn
contains_vector
<
'a
,
Ty
,
C
>
(
cx
:
&
C
,
layout
:
TyAndLayout
<
'a
,
Ty
>
)
->
bool
where
Ty
:
TyAbiInterface
<
'a
,
C
>
+
Copy
,
{
match
layout
.abi
{
Abi
::
Uninhabited
|
Abi
::
Scalar
(
_
)
|
Abi
::
ScalarPair
(
..
)
=>
false
,
Abi
::
Vector
{
..
}
=>
true
,
Abi
::
Aggregate
{
..
}
=>
{
for
i
in
0
..
layout
.fields
.count
()
{
if
contains_vector
(
cx
,
layout
.field
(
cx
,
i
))
{
return
true
;
}
}
false
}
}
}
arg
.make_indirect_byval
(
Some
(
byval_align
));
let
t
=
cx
.target_spec
();
let
align_4
=
Align
::
from_bytes
(
4
)
.unwrap
();
let
align_16
=
Align
::
from_bytes
(
16
)
.unwrap
();
let
byval_align
=
if
arg
.layout.align.abi
<
align_4
{
// (1.)
align_4
}
else
if
t
.is_like_osx
&&
contains_vector
(
cx
,
arg
.layout
)
{
// (3.)
align_16
}
else
{
// (4.)
align_4
};
arg
.make_indirect_byval
(
Some
(
byval_align
));
}
else
{
arg
.extend_integer_width_to
(
32
);
}
}
if
flavor
==
Flavor
::
FastcallOrVectorcall
{
...
...
tests/codegen/align-byval-vector.rs
0 → 100644
浏览文件 @
a07eb0ab
// revisions:x86-linux x86-darwin
//[x86-linux] compile-flags: --target i686-unknown-linux-gnu
//[x86-linux] needs-llvm-components: x86
//[x86-darwin] compile-flags: --target i686-apple-darwin
//[x86-darwin] needs-llvm-components: x86
// Tests that aggregates containing vector types get their alignment increased to 16 on Darwin.
#![feature(no_core,
lang_items,
repr_simd,
simd_ffi)]
#![crate_type
=
"lib"
]
#![no_std]
#![no_core]
#![allow(non_camel_case_types)]
#[lang
=
"sized"
]
trait
Sized
{}
#[lang
=
"freeze"
]
trait
Freeze
{}
#[lang
=
"copy"
]
trait
Copy
{}
#[repr(simd)]
pub
struct
i32x4
(
i32
,
i32
,
i32
,
i32
);
#[repr(C)]
pub
struct
Foo
{
a
:
i32x4
,
b
:
i8
,
}
// This tests that we recursively check for vector types, not just at the top level.
#[repr(C)]
pub
struct
DoubleFoo
{
one
:
Foo
,
two
:
Foo
,
}
extern
"C"
{
// x86-linux: declare void @f({{.*}}byval(%Foo) align 4{{.*}})
// x86-darwin: declare void @f({{.*}}byval(%Foo) align 16{{.*}})
fn
f
(
foo
:
Foo
);
// x86-linux: declare void @g({{.*}}byval(%DoubleFoo) align 4{{.*}})
// x86-darwin: declare void @g({{.*}}byval(%DoubleFoo) align 16{{.*}})
fn
g
(
foo
:
DoubleFoo
);
}
pub
fn
main
()
{
unsafe
{
f
(
Foo
{
a
:
i32x4
(
1
,
2
,
3
,
4
),
b
:
0
})
}
unsafe
{
g
(
DoubleFoo
{
one
:
Foo
{
a
:
i32x4
(
1
,
2
,
3
,
4
),
b
:
0
},
two
:
Foo
{
a
:
i32x4
(
1
,
2
,
3
,
4
),
b
:
0
},
})
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录