Legalize i64.const by breaking it into two i32.const, on 32-bits platforms;

This commit is contained in:
Benjamin Bouvier
2019-08-30 13:01:03 +02:00
parent 6f1ed94e82
commit 3aa76b558c
5 changed files with 62 additions and 9 deletions

View File

@@ -188,6 +188,10 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro
narrow.custom_legalize(load, "narrow_load");
narrow.custom_legalize(store, "narrow_store");
// iconst.i64 can't be legalized in the meta langage (because integer literals can't be
// embedded as part of arguments), so use a custom legalization for now.
narrow.custom_legalize(iconst, "narrow_iconst");
narrow.legalize(
def!(a = iadd(x, y)),
vec![

View File

@@ -16,7 +16,7 @@
use crate::bitset::BitSet;
use crate::cursor::{Cursor, FuncCursor};
use crate::flowgraph::ControlFlowGraph;
use crate::ir::types::I32;
use crate::ir::types::{I32, I64};
use crate::ir::{self, InstBuilder, MemFlags};
use crate::isa::TargetIsa;
use crate::predicates;
@@ -633,3 +633,35 @@ fn narrow_store(
);
pos.remove_inst();
}
/// Expands an illegal iconst value by splitting it into two.
fn narrow_iconst(
inst: ir::Inst,
func: &mut ir::Function,
_cfg: &mut ControlFlowGraph,
isa: &dyn TargetIsa,
) {
let imm: i64 = if let ir::InstructionData::UnaryImm {
opcode: ir::Opcode::Iconst,
imm,
} = &func.dfg[inst]
{
(*imm).into()
} else {
panic!("unexpected instruction in narrow_iconst");
};
let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
let ty = pos.func.dfg.ctrl_typevar(inst);
if isa.pointer_bits() == 32 && ty == I64 {
let low = pos.ins().iconst(I32, imm & 0xffffffff);
let high = pos.ins().iconst(I32, imm >> 32);
// The instruction has as many results as iconcat, so no need to replace them.
pos.func.dfg.replace(inst).iconcat(low, high);
return;
}
unimplemented!("missing encoding or legalization for iconst.{:?}", ty);
}

View File

@@ -62,14 +62,6 @@ ebb0:
return v1
}
function %f64const() -> f64 {
ebb0:
v1 = f64const 0x1.0p1
; check: $(tmp=$V) = iconst.i64
; check: v1 = bitcast.f64 $tmp
return v1
}
function %select_f64(f64, f64, i32) -> f64 {
ebb0(v0: f64, v1: f64, v2: i32):
v3 = select v2, v0, v1

View File

@@ -0,0 +1,13 @@
; Test the legalization of f64const.
test legalizer
target x86_64
; regex: V=v\d+
function %f64const() -> f64 {
ebb0:
v1 = f64const 0x1.0p1
; check: $(tmp=$V) = iconst.i64
; check: v1 = bitcast.f64 $tmp
return v1
}

View File

@@ -0,0 +1,12 @@
test legalizer
target i686
function %foo() -> i64 {
ebb0:
v1 = iconst.i64 0x6400000042
return v1
}
; check: v2 = iconst.i32 66
; check: v3 = iconst.i32 100
; check: v1 = iconcat v2, v3