1
Fork 0

add compile fail tests

This commit is contained in:
gnzlbg 2018-03-15 16:36:02 +01:00
parent 8478fa2007
commit 4fe6acf972
4 changed files with 125 additions and 1 deletions

View file

@ -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;

View file

@ -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)

View file

@ -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);

View 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
}