add compile fail tests
This commit is contained in:
parent
8478fa2007
commit
4fe6acf972
4 changed files with 125 additions and 1 deletions
|
@ -621,6 +621,7 @@ extern "C" {
|
|||
pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
|
||||
pub fn LLVMRustConstInt128Get(ConstantVal: ValueRef, SExt: bool,
|
||||
high: *mut u64, low: *mut u64) -> bool;
|
||||
pub fn LLVMConstRealGetDouble (ConstantVal: ValueRef, losesInfo: *mut Bool) -> f64;
|
||||
|
||||
|
||||
// Operations on composite constants
|
||||
|
@ -1607,6 +1608,7 @@ extern "C" {
|
|||
pub fn LLVMRustWriteValueToString(value_ref: ValueRef, s: RustStringRef);
|
||||
|
||||
pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
|
||||
pub fn LLVMIsAConstantFP(value_ref: ValueRef) -> ValueRef;
|
||||
|
||||
pub fn LLVMRustPassKind(Pass: PassRef) -> PassKind;
|
||||
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef;
|
||||
|
|
|
@ -270,6 +270,19 @@ pub fn const_get_elt(v: ValueRef, idx: u64) -> ValueRef {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn const_get_real(v: ValueRef) -> Option<(f64, bool)> {
|
||||
unsafe {
|
||||
if is_const_real(v) {
|
||||
let mut loses_info: llvm::Bool = ::std::mem::uninitialized();
|
||||
let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info as *mut llvm::Bool);
|
||||
let loses_info = if loses_info == 1 { true } else { false };
|
||||
Some((r, loses_info))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn const_to_uint(v: ValueRef) -> u64 {
|
||||
unsafe {
|
||||
llvm::LLVMConstIntGetZExtValue(v)
|
||||
|
@ -282,6 +295,13 @@ pub fn is_const_integral(v: ValueRef) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_const_real(v: ValueRef) -> bool {
|
||||
unsafe {
|
||||
!llvm::LLVMIsAConstantFP(v).is_null()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
fn hi_lo_to_u128(lo: u64, hi: u64) -> u128 {
|
||||
((hi as u128) << 64) | (lo as u128)
|
||||
|
|
|
@ -1174,7 +1174,25 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
|||
ty::TyFloat(f) => {
|
||||
// ordered arithmetic reductions take an accumulator
|
||||
let acc = if $ordered {
|
||||
args[1].immediate()
|
||||
let acc = args[1].immediate();
|
||||
// FIXME: https://bugs.llvm.org/show_bug.cgi?id=36734
|
||||
// * if the accumulator of the fadd isn't 0, incorrect
|
||||
// code is generated
|
||||
// * if the accumulator of the fmul isn't 1, incorrect
|
||||
// code is generated
|
||||
match const_get_real(acc) {
|
||||
None => return_error!("accumulator of {} is not a constant", $name),
|
||||
Some((v, loses_info)) => {
|
||||
if $name.contains("mul") && v != 1.0_f64 {
|
||||
return_error!("accumulator of {} is not 1.0", $name);
|
||||
} else if $name.contains("add") && v != 0.0_f64 {
|
||||
return_error!("accumulator of {} is not 0.0", $name);
|
||||
} else if loses_info {
|
||||
return_error!("accumulator of {} loses information", $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
acc
|
||||
} else {
|
||||
// unordered arithmetic reductions do not:
|
||||
match f.bit_width() {
|
||||
|
@ -1248,6 +1266,14 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
|
|||
in_elem, in_ty, ret_ty);
|
||||
args[0].immediate()
|
||||
} else {
|
||||
match in_elem.sty {
|
||||
ty::TyInt(_) | ty::TyUint(_) => {},
|
||||
_ => {
|
||||
return_error!("unsupported {} from `{}` with element `{}` to `{}`",
|
||||
$name, in_ty, in_elem, ret_ty)
|
||||
}
|
||||
}
|
||||
|
||||
// boolean reductions operate on vectors of i1s:
|
||||
let i1 = Type::i1(bx.cx);
|
||||
let i1xn = Type::vector(&i1, in_len as u64);
|
||||
|
|
76
src/test/compile-fail/simd-intrinsic-generic-reduction.rs
Normal file
76
src/test/compile-fail/simd-intrinsic-generic-reduction.rs
Normal file
|
@ -0,0 +1,76 @@
|
|||
// Copyright 2015 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, platform_intrinsics)]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
|
||||
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
fn simd_reduce_add_ordered<T, U>(x: T, y: U) -> U;
|
||||
fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
|
||||
fn simd_reduce_and<T, U>(x: T) -> U;
|
||||
fn simd_reduce_or<T, U>(x: T) -> U;
|
||||
fn simd_reduce_xor<T, U>(x: T) -> U;
|
||||
fn simd_reduce_all<T>(x: T) -> bool;
|
||||
fn simd_reduce_any<T>(x: T) -> bool;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = u32x4(0, 0, 0, 0);
|
||||
let z = f32x4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
unsafe {
|
||||
simd_reduce_add_ordered(z, 0_f32);
|
||||
simd_reduce_mul_ordered(z, 1_f32);
|
||||
|
||||
simd_reduce_add_ordered(z, 2_f32);
|
||||
//~^ ERROR accumulator of simd_reduce_add_ordered is not 0.0
|
||||
simd_reduce_mul_ordered(z, 3_f32);
|
||||
//~^ ERROR accumulator of simd_reduce_mul_ordered is not 1.0
|
||||
|
||||
let _: f32 = simd_reduce_and(x);
|
||||
//~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32`
|
||||
let _: f32 = simd_reduce_or(x);
|
||||
//~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32`
|
||||
let _: f32 = simd_reduce_xor(x);
|
||||
//~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32`
|
||||
|
||||
let _: f32 = simd_reduce_and(z);
|
||||
//~^ ERROR unsupported simd_reduce_and from `f32x4` with element `f32` to `f32`
|
||||
let _: f32 = simd_reduce_or(z);
|
||||
//~^ ERROR unsupported simd_reduce_or from `f32x4` with element `f32` to `f32`
|
||||
let _: f32 = simd_reduce_xor(z);
|
||||
//~^ ERROR unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32`
|
||||
|
||||
let _: bool = simd_reduce_all(z);
|
||||
//~^ ERROR unsupported simd_reduce_all from `f32x4` with element `f32` to `bool`
|
||||
let _: bool = simd_reduce_any(z);
|
||||
//~^ ERROR unsupported simd_reduce_any from `f32x4` with element `f32` to `bool`
|
||||
|
||||
foo(0_f32);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
unsafe fn foo(x: f32) {
|
||||
let z = f32x4(0.0, 0.0, 0.0, 0.0);
|
||||
simd_reduce_add_ordered(z, x);
|
||||
//~^ ERROR accumulator of simd_reduce_add_ordered is not a constant
|
||||
simd_reduce_mul_ordered(z, x);
|
||||
//~^ ERROR accumulator of simd_reduce_mul_ordered is not a constant
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue