Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port vconst to ISLE (AArch64) #4750

Merged
merged 2 commits into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cranelift/codegen/src/isa/aarch64/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -2428,6 +2428,11 @@
(if-let addr_reg (amode_is_reg addr))
addr_reg)

;; Lower a constant f64.
(decl constant_f64 (u64) Reg)
;; TODO: Port lower_constant_f64() to ISLE.
(extern constructor constant_f64 constant_f64)

;; Lower a constant f128.
(decl constant_f128 (u128) Reg)
;; TODO: Port lower_constant_f128() to ISLE.
Expand Down
9 changes: 9 additions & 0 deletions cranelift/codegen/src/isa/aarch64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -1628,6 +1628,15 @@
(rule (lower (resumable_trap trap_code))
(side_effect (udf trap_code)))

;;;; Rules for `vconst` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type (ty_vec128 _) (vconst (u128_from_constant x))))
(constant_f128 x))

(rule (lower (has_type ty (vconst (u64_from_constant x))))
(if (ty_vec64 ty))
(constant_f64 x))

;;;; Rules for `splat` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type ty (splat x @ (value_type in_ty))))
Expand Down
8 changes: 0 additions & 8 deletions cranelift/codegen/src/isa/aarch64/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
//! - Floating-point immediates (FIMM instruction).

use super::lower_inst;
use crate::data_value::DataValue;
use crate::ir::condcodes::{FloatCC, IntCC};
use crate::ir::types::*;
use crate::ir::Inst as IRInst;
Expand Down Expand Up @@ -94,13 +93,6 @@ pub(crate) fn input_to_shiftimm(
input_to_const(ctx, input).and_then(ShiftOpShiftImm::maybe_from_shift)
}

pub(crate) fn const_param_to_u128(ctx: &mut Lower<Inst>, inst: IRInst) -> Option<u128> {
match ctx.get_immediate(inst) {
Some(DataValue::V128(bytes)) => Some(u128::from_le_bytes(bytes)),
_ => None,
}
}

/// How to handle narrow values loaded into registers; see note on `narrow_mode`
/// parameter to `put_input_in_*` below.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
Expand Down
14 changes: 11 additions & 3 deletions cranelift/codegen/src/isa/aarch64/lower/isle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ pub mod generated_code;

// Types that the generated ISLE code uses via `use super::*`.
use super::{
insn_inputs, lower_constant_f128, writable_zero_reg, zero_reg, AMode, ASIMDFPModImm,
ASIMDMovModImm, BranchTarget, CallIndInfo, CallInfo, Cond, CondBrKind, ExtendOp, FPUOpRI,
FloatCC, Imm12, ImmLogic, ImmShift, Inst as MInst, IntCC, JTSequenceInfo, MachLabel,
insn_inputs, lower_constant_f128, lower_constant_f64, writable_zero_reg, zero_reg, AMode,
ASIMDFPModImm, ASIMDMovModImm, BranchTarget, CallIndInfo, CallInfo, Cond, CondBrKind, ExtendOp,
FPUOpRI, FloatCC, Imm12, ImmLogic, ImmShift, Inst as MInst, IntCC, JTSequenceInfo, MachLabel,
MoveWideConst, MoveWideOp, NarrowValueMode, Opcode, OperandSize, PairAMode, Reg, ScalarSize,
ShiftOpAndAmt, UImm5, VecMisc2, VectorSize, NZCV,
};
Expand Down Expand Up @@ -484,6 +484,14 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6>
address.is_reg()
}

fn constant_f64(&mut self, value: u64) -> Reg {
let rd = self.temp_writable_reg(I8X16);

lower_constant_f64(self.lower_ctx, rd, f64::from_bits(value));

rd.to_reg()
}

fn constant_f128(&mut self, value: u128) -> Reg {
let rd = self.temp_writable_reg(I8X16);

Expand Down
6 changes: 1 addition & 5 deletions cranelift/codegen/src/isa/aarch64/lower_inst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,11 +662,7 @@ pub(crate) fn lower_insn_to_regs(
panic!("Branch opcode reached non-branch lowering logic!");
}

Opcode::Vconst => {
let value = const_param_to_u128(ctx, insn).expect("Invalid immediate bytes");
let rd = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
lower_constant_f128(ctx, rd, value);
}
Opcode::Vconst => implemented_in_isle(ctx),

Opcode::RawBitcast => {
let rm = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None);
Expand Down
6 changes: 6 additions & 0 deletions cranelift/codegen/src/machinst/isle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,12 @@ macro_rules! isle_prelude_methods {
Some(u128::from_le_bytes(bytes.try_into().ok()?))
}

#[inline]
fn u64_from_constant(&mut self, constant: Constant) -> Option<u64> {
let bytes = self.lower_ctx.get_constant_data(constant).as_slice();
Some(u64::from_le_bytes(bytes.try_into().ok()?))
}

#[inline]
fn u128_from_constant(&mut self, constant: Constant) -> Option<u128> {
let bytes = self.lower_ctx.get_constant_data(constant).as_slice();
Expand Down
14 changes: 11 additions & 3 deletions cranelift/codegen/src/machinst/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1387,15 +1387,23 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
let inst_data = self.data(ir_inst);
match inst_data {
InstructionData::Shuffle { imm, .. } => {
let buffer = self.f.dfg.immediates.get(imm.clone()).unwrap().as_slice();
let value = DataValue::V128(buffer.try_into().expect("a 16-byte data buffer"));
let mask = self.f.dfg.immediates.get(imm.clone()).unwrap().as_slice();
let value = match mask.len() {
16 => DataValue::V128(mask.try_into().expect("a 16-byte vector mask")),
8 => DataValue::V64(mask.try_into().expect("an 8-byte vector mask")),
length => panic!("unexpected Shuffle mask length {}", length),
};
Some(value)
}
InstructionData::UnaryConst {
constant_handle, ..
} => {
let buffer = self.f.dfg.constants.get(constant_handle.clone()).as_slice();
let value = DataValue::V128(buffer.try_into().expect("a 16-byte data buffer"));
let value = match buffer.len() {
16 => DataValue::V128(buffer.try_into().expect("a 16-byte data buffer")),
8 => DataValue::V64(buffer.try_into().expect("an 8-byte data buffer")),
length => panic!("unexpected UnaryConst buffer length {}", length),
};
Some(value)
}
_ => inst_data.imm_value(),
Expand Down
5 changes: 5 additions & 0 deletions cranelift/codegen/src/prelude.isle
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,11 @@
(decl u128_from_constant (u128) Constant)
(extern extractor u128_from_constant u128_from_constant)

;; Accessor for `Constant` as u64.

(decl u64_from_constant (u64) Constant)
(extern extractor u64_from_constant u64_from_constant)


;;;; Helpers for tail recursion loops ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand Down
39 changes: 39 additions & 0 deletions cranelift/filetests/filetests/runtests/simd-vconst-64bit.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
test interpret
test run
target aarch64
; x86_64 and s390x do not support 64-bit vectors.

function %vconst_zeroes() -> i8x8 {
block0:
v0 = vconst.i8x8 0x00
return v0
}
; run: %vconst_zeroes() == [0 0 0 0 0 0 0 0]

function %vconst_ones() -> i8x8 {
block0:
v0 = vconst.i8x8 0xffffffffffffffff
return v0
}
; run: %vconst_ones() == [255 255 255 255 255 255 255 255]

function %vconst_i8x8() -> i8x8 {
block0:
v0 = vconst.i8x8 [0 31 63 95 127 159 191 255]
return v0
}
; run: %vconst_i8x8() == [0 31 63 95 127 159 191 255]

function %vconst_i16x4() -> i16x4 {
block0:
v0 = vconst.i16x4 [0 255 32767 65535]
return v0
}
; run: %vconst_i16x4() == [0 255 32767 65535]

function %vconst_i32x2() -> i32x2 {
block0:
v0 = vconst.i32x2 [0 4294967295]
return v0
}
; run: %vconst_i32x2() == [0 4294967295]
12 changes: 10 additions & 2 deletions cranelift/interpreter/src/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ where
.constants
.get(constant_handle.clone())
.as_slice();
DataValue::V128(buffer.try_into().expect("a 16-byte data buffer"))
match ctrl_ty.bytes() {
16 => DataValue::V128(buffer.try_into().expect("a 16-byte data buffer")),
8 => DataValue::V64(buffer.try_into().expect("an 8-byte data buffer")),
length => panic!("unexpected UnaryConst buffer length {}", length),
}
}
InstructionData::Shuffle { imm, .. } => {
let mask = state
Expand All @@ -85,7 +89,11 @@ where
.get(imm)
.unwrap()
.as_slice();
DataValue::V128(mask.try_into().expect("a 16-byte vector mask"))
match ctrl_ty.bytes() {
16 => DataValue::V128(mask.try_into().expect("a 16-byte vector mask")),
8 => DataValue::V64(mask.try_into().expect("an 8-byte vector mask")),
length => panic!("unexpected Shuffle mask length {}", length),
}
}
_ => inst.imm_value().unwrap(),
})
Expand Down