Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
18afb26
Add print and assertion options to the run tests.
krk Nov 14, 2019
b5cc84a
Revert verifier errors format string.
krk Nov 19, 2019
892a6b0
Implement FromStr for Operator.
krk Nov 21, 2019
5e78a80
Add function name to errors.
krk Nov 21, 2019
0e1b3de
Remove some return keywords.
krk Nov 21, 2019
ba49813
Refactor print_only parameter of check into a new print function.
krk Nov 21, 2019
62084b5
Add Value enum to represent parsed values in function_runner.
krk Nov 21, 2019
3405df7
Comment test failing in Windows, issue at #1279.
krk Dec 6, 2019
e7d02ea
Fix commented run command in test.
krk Dec 7, 2019
51c2e53
Substitute single line macro "consume".
krk Dec 15, 2019
0c9942c
Remove boolean_to_vec function and simplify its only callsite.
krk Dec 15, 2019
3a57022
Use ConstantData less in parsing test options.
krk Dec 15, 2019
6875284
Remove unnecessary type condition in FunctionRunner.invoke.
krk Dec 15, 2019
b076b68
Do not compile method that cannot be run in test.
krk Dec 15, 2019
02d887c
Fix return value count error message.
krk Dec 15, 2019
350c755
Simplify return type check for two I64s.
krk Dec 15, 2019
d772f3e
Remove unnecessary trivial_numeric_casts attribute.
krk Dec 18, 2019
7dc5f43
Merge use declarations.
krk Dec 18, 2019
7ec2f56
Remove overflowing_shl.
krk Dec 18, 2019
059ffcc
Mark invoke function as unsafe.
krk Dec 18, 2019
32d94ec
Remove unnecessary return.
krk Dec 18, 2019
bd443f8
Add descriptive panic message.
krk Dec 18, 2019
0be5b8d
Reword error message.
krk Dec 18, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
430 changes: 399 additions & 31 deletions cranelift-filetests/src/function_runner.rs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cranelift-filetests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
)]

pub use crate::function_runner::FunctionRunner;
pub use crate::function_runner::FunctionRunnerBuilder;
use crate::runner::TestRunner;
use cranelift_codegen::timing;
use cranelift_reader::TestCommand;
Expand Down
8 changes: 5 additions & 3 deletions cranelift-filetests/src/test_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! The `run` test command compiles each function on the host machine and executes it

use crate::function_runner::FunctionRunner;
use crate::function_runner::FunctionRunnerBuilder;
use crate::subtest::{Context, SubTest, SubtestResult};
use cranelift_codegen;
use cranelift_codegen::ir;
Expand Down Expand Up @@ -36,8 +36,10 @@ impl SubTest for TestRun {
fn run(&self, func: Cow<ir::Function>, context: &Context) -> SubtestResult<()> {
for comment in context.details.comments.iter() {
if comment.text.contains("run") {
let runner =
FunctionRunner::with_host_isa(func.clone().into_owned(), context.flags.clone());
let runner = FunctionRunnerBuilder::new(func.clone().into_owned())
.with_host_isa(context.flags.clone())
.with_action_text(comment.text)
.finish();
runner.run()?
}
}
Expand Down
2 changes: 1 addition & 1 deletion cranelift-reader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

pub use crate::error::{Location, ParseError, ParseResult};
pub use crate::isaspec::{parse_options, IsaSpec};
pub use crate::parser::{parse_functions, parse_test, ParseOptions};
pub use crate::parser::{parse_functions, parse_test, ParseOptions, Parser};
pub use crate::sourcemap::SourceMap;
pub use crate::testcommand::{TestCommand, TestOption};
pub use crate::testfile::{Comment, Details, Feature, TestFile};
Expand Down
29 changes: 15 additions & 14 deletions cranelift-reader/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ pub fn parse_test<'a>(text: &'a str, options: ParseOptions<'a>) -> ParseResult<T
})
}

/// Parser for .clif files.
pub struct Parser<'a> {
lex: Lexer<'a>,

Expand Down Expand Up @@ -609,8 +610,8 @@ impl<'a> Parser<'a> {
}
}

// Match and consume either a hexadecimal Uimm128 immediate (e.g. 0x000102...) or its literal list form (e.g. [0 1 2...])
fn match_constant_data(&mut self, controlling_type: Type) -> ParseResult<ConstantData> {
/// Match and consume either a hexadecimal Uimm128 immediate (e.g. 0x000102...) or its literal list form (e.g. [0 1 2...])
pub fn match_constant_data(&mut self, controlling_type: Type) -> ParseResult<ConstantData> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that moving that parsing code into this cranelift-reader crate would let us avoid making all these methods public as well.

let expected_size = controlling_type.bytes() as usize;
let constant_data = if self.optional(Token::LBracket) {
// parse using a list of values, e.g. vconst.i32x4 [0 1 2 3]
Expand All @@ -634,8 +635,8 @@ impl<'a> Parser<'a> {
}
}

// Match and consume a Uimm64 immediate.
fn match_uimm64(&mut self, err_msg: &str) -> ParseResult<Uimm64> {
/// Match and consume a Uimm64 immediate.
pub fn match_uimm64(&mut self, err_msg: &str) -> ParseResult<Uimm64> {
if let Some(Token::Integer(text)) = self.token() {
self.consume();
// Lexer just gives us raw text that looks like an integer.
Expand All @@ -647,8 +648,8 @@ impl<'a> Parser<'a> {
}
}

// Match and consume a Uimm32 immediate.
fn match_uimm32(&mut self, err_msg: &str) -> ParseResult<Uimm32> {
/// Match and consume a Uimm32 immediate.
pub fn match_uimm32(&mut self, err_msg: &str) -> ParseResult<Uimm32> {
if let Some(Token::Integer(text)) = self.token() {
self.consume();
// Lexer just gives us raw text that looks like an integer.
Expand All @@ -659,9 +660,9 @@ impl<'a> Parser<'a> {
}
}

// Match and consume a u8 immediate.
// This is used for lane numbers in SIMD vectors.
fn match_uimm8(&mut self, err_msg: &str) -> ParseResult<u8> {
/// Match and consume a u8 immediate.
pub fn match_uimm8(&mut self, err_msg: &str) -> ParseResult<u8> {
if let Some(Token::Integer(text)) = self.token() {
self.consume();
// Lexer just gives us raw text that looks like an integer.
Expand Down Expand Up @@ -740,8 +741,8 @@ impl<'a> Parser<'a> {
Ok(Imm64::new(0))
}

// Match and consume an Ieee32 immediate.
fn match_ieee32(&mut self, err_msg: &str) -> ParseResult<Ieee32> {
/// Match and consume an Ieee32 immediate.
pub fn match_ieee32(&mut self, err_msg: &str) -> ParseResult<Ieee32> {
if let Some(Token::Float(text)) = self.token() {
self.consume();
// Lexer just gives us raw text that looks like a float.
Expand All @@ -752,8 +753,8 @@ impl<'a> Parser<'a> {
}
}

// Match and consume an Ieee64 immediate.
fn match_ieee64(&mut self, err_msg: &str) -> ParseResult<Ieee64> {
/// Match and consume an Ieee64 immediate.
pub fn match_ieee64(&mut self, err_msg: &str) -> ParseResult<Ieee64> {
if let Some(Token::Float(text)) = self.token() {
self.consume();
// Lexer just gives us raw text that looks like a float.
Expand All @@ -764,8 +765,8 @@ impl<'a> Parser<'a> {
}
}

// Match and consume a boolean immediate.
fn match_bool(&mut self, err_msg: &str) -> ParseResult<bool> {
/// Match and consume a boolean immediate.
pub fn match_bool(&mut self, err_msg: &str) -> ParseResult<bool> {
if let Some(Token::Identifier(text)) = self.token() {
self.consume();
match text {
Expand Down
28 changes: 28 additions & 0 deletions docs/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -397,3 +397,31 @@ Example::
return v0
}
; run

To print the return value of the function and fail, add a ``; run: print`` directive
after each function. This is for debugging only.

Example::

test run

function %trivial_test() -> i16 {
ebb0:
v0 = iconst.i16 42
return v0
}
; run: print

To assert on the return value of the function, add a ``; run: %fn() <op> <expected>`` directive
after a function. Equality "==" and inequality "!=" operators are supported.

Example::

test run

function %trivial_test() -> i16 {
ebb0:
v0 = iconst.i16 42
return v0
}
; run: %fn() == 0x2a
18 changes: 18 additions & 0 deletions filetests/function_runner/basic.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
test run
target x86_64

function %test_assert_equal() -> i64 {
ebb0:
v0 = iconst.i64 42
return v0
}

; run: %fn() == 0x2a

function %test_assert_inequal() -> i64 {
ebb0:
v0 = iconst.i64 0
return v0
}

; run: %fn() != 0x2a
89 changes: 89 additions & 0 deletions filetests/function_runner/types.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
test run
target x86_64

function %test_i8() -> i8 {
ebb0:
v0 = iconst.i8 42
return v0
}
; run: %fn() == 0x2a

function %test_i16() -> i16 {
ebb0:
v0 = iconst.i16 42
return v0
}
; run: %fn() == 0x2a

function %test_i32() -> i32 {
ebb0:
v0 = iconst.i32 42
return v0
}
; run: %fn() == 0x2a

function %test_i64() -> i64 {
ebb0:
v0 = iconst.i64 0x4242_3535_1234_5678
return v0
}
; run: %fn() == 0x4242_3535_1234_5678

; Multi-value return does not work on Windows ABI, for details see #1279.
; function %test_i128() -> i128 {
; ebb0:
; v0 = iconst.i64 0x4242_3535_1234_5678
; v1 = iconst.i64 0xabcd_ef01_beef_b411
; v2 = iconcat v0, v1
; return v2
; }
; ; r-u-n: %fn() == 0x4242_3535_1234_5678_abcd_ef01_beef_b411

function %test_b1() -> b1 {
ebb0:
v0 = bconst.b1 true
return v0
}
; run: %fn() == true

function %test_b8() -> b8 {
ebb0:
v0 = bconst.b8 true
return v0
}
; run: %fn() == true

function %test_b16() -> b16 {
ebb0:
v0 = bconst.b16 true
return v0
}
; run: %fn() == true

function %test_b32() -> b32 {
ebb0:
v0 = bconst.b32 true
return v0
}
; run: %fn() == true

function %test_b64() -> b64 {
ebb0:
v0 = bconst.b64 true
return v0
}
; run: %fn() == true

function %test_f32() -> f32 {
ebb0:
v0 = f32const 0x1.23
return v0
}
; run: %fn() == 0x1.23

function %test_f64() -> f64 {
ebb0:
v0 = f64const 0x1000.0001
return v0
}
; run: %fn() == 0x1000.0001
11 changes: 8 additions & 3 deletions src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::utils::read_to_string;
use cranelift_codegen::isa::{CallConv, TargetIsa};
use cranelift_filetests::FunctionRunner;
use cranelift_filetests::FunctionRunnerBuilder;
use cranelift_native::builder as host_isa_builder;
use cranelift_reader::{parse_test, Details, IsaSpec, ParseOptions};
use std::path::PathBuf;
Expand Down Expand Up @@ -81,9 +81,14 @@ fn run_file_contents(file_contents: String) -> Result<(), String> {
};
let test_file = parse_test(&file_contents, options).map_err(|e| e.to_string())?;
for (func, Details { comments, .. }) in test_file.functions {
if comments.iter().any(|c| c.text.contains("run")) {
let comment = comments.iter().find(|c| c.text.contains("run"));
if let Some(c) = comment {
let isa = create_target_isa(&test_file.isa_spec)?;
FunctionRunner::new(func, isa).run()?
let runner = FunctionRunnerBuilder::new(func)
.with_isa(isa)
.with_action_text(c.text)
.finish();
runner.run()?
}
}
Ok(())
Expand Down