Properly infer result type for single-result instructions.
Polymorphic single-result instructions don't always return the controlling type variable as their first result. They may use a derived type variable, as for example icmp does.
This commit is contained in:
@@ -474,7 +474,21 @@ def gen_inst_builder(inst, fmt):
|
|||||||
fmt.line(
|
fmt.line(
|
||||||
'let ctrl_typevar = self.data_flow_graph().value_type({});'
|
'let ctrl_typevar = self.data_flow_graph().value_type({});'
|
||||||
.format(inst.ins[inst.format.typevar_operand].name))
|
.format(inst.ins[inst.format.typevar_operand].name))
|
||||||
|
if inst.format.multiple_results:
|
||||||
|
# The format constructor will resolve the result types from the
|
||||||
|
# type var.
|
||||||
args.append('ctrl_typevar')
|
args.append('ctrl_typevar')
|
||||||
|
elif inst.outs[inst.value_results[0]].typ == inst.ctrl_typevar:
|
||||||
|
# The format constructor expects a simple result type.
|
||||||
|
# No type transformation needed from the controlling type
|
||||||
|
# variable.
|
||||||
|
args.append('ctrl_typevar')
|
||||||
|
else:
|
||||||
|
# The format constructor expects a simple result type.
|
||||||
|
# TODO: This formula could be resolved ahead of time.
|
||||||
|
args.append(
|
||||||
|
'Opcode::{}.constraints().result_type(0, ctrl_typevar)'
|
||||||
|
.format(inst.camel_name))
|
||||||
else:
|
else:
|
||||||
# This non-polymorphic instruction has a fixed result type.
|
# This non-polymorphic instruction has a fixed result type.
|
||||||
args.append(
|
args.append(
|
||||||
|
|||||||
@@ -180,3 +180,32 @@ impl<'f> InstBuilderBase<'f> for ReplaceBuilder<'f> {
|
|||||||
(self.inst, self.dfg)
|
(self.inst, self.dfg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use ir::{Function, Cursor, InstBuilder};
|
||||||
|
use ir::types::*;
|
||||||
|
use ir::condcodes::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn types() {
|
||||||
|
let mut func = Function::new();
|
||||||
|
let dfg = &mut func.dfg;
|
||||||
|
let ebb0 = dfg.make_ebb();
|
||||||
|
let arg0 = dfg.append_ebb_arg(ebb0, I32);
|
||||||
|
let pos = &mut Cursor::new(&mut func.layout);
|
||||||
|
pos.insert_ebb(ebb0);
|
||||||
|
|
||||||
|
// Explicit types.
|
||||||
|
let v0 = dfg.ins(pos).iconst(I32, 3);
|
||||||
|
assert_eq!(dfg.value_type(v0), I32);
|
||||||
|
|
||||||
|
// Inferred from inputs.
|
||||||
|
let v1 = dfg.ins(pos).iadd(arg0, v0);
|
||||||
|
assert_eq!(dfg.value_type(v1), I32);
|
||||||
|
|
||||||
|
// Formula.
|
||||||
|
let cmp = dfg.ins(pos).icmp(IntCC::Equal, arg0, v0);
|
||||||
|
assert_eq!(dfg.value_type(cmp), B1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user