diff --git a/cranelift/codegen/meta/src/shared/legalize.rs b/cranelift/codegen/meta/src/shared/legalize.rs index 9588272709..1c2c510460 100644 --- a/cranelift/codegen/meta/src/shared/legalize.rs +++ b/cranelift/codegen/meta/src/shared/legalize.rs @@ -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![ diff --git a/cranelift/codegen/src/legalizer/mod.rs b/cranelift/codegen/src/legalizer/mod.rs index 0f24689d8c..2fd353c7b9 100644 --- a/cranelift/codegen/src/legalizer/mod.rs +++ b/cranelift/codegen/src/legalizer/mod.rs @@ -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); +} diff --git a/cranelift/filetests/filetests/isa/x86/legalize-custom.clif b/cranelift/filetests/filetests/isa/x86/legalize-custom.clif index 747f4e819b..2657bfd497 100644 --- a/cranelift/filetests/filetests/isa/x86/legalize-custom.clif +++ b/cranelift/filetests/filetests/isa/x86/legalize-custom.clif @@ -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 diff --git a/cranelift/filetests/filetests/isa/x86/legalize-f64const-x64.clif b/cranelift/filetests/filetests/isa/x86/legalize-f64const-x64.clif new file mode 100644 index 0000000000..addafe90a3 --- /dev/null +++ b/cranelift/filetests/filetests/isa/x86/legalize-f64const-x64.clif @@ -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 +} diff --git a/cranelift/filetests/filetests/legalizer/iconst-i64.clif b/cranelift/filetests/filetests/legalizer/iconst-i64.clif new file mode 100644 index 0000000000..a3c9168416 --- /dev/null +++ b/cranelift/filetests/filetests/legalizer/iconst-i64.clif @@ -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