Make the verifier accept any of the legal encodings of an instruction

This commit is contained in:
Angus Holder
2017-09-18 20:41:01 +01:00
committed by Jakob Stoklund Olesen
parent da4cde8117
commit d2273c73ea
2 changed files with 38 additions and 20 deletions

View File

@@ -16,6 +16,6 @@ function %RV32I(i32 link [%x1]) -> i32 link [%x1] {
ebb0(v9999: i32): ebb0(v9999: i32):
v1 = iconst.i32 1 v1 = iconst.i32 1
v2 = iconst.i32 2 v2 = iconst.i32 2
[R#0,-] v3 = iadd v1, v2 ; error: Instruction re-encoding [R#0,-] v3 = iadd v1, v2 ; error: Instruction encoding R#00 doesn't match any possibilities
return v9999 return v9999
} }

View File

@@ -68,7 +68,7 @@ use ir::{types, Function, ValueDef, Ebb, Inst, SigRef, FuncRef, ValueList, JumpT
use isa::TargetIsa; use isa::TargetIsa;
use settings::{Flags, FlagsOrIsa}; use settings::{Flags, FlagsOrIsa};
use std::error as std_error; use std::error as std_error;
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter, Write};
use std::result; use std::result;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::cmp::Ordering; use std::cmp::Ordering;
@@ -883,29 +883,47 @@ impl<'a> Verifier<'a> {
let encoding = self.func.encodings[inst]; let encoding = self.func.encodings[inst];
if encoding.is_legal() { if encoding.is_legal() {
let verify_encoding = isa.encode( let mut encodings = isa.legal_encodings(
&self.func.dfg, &self.func.dfg,
&self.func.dfg[inst], &self.func.dfg[inst],
self.func.dfg.ctrl_typevar(inst), self.func.dfg.ctrl_typevar(inst),
); ).peekable();
match verify_encoding {
Ok(verify_encoding) => { if encodings.peek().is_none() {
if verify_encoding != encoding { return err!(
return err!( inst,
inst, "Instruction failed to re-encode {}",
"Instruction re-encoding {} doesn't match {}", isa.encoding_info().display(encoding)
isa.encoding_info().display(verify_encoding), );
isa.encoding_info().display(encoding) }
);
let has_valid_encoding = encodings
.position(|possible_enc| encoding == possible_enc)
.is_some();
if !has_valid_encoding {
let mut possible_encodings = String::new();
for enc in isa.legal_encodings(
&self.func.dfg,
&self.func.dfg[inst],
self.func.dfg.ctrl_typevar(inst),
)
{
if possible_encodings.len() != 0 {
possible_encodings.push_str(", ");
} }
possible_encodings
.write_fmt(format_args!("{}", isa.encoding_info().display(enc)))
.unwrap();
} }
Err(_) => {
return err!( return err!(
inst, inst,
"Instruction failed to re-encode {}", "Instruction encoding {} doesn't match any possibilities: [{}]",
isa.encoding_info().display(encoding) isa.encoding_info().display(encoding),
) possible_encodings
} );
} }
return Ok(()); return Ok(());
} }