Teach simple_gvn that iconst.i32 is not congruent to iconst.i64.
This commit is contained in:
@@ -9,3 +9,17 @@ ebb0(v0: i32):
|
|||||||
; check: regmove v0, %10 -> %20
|
; check: regmove v0, %10 -> %20
|
||||||
return v0
|
return v0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function %differing_typevars() -> i64 {
|
||||||
|
ebb0:
|
||||||
|
v0 = iconst.i32 7
|
||||||
|
v1 = iconst.i64 7
|
||||||
|
v2 = iconst.i64 8
|
||||||
|
; check: v0 = iconst.i32 7
|
||||||
|
; check: v1 = iconst.i64 7
|
||||||
|
; check: v2 = iconst.i64 8
|
||||||
|
v3 = uextend.i64 v0
|
||||||
|
v4 = iadd v2, v1
|
||||||
|
v5 = iadd v4, v3
|
||||||
|
return v5
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ use std::fmt::{self, Display, Debug, Formatter};
|
|||||||
///
|
///
|
||||||
/// SIMD vector types have power-of-two lanes, up to 256. Lanes can be any int/float/bool type.
|
/// SIMD vector types have power-of-two lanes, up to 256. Lanes can be any int/float/bool type.
|
||||||
///
|
///
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Type(u8);
|
pub struct Type(u8);
|
||||||
|
|
||||||
/// No type. Used for functions without a return value. Can't be loaded or stored. Can't be part of
|
/// No type. Used for functions without a return value. Can't be loaded or stored. Can't be part of
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use flowgraph::ControlFlowGraph;
|
use flowgraph::ControlFlowGraph;
|
||||||
use dominator_tree::DominatorTree;
|
use dominator_tree::DominatorTree;
|
||||||
use ir::{Cursor, CursorBase, InstructionData, Function, Inst, Opcode};
|
use ir::{Cursor, CursorBase, InstructionData, Function, Inst, Opcode, Type};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
/// Test whether the given opcode is unsafe to even consider for GVN.
|
/// Test whether the given opcode is unsafe to even consider for GVN.
|
||||||
@@ -14,7 +14,7 @@ fn trivially_unsafe_for_gvn(opcode: Opcode) -> bool {
|
|||||||
/// Perform simple GVN on `func`.
|
/// Perform simple GVN on `func`.
|
||||||
///
|
///
|
||||||
pub fn do_simple_gvn(func: &mut Function, cfg: &mut ControlFlowGraph) {
|
pub fn do_simple_gvn(func: &mut Function, cfg: &mut ControlFlowGraph) {
|
||||||
let mut visible_values: HashMap<InstructionData, Inst> = HashMap::new();
|
let mut visible_values: HashMap<(InstructionData, Type), Inst> = HashMap::new();
|
||||||
|
|
||||||
let domtree = DominatorTree::with_function(func, cfg);
|
let domtree = DominatorTree::with_function(func, cfg);
|
||||||
|
|
||||||
@@ -26,6 +26,7 @@ pub fn do_simple_gvn(func: &mut Function, cfg: &mut ControlFlowGraph) {
|
|||||||
|
|
||||||
while let Some(inst) = pos.next_inst() {
|
while let Some(inst) = pos.next_inst() {
|
||||||
let opcode = func.dfg[inst].opcode();
|
let opcode = func.dfg[inst].opcode();
|
||||||
|
let ctrl_typevar = func.dfg.ctrl_typevar(inst);
|
||||||
|
|
||||||
// Resolve aliases, particularly aliases we created earlier.
|
// Resolve aliases, particularly aliases we created earlier.
|
||||||
func.dfg.resolve_aliases_in_arguments(inst);
|
func.dfg.resolve_aliases_in_arguments(inst);
|
||||||
@@ -42,7 +43,7 @@ pub fn do_simple_gvn(func: &mut Function, cfg: &mut ControlFlowGraph) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let key = func.dfg[inst].clone();
|
let key = (func.dfg[inst].clone(), ctrl_typevar);
|
||||||
let entry = visible_values.entry(key);
|
let entry = visible_values.entry(key);
|
||||||
use std::collections::hash_map::Entry::*;
|
use std::collections::hash_map::Entry::*;
|
||||||
match entry {
|
match entry {
|
||||||
|
|||||||
Reference in New Issue
Block a user