Enforce encodings for instructions with side effects.
We allow ghost instructions to exist if they have no side effects. Instructions that affect control flow or that have other side effects must be encoded. Teach the IL verifier to enforce this. Once any instruction has an encoding, all instructions with side effects must have an encoding.
This commit is contained in:
@@ -59,7 +59,7 @@ ebb0(v0: i32):
|
|||||||
brnz v0, ebb1(v0)
|
brnz v0, ebb1(v0)
|
||||||
v1 = iadd_imm v0, 7
|
v1 = iadd_imm v0, 7
|
||||||
; v1 and v0 interfere here:
|
; v1 and v0 interfere here:
|
||||||
trapnz v0
|
v2 = iadd_imm v0, 8
|
||||||
; check: $(cp1=$V) = copy $v1
|
; check: $(cp1=$V) = copy $v1
|
||||||
; not: copy
|
; not: copy
|
||||||
; check: jump $ebb1($cp1)
|
; check: jump $ebb1($cp1)
|
||||||
|
|||||||
@@ -666,30 +666,70 @@ impl<'a> Verifier<'a> {
|
|||||||
/// If the verifier has been set up with an ISA, make sure that the recorded encoding for the
|
/// If the verifier has been set up with an ISA, make sure that the recorded encoding for the
|
||||||
/// instruction (if any) matches how the ISA would encode it.
|
/// instruction (if any) matches how the ISA would encode it.
|
||||||
fn verify_encoding(&self, inst: Inst) -> Result {
|
fn verify_encoding(&self, inst: Inst) -> Result {
|
||||||
if let Some(isa) = self.isa {
|
// When the encodings table is empty, we don't require any instructions to be encoded.
|
||||||
let encoding = self.func.encodings.get_or_default(inst);
|
//
|
||||||
if encoding.is_legal() {
|
// Once some instructions are encoded, we require all side-effecting instructions to have a
|
||||||
let verify_encoding =
|
// legal encoding.
|
||||||
isa.encode(&self.func.dfg,
|
if self.func.encodings.is_empty() {
|
||||||
&self.func.dfg[inst],
|
return Ok(());
|
||||||
self.func.dfg.ctrl_typevar(inst));
|
}
|
||||||
match verify_encoding {
|
|
||||||
Ok(verify_encoding) => {
|
let isa = match self.isa {
|
||||||
if verify_encoding != encoding {
|
Some(isa) => isa,
|
||||||
return err!(inst,
|
None => return Ok(()),
|
||||||
"Instruction re-encoding {} doesn't match {}",
|
};
|
||||||
isa.encoding_info().display(verify_encoding),
|
|
||||||
isa.encoding_info().display(encoding));
|
let encoding = self.func.encodings.get_or_default(inst);
|
||||||
}
|
if encoding.is_legal() {
|
||||||
}
|
let verify_encoding =
|
||||||
Err(e) => {
|
isa.encode(&self.func.dfg,
|
||||||
|
&self.func.dfg[inst],
|
||||||
|
self.func.dfg.ctrl_typevar(inst));
|
||||||
|
match verify_encoding {
|
||||||
|
Ok(verify_encoding) => {
|
||||||
|
if verify_encoding != encoding {
|
||||||
return err!(inst,
|
return err!(inst,
|
||||||
"Instruction failed to re-encode {}: {:?}",
|
"Instruction re-encoding {} doesn't match {}",
|
||||||
isa.encoding_info().display(encoding),
|
isa.encoding_info().display(verify_encoding),
|
||||||
e)
|
isa.encoding_info().display(encoding));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return err!(inst,
|
||||||
|
"Instruction failed to re-encode {}: {:?}",
|
||||||
|
isa.encoding_info().display(encoding),
|
||||||
|
e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instruction is not encoded, so it is a ghost instruction.
|
||||||
|
// Instructions with side effects are not allowed to be ghost instructions.
|
||||||
|
let opcode = self.func.dfg[inst].opcode();
|
||||||
|
|
||||||
|
if opcode.is_branch() {
|
||||||
|
return err!(inst, "Branch must have an encoding");
|
||||||
|
}
|
||||||
|
|
||||||
|
if opcode.is_call() {
|
||||||
|
return err!(inst, "Call must have an encoding");
|
||||||
|
}
|
||||||
|
|
||||||
|
if opcode.is_return() {
|
||||||
|
return err!(inst, "Return must have an encoding");
|
||||||
|
}
|
||||||
|
|
||||||
|
if opcode.can_store() {
|
||||||
|
return err!(inst, "Store must have an encoding");
|
||||||
|
}
|
||||||
|
|
||||||
|
if opcode.can_trap() {
|
||||||
|
return err!(inst, "Trapping instruction must have an encoding");
|
||||||
|
}
|
||||||
|
|
||||||
|
if opcode.other_side_effects() {
|
||||||
|
return err!(inst, "Instruction with side effects must have an encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user