Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
a9101095
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,发现更多精彩内容 >>
提交
a9101095
编写于
1月 26, 2018
作者:
A
Alex Crichton
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'simd-always-mem' of
https://github.com/alexcrichton/rust
into rollup
上级
a7f41567
502de01f
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
207 addition
and
3 deletion
+207
-3
src/librustc_trans/abi.rs
src/librustc_trans/abi.rs
+25
-0
src/test/codegen/x86_mmx.rs
src/test/codegen/x86_mmx.rs
+1
-3
src/test/run-pass/simd-target-feature-mixup.rs
src/test/run-pass/simd-target-feature-mixup.rs
+181
-0
未找到文件。
src/librustc_trans/abi.rs
浏览文件 @
a9101095
...
@@ -871,6 +871,31 @@ fn adjust_for_abi(&mut self,
...
@@ -871,6 +871,31 @@ fn adjust_for_abi(&mut self,
match
arg
.layout.abi
{
match
arg
.layout.abi
{
layout
::
Abi
::
Aggregate
{
..
}
=>
{}
layout
::
Abi
::
Aggregate
{
..
}
=>
{}
// This is a fun case! The gist of what this is doing is
// that we want callers and callees to always agree on the
// ABI of how they pass SIMD arguments. If we were to *not*
// make these arguments indirect then they'd be immediates
// in LLVM, which means that they'd used whatever the
// appropriate ABI is for the callee and the caller. That
// means, for example, if the caller doesn't have AVX
// enabled but the callee does, then passing an AVX argument
// across this boundary would cause corrupt data to show up.
//
// This problem is fixed by unconditionally passing SIMD
// arguments through memory between callers and callees
// which should get them all to agree on ABI regardless of
// target feature sets. Some more information about this
// issue can be found in #44367.
//
// Note that the platform intrinsic ABI is exempt here as
// that's how we connect up to LLVM and it's unstable
// anyway, we control all calls to it in libstd.
layout
::
Abi
::
Vector
{
..
}
if
abi
!=
Abi
::
PlatformIntrinsic
=>
{
arg
.make_indirect
();
return
}
_
=>
return
_
=>
return
}
}
...
...
src/test/codegen/x86_mmx.rs
浏览文件 @
a9101095
...
@@ -22,9 +22,7 @@
...
@@ -22,9 +22,7 @@
#[no_mangle]
#[no_mangle]
pub
fn
a
(
a
:
&
mut
i8x8
,
b
:
i8x8
)
->
i8x8
{
pub
fn
a
(
a
:
&
mut
i8x8
,
b
:
i8x8
)
->
i8x8
{
// CHECK-LABEL: define x86_mmx @a(x86_mmx*{{.*}}, x86_mmx{{.*}})
// CHECK-LABEL: define void @a(x86_mmx*{{.*}}, x86_mmx*{{.*}}, x86_mmx*{{.*}})
// CHECK: store x86_mmx %b, x86_mmx* %a
// CHECK: ret x86_mmx %b
*
a
=
b
;
*
a
=
b
;
return
b
return
b
}
}
src/test/run-pass/simd-target-feature-mixup.rs
0 → 100644
浏览文件 @
a9101095
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(repr_simd,
target_feature,
cfg_target_feature)]
use
std
::
process
::{
Command
,
ExitStatus
};
use
std
::
env
;
fn
main
()
{
if
let
Some
(
level
)
=
env
::
args
()
.nth
(
1
)
{
return
test
::
main
(
&
level
)
}
let
me
=
env
::
current_exe
()
.unwrap
();
for
level
in
[
"sse"
,
"avx"
,
"avx512"
]
.iter
()
{
let
status
=
Command
::
new
(
&
me
)
.arg
(
level
)
.status
()
.unwrap
();
if
status
.success
()
{
println!
(
"success with {}"
,
level
);
continue
}
// We don't actually know if our computer has the requisite target features
// for the test below. Testing for that will get added to libstd later so
// for now just asume sigill means this is a machine that can't run this test.
if
is_sigill
(
status
)
{
println!
(
"sigill with {}, assuming spurious"
,
level
);
continue
}
panic!
(
"invalid status at {}: {}"
,
level
,
status
);
}
}
#[cfg(unix)]
fn
is_sigill
(
status
:
ExitStatus
)
->
bool
{
use
std
::
os
::
unix
::
prelude
::
*
;
status
.signal
()
==
Some
(
4
)
}
#[cfg(any(target_arch
=
"x86"
,
target_arch
=
"x86_64"
))]
#[allow(bad_style)]
mod
test
{
// An SSE type
#[repr(simd)]
#[derive(PartialEq,
Debug,
Clone,
Copy)]
struct
__
m128i
(
u64
,
u64
);
// An AVX type
#[repr(simd)]
#[derive(PartialEq,
Debug,
Clone,
Copy)]
struct
__
m256i
(
u64
,
u64
,
u64
,
u64
);
// An AVX-512 type
#[repr(simd)]
#[derive(PartialEq,
Debug,
Clone,
Copy)]
struct
__
m512i
(
u64
,
u64
,
u64
,
u64
,
u64
,
u64
,
u64
,
u64
);
pub
fn
main
(
level
:
&
str
)
{
unsafe
{
main_normal
(
level
);
main_sse
(
level
);
if
level
==
"sse"
{
return
}
main_avx
(
level
);
if
level
==
"avx"
{
return
}
main_avx512
(
level
);
}
}
macro_rules!
mains
{
(
$
(
$
(
#[
$
attr:meta]
)
*
unsafe
fn
$main:ident
(
level
:
&
str
)
{
...
}
)
*
)
=>
(
$
(
$
(
#[
$
attr]
)
*
unsafe
fn
$main
(
level
:
&
str
)
{
let
m128
=
__
m128i
(
1
,
2
);
let
m256
=
__
m256i
(
3
,
4
,
5
,
6
);
let
m512
=
__
m512i
(
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
);
assert_eq!
(
id_sse_128
(
m128
),
m128
);
assert_eq!
(
id_sse_256
(
m256
),
m256
);
assert_eq!
(
id_sse_512
(
m512
),
m512
);
if
level
==
"sse"
{
return
}
assert_eq!
(
id_avx_128
(
m128
),
m128
);
assert_eq!
(
id_avx_256
(
m256
),
m256
);
assert_eq!
(
id_avx_512
(
m512
),
m512
);
if
level
==
"avx"
{
return
}
assert_eq!
(
id_avx512_128
(
m128
),
m128
);
assert_eq!
(
id_avx512_256
(
m256
),
m256
);
assert_eq!
(
id_avx512_512
(
m512
),
m512
);
}
)
*
)
}
mains!
{
unsafe
fn
main_normal
(
level
:
&
str
)
{
...
}
#[target_feature(enable
=
"sse2"
)]
unsafe
fn
main_sse
(
level
:
&
str
)
{
...
}
#[target_feature(enable
=
"avx"
)]
unsafe
fn
main_avx
(
level
:
&
str
)
{
...
}
#[target_feature(enable
=
"avx512bw"
)]
unsafe
fn
main_avx512
(
level
:
&
str
)
{
...
}
}
#[target_feature(enable
=
"sse2"
)]
unsafe
fn
id_sse_128
(
a
:
__
m128i
)
->
__
m128i
{
assert_eq!
(
a
,
__
m128i
(
1
,
2
));
a
.clone
()
}
#[target_feature(enable
=
"sse2"
)]
unsafe
fn
id_sse_256
(
a
:
__
m256i
)
->
__
m256i
{
assert_eq!
(
a
,
__
m256i
(
3
,
4
,
5
,
6
));
a
.clone
()
}
#[target_feature(enable
=
"sse2"
)]
unsafe
fn
id_sse_512
(
a
:
__
m512i
)
->
__
m512i
{
assert_eq!
(
a
,
__
m512i
(
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
));
a
.clone
()
}
#[target_feature(enable
=
"avx"
)]
unsafe
fn
id_avx_128
(
a
:
__
m128i
)
->
__
m128i
{
assert_eq!
(
a
,
__
m128i
(
1
,
2
));
a
.clone
()
}
#[target_feature(enable
=
"avx"
)]
unsafe
fn
id_avx_256
(
a
:
__
m256i
)
->
__
m256i
{
assert_eq!
(
a
,
__
m256i
(
3
,
4
,
5
,
6
));
a
.clone
()
}
#[target_feature(enable
=
"avx"
)]
unsafe
fn
id_avx_512
(
a
:
__
m512i
)
->
__
m512i
{
assert_eq!
(
a
,
__
m512i
(
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
));
a
.clone
()
}
#[target_feature(enable
=
"avx512bw"
)]
unsafe
fn
id_avx512_128
(
a
:
__
m128i
)
->
__
m128i
{
assert_eq!
(
a
,
__
m128i
(
1
,
2
));
a
.clone
()
}
#[target_feature(enable
=
"avx512bw"
)]
unsafe
fn
id_avx512_256
(
a
:
__
m256i
)
->
__
m256i
{
assert_eq!
(
a
,
__
m256i
(
3
,
4
,
5
,
6
));
a
.clone
()
}
#[target_feature(enable
=
"avx512bw"
)]
unsafe
fn
id_avx512_512
(
a
:
__
m512i
)
->
__
m512i
{
assert_eq!
(
a
,
__
m512i
(
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
));
a
.clone
()
}
}
#[cfg(not(any(target_arch
=
"x86"
,
target_arch
=
"x86_64"
)))]
mod
test
{
pub
fn
main
(
level
:
&
str
)
{}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录