Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
d0da4cfe
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,发现更多精彩内容 >>
提交
d0da4cfe
编写于
5月 02, 2014
作者:
B
Brendan Zabarauskas
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement comparison operators for int and uint SIMD vectors
上级
6dd7a56e
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
135 addition
and
20 deletion
+135
-20
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/base.rs
+38
-0
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/expr.rs
+13
-14
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/mod.rs
+21
-2
src/test/compile-fail/simd-binop.rs
src/test/compile-fail/simd-binop.rs
+37
-0
src/test/run-pass/simd-binop.rs
src/test/run-pass/simd-binop.rs
+26
-4
未找到文件。
src/librustc/middle/trans/base.rs
浏览文件 @
d0da4cfe
...
...
@@ -619,6 +619,44 @@ fn die(cx: &Block) -> ! {
}
}
pub
fn
compare_simd_types
(
cx
:
&
Block
,
lhs
:
ValueRef
,
rhs
:
ValueRef
,
t
:
ty
::
t
,
size
:
uint
,
op
:
ast
::
BinOp
)
->
ValueRef
{
match
ty
::
get
(
t
)
.sty
{
ty
::
ty_float
(
_
)
=>
{
// The comparison operators for floating point vectors are challenging.
// LLVM outputs a `< size x i1 >`, but if we perform a sign extension
// then bitcast to a floating point vector, the result will be `-NaN`
// for each truth value. Because of this they are unsupported.
cx
.sess
()
.bug
(
"compare_simd_types: comparison operators
\
not supported for floating point SIMD types"
)
},
ty
::
ty_uint
(
_
)
|
ty
::
ty_int
(
_
)
=>
{
let
cmp
=
match
op
{
ast
::
BiEq
=>
lib
::
llvm
::
IntEQ
,
ast
::
BiNe
=>
lib
::
llvm
::
IntNE
,
ast
::
BiLt
=>
lib
::
llvm
::
IntSLT
,
ast
::
BiLe
=>
lib
::
llvm
::
IntSLE
,
ast
::
BiGt
=>
lib
::
llvm
::
IntSGT
,
ast
::
BiGe
=>
lib
::
llvm
::
IntSGE
,
_
=>
cx
.sess
()
.bug
(
"compare_simd_types: must be a comparison operator"
),
};
let
return_ty
=
Type
::
vector
(
&
type_of
(
cx
.ccx
(),
t
),
size
as
u64
);
// LLVM outputs an `< size x i1 >`, so we need to perform a sign extension
// to get the correctly sized type. This will compile to a single instruction
// once the IR is converted to assembly if the SIMD instruction is supported
// by the target architecture.
SExt
(
cx
,
ICmp
(
cx
,
cmp
,
lhs
,
rhs
),
return_ty
)
},
_
=>
cx
.sess
()
.bug
(
"compare_simd_types: invalid SIMD type"
),
}
}
pub
type
val_and_ty_fn
<
'r
,
'b
>
=
|
&
'b
Block
<
'b
>
,
ValueRef
,
ty
::
t
|:
'r
->
&
'b
Block
<
'b
>
;
...
...
src/librustc/middle/trans/expr.rs
浏览文件 @
d0da4cfe
...
...
@@ -1259,16 +1259,15 @@ fn trans_eager_binop<'a>(
->
DatumBlock
<
'a
,
Expr
>
{
let
_
icx
=
push_ctxt
(
"trans_eager_binop"
);
let
mut
intype
=
{
let
tcx
=
bcx
.tcx
();
let
is_simd
=
ty
::
type_is_simd
(
tcx
,
lhs_t
);
let
intype
=
{
if
ty
::
type_is_bot
(
lhs_t
)
{
rhs_t
}
else
if
is_simd
{
ty
::
simd_type
(
tcx
,
lhs_t
)
}
else
{
lhs_t
}
};
let
tcx
=
bcx
.tcx
();
if
ty
::
type_is_simd
(
tcx
,
intype
)
{
intype
=
ty
::
simd_type
(
tcx
,
intype
);
}
let
is_float
=
ty
::
type_is_fp
(
intype
);
let
signed
=
ty
::
type_is_signed
(
intype
);
let
is_
signed
=
ty
::
type_is_signed
(
intype
);
let
rhs
=
base
::
cast_shift_expr_rhs
(
bcx
,
op
,
lhs
,
rhs
);
...
...
@@ -1293,7 +1292,7 @@ fn trans_eager_binop<'a>(
// Only zero-check integers; fp /0 is NaN
bcx
=
base
::
fail_if_zero
(
bcx
,
binop_expr
.span
,
op
,
rhs
,
rhs_t
);
if
signed
{
if
is_
signed
{
SDiv
(
bcx
,
lhs
,
rhs
)
}
else
{
UDiv
(
bcx
,
lhs
,
rhs
)
...
...
@@ -1307,7 +1306,7 @@ fn trans_eager_binop<'a>(
// Only zero-check integers; fp %0 is NaN
bcx
=
base
::
fail_if_zero
(
bcx
,
binop_expr
.span
,
op
,
rhs
,
rhs_t
);
if
signed
{
if
is_
signed
{
SRem
(
bcx
,
lhs
,
rhs
)
}
else
{
URem
(
bcx
,
lhs
,
rhs
)
...
...
@@ -1319,21 +1318,21 @@ fn trans_eager_binop<'a>(
ast
::
BiBitXor
=>
Xor
(
bcx
,
lhs
,
rhs
),
ast
::
BiShl
=>
Shl
(
bcx
,
lhs
,
rhs
),
ast
::
BiShr
=>
{
if
signed
{
if
is_
signed
{
AShr
(
bcx
,
lhs
,
rhs
)
}
else
{
LShr
(
bcx
,
lhs
,
rhs
)
}
}
ast
::
BiEq
|
ast
::
BiNe
|
ast
::
BiLt
|
ast
::
BiGe
|
ast
::
BiLe
|
ast
::
BiGt
=>
{
if
ty
::
type_is_bot
(
rhs_t
)
{
C_bool
(
bcx
.ccx
(),
false
)
}
else
{
if
!
ty
::
type_is_scalar
(
rhs_t
)
{
bcx
.tcx
()
.sess
.span_bug
(
binop_expr
.span
,
"non-scalar comparison"
);
}
}
else
if
ty
::
type_is_scalar
(
rhs_t
)
{
let
cmpr
=
base
::
compare_scalar_types
(
bcx
,
lhs
,
rhs
,
rhs_t
,
op
);
bcx
=
cmpr
.bcx
;
ZExt
(
bcx
,
cmpr
.val
,
Type
::
i8
(
bcx
.ccx
()))
}
else
if
is_simd
{
base
::
compare_simd_types
(
bcx
,
lhs
,
rhs
,
intype
,
ty
::
simd_size
(
tcx
,
lhs_t
),
op
)
}
else
{
bcx
.tcx
()
.sess
.span_bug
(
binop_expr
.span
,
"comparison operator unsupported for type"
)
}
}
_
=>
{
...
...
src/librustc/middle/typeck/check/mod.rs
浏览文件 @
d0da4cfe
...
...
@@ -2102,8 +2102,27 @@ fn check_binop(fcx: &FnCtxt,
let
result_t
=
match
op
{
ast
::
BiEq
|
ast
::
BiNe
|
ast
::
BiLt
|
ast
::
BiLe
|
ast
::
BiGe
|
ast
::
BiGt
=>
ty
::
mk_bool
(),
_
=>
lhs_t
ast
::
BiGt
=>
{
if
ty
::
type_is_simd
(
tcx
,
lhs_t
)
{
if
ty
::
type_is_fp
(
ty
::
simd_type
(
tcx
,
lhs_t
))
{
fcx
.type_error_message
(
expr
.span
,
|
actual
|
{
format!
(
"binary comparison operation `{}` not supported
\
for floating point SIMD vector `{}`"
,
ast_util
::
binop_to_str
(
op
),
actual
)
},
lhs_t
,
None
);
ty
::
mk_err
()
}
else
{
lhs_t
}
}
else
{
ty
::
mk_bool
()
}
},
_
=>
lhs_t
,
};
fcx
.write_ty
(
expr
.id
,
result_t
);
...
...
src/test/compile-fail/simd-binop.rs
0 → 100644
浏览文件 @
d0da4cfe
// Copyright 2014 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.
// ignore-tidy-linelength
#![allow(experimental)]
use
std
::
unstable
::
simd
::
f32x4
;
fn
main
()
{
let
_
=
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
)
==
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
);
//~^ ERROR binary comparison operation `==` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
let
_
=
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
)
!=
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
);
//~^ ERROR binary comparison operation `!=` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
let
_
=
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
)
<
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
);
//~^ ERROR binary comparison operation `<` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
let
_
=
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
)
<=
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
);
//~^ ERROR binary comparison operation `<=` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
let
_
=
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
)
>=
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
);
//~^ ERROR binary comparison operation `>=` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
let
_
=
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
)
>
f32x4
(
0.0
,
0.0
,
0.0
,
0.0
);
//~^ ERROR binary comparison operation `>` not supported for floating point SIMD vector `std::unstable::simd::f32x4`
}
src/test/run-pass/simd-binop.rs
浏览文件 @
d0da4cfe
...
...
@@ -25,6 +25,8 @@ fn eq_i32x4(i32x4(x0, x1, x2, x3): i32x4, i32x4(y0, y1, y2, y3): i32x4) -> bool
}
pub
fn
main
()
{
// arithmetic operators
assert
!
(
eq_u32x4
(
u32x4
(
1
,
2
,
3
,
4
)
+
u32x4
(
4
,
3
,
2
,
1
),
u32x4
(
5
,
5
,
5
,
5
)));
assert
!
(
eq_u32x4
(
u32x4
(
4
,
5
,
6
,
7
)
-
u32x4
(
4
,
3
,
2
,
1
),
u32x4
(
0
,
2
,
4
,
6
)));
assert
!
(
eq_u32x4
(
u32x4
(
1
,
2
,
3
,
4
)
*
u32x4
(
4
,
3
,
2
,
1
),
u32x4
(
4
,
6
,
6
,
4
)));
...
...
@@ -43,8 +45,28 @@ pub fn main() {
assert
!
(
eq_i32x4
(
i32x4
(
1
,
2
,
3
,
4
)
<<
i32x4
(
4
,
3
,
2
,
1
),
i32x4
(
16
,
16
,
12
,
8
)));
assert
!
(
eq_i32x4
(
i32x4
(
1
,
2
,
3
,
4
)
>>
i32x4
(
4
,
3
,
2
,
1
),
i32x4
(
0
,
0
,
0
,
2
)));
assert
!
(
eq_f32x4
(
f32x4
(
1.0
,
2.0
,
3.0
,
4.0
)
+
f32x4
(
4.0
,
3.0
,
2.0
,
1.0
),
f32x4
(
5.0
,
5.0
,
5.0
,
5.0
)));
assert
!
(
eq_f32x4
(
f32x4
(
1.0
,
2.0
,
3.0
,
4.0
)
-
f32x4
(
4.0
,
3.0
,
2.0
,
1.0
),
f32x4
(
-
3.0
,
-
1.0
,
1.0
,
3.0
)));
assert
!
(
eq_f32x4
(
f32x4
(
1.0
,
2.0
,
3.0
,
4.0
)
*
f32x4
(
4.0
,
3.0
,
2.0
,
1.0
),
f32x4
(
4.0
,
6.0
,
6.0
,
4.0
)));
assert
!
(
eq_f32x4
(
f32x4
(
1.0
,
2.0
,
3.0
,
4.0
)
/
f32x4
(
4.0
,
4.0
,
2.0
,
1.0
),
f32x4
(
0.25
,
0.5
,
1.5
,
4.0
)));
assert
!
(
eq_f32x4
(
f32x4
(
1.0
,
2.0
,
3.0
,
4.0
)
+
f32x4
(
4.0
,
3.0
,
2.0
,
1.0
),
f32x4
(
5.0
,
5.0
,
5.0
,
5.0
)));
assert
!
(
eq_f32x4
(
f32x4
(
1.0
,
2.0
,
3.0
,
4.0
)
-
f32x4
(
4.0
,
3.0
,
2.0
,
1.0
),
f32x4
(
-
3.0
,
-
1.0
,
1.0
,
3.0
)));
assert
!
(
eq_f32x4
(
f32x4
(
1.0
,
2.0
,
3.0
,
4.0
)
*
f32x4
(
4.0
,
3.0
,
2.0
,
1.0
),
f32x4
(
4.0
,
6.0
,
6.0
,
4.0
)));
assert
!
(
eq_f32x4
(
f32x4
(
1.0
,
2.0
,
3.0
,
4.0
)
/
f32x4
(
4.0
,
4.0
,
2.0
,
1.0
),
f32x4
(
0.25
,
0.5
,
1.5
,
4.0
)));
// comparison operators
assert
!
(
eq_u32x4
(
u32x4
(
1
,
2
,
3
,
4
)
==
u32x4
(
3
,
2
,
1
,
0
),
u32x4
(
0
,
!
0
,
0
,
0
)));
assert
!
(
eq_u32x4
(
u32x4
(
1
,
2
,
3
,
4
)
!=
u32x4
(
3
,
2
,
1
,
0
),
u32x4
(
!
0
,
0
,
!
0
,
!
0
)));
assert
!
(
eq_u32x4
(
u32x4
(
1
,
2
,
3
,
4
)
<
u32x4
(
3
,
2
,
1
,
0
),
u32x4
(
!
0
,
0
,
0
,
0
)));
assert
!
(
eq_u32x4
(
u32x4
(
1
,
2
,
3
,
4
)
<=
u32x4
(
3
,
2
,
1
,
0
),
u32x4
(
!
0
,
!
0
,
0
,
0
)));
assert
!
(
eq_u32x4
(
u32x4
(
1
,
2
,
3
,
4
)
>=
u32x4
(
3
,
2
,
1
,
0
),
u32x4
(
0
,
!
0
,
!
0
,
!
0
)));
assert
!
(
eq_u32x4
(
u32x4
(
1
,
2
,
3
,
4
)
>
u32x4
(
3
,
2
,
1
,
0
),
u32x4
(
0
,
0
,
!
0
,
!
0
)));
assert
!
(
eq_i32x4
(
i32x4
(
1
,
2
,
3
,
4
)
==
i32x4
(
3
,
2
,
1
,
0
),
i32x4
(
0
,
!
0
,
0
,
0
)));
assert
!
(
eq_i32x4
(
i32x4
(
1
,
2
,
3
,
4
)
!=
i32x4
(
3
,
2
,
1
,
0
),
i32x4
(
!
0
,
0
,
!
0
,
!
0
)));
assert
!
(
eq_i32x4
(
i32x4
(
1
,
2
,
3
,
4
)
<
i32x4
(
3
,
2
,
1
,
0
),
i32x4
(
!
0
,
0
,
0
,
0
)));
assert
!
(
eq_i32x4
(
i32x4
(
1
,
2
,
3
,
4
)
<=
i32x4
(
3
,
2
,
1
,
0
),
i32x4
(
!
0
,
!
0
,
0
,
0
)));
assert
!
(
eq_i32x4
(
i32x4
(
1
,
2
,
3
,
4
)
>=
i32x4
(
3
,
2
,
1
,
0
),
i32x4
(
0
,
!
0
,
!
0
,
!
0
)));
assert
!
(
eq_i32x4
(
i32x4
(
1
,
2
,
3
,
4
)
>
i32x4
(
3
,
2
,
1
,
0
),
i32x4
(
0
,
0
,
!
0
,
!
0
)));
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录