diff --git a/cranelift/filetests/filetests/runtests/iabs.clif b/cranelift/filetests/filetests/runtests/iabs.clif new file mode 100644 index 0000000000..acf2bf8584 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/iabs.clif @@ -0,0 +1,42 @@ +test interpret +; aarch64 & x86_64 only support vector iabs + +function %iabs_i8(i8) -> i8 { +block0(v0: i8): + v1 = iabs v0 + return v1 +} +; run: %iabs_i8(0) == 0 +; run: %iabs_i8(127) == 127 +; run: %iabs_i8(-127) == 127 +; run: %iabs_i8(-128) == -128 + +function %iabs_i16(i16) -> i16 { +block0(v0: i16): + v1 = iabs v0 + return v1 +} +; run: %iabs_i16(0) == 0 +; run: %iabs_i16(32767) == 32767 +; run: %iabs_i16(-32767) == 32767 +; run: %iabs_i16(-32768) == -32768 + +function %iabs_i32(i32) -> i32 { +block0(v0: i32): + v1 = iabs v0 + return v1 +} +; run: %iabs_i32(0) == 0 +; run: %iabs_i32(2147483647) == 2147483647 +; run: %iabs_i32(-2147483647) == 2147483647 +; run: %iabs_i32(-2147483648) == -2147483648 + +function %iabs_i64(i64) -> i64 { +block0(v0: i64): + v1 = iabs v0 + return v1 +} +; run: %iabs_i64(0) == 0 +; run: %iabs_i64(9223372036854775807) == 9223372036854775807 +; run: %iabs_i64(-9223372036854775807) == 9223372036854775807 +; run: %iabs_i64(-9223372036854775808) == -9223372036854775808 \ No newline at end of file diff --git a/cranelift/filetests/filetests/runtests/simd-iabs.clif b/cranelift/filetests/filetests/runtests/simd-iabs.clif new file mode 100644 index 0000000000..022815c4a4 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/simd-iabs.clif @@ -0,0 +1,34 @@ +test interpret +test run +target aarch64 +set enable_simd +target x86_64 machinst + +function %iabs_i8x16(i8x16) -> i8x16 { +block0(v0: i8x16): + v1 = iabs v0 + return v1 +} +; run: %iabs_i8x16([0 0 0 0 127 127 127 127 -127 -127 -127 -127 -128 -128 -128 -128]) == [0 0 0 0 127 127 127 127 127 127 127 127 -128 -128 -128 -128] + +function %iabs_i16x8(i16x8) -> i16x8 { +block0(v0: i16x8): + v1 = iabs v0 + return v1 +} +; run: %iabs_i16x8([0 0 32767 32767 -32767 -32767 -32768 -32768]) == [0 0 32767 32767 32767 32767 -32768 -32768] + +function %iabs_i32x4(i32x4) -> i32x4 { +block0(v0: i32x4): + v1 = iabs v0 + return v1 +} +; run: %iabs_i32x4([0 2147483647 -2147483647 -2147483648]) == [0 2147483647 2147483647 -2147483648] + +function %iabs_i64x2(i64x2) -> i64x2 { +block0(v0: i64x2): + v1 = iabs v0 + return v1 +} +; run: %iabs_i64x2([0 9223372036854775807]) == [0 9223372036854775807] +; run: %iabs_i64x2([-9223372036854775807 -9223372036854775808]) == [9223372036854775807 -9223372036854775808] diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index 9fb8c0ac37..a82be29ace 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -557,7 +557,30 @@ where false, )?), Opcode::Ineg => binary(Value::sub, Value::int(0, ctrl_ty)?, arg(0)?)?, - Opcode::Iabs => unimplemented!("Iabs"), + Opcode::Iabs => { + let (min_val, _) = ctrl_ty.lane_type().bounds(true); + let min_val: V = Value::int(min_val as i128, ctrl_ty.lane_type())?; + if ctrl_ty.is_vector() { + let arg0 = extractlanes(&arg(0)?, ctrl_ty.lane_type())?; + let new_vec = arg0 + .into_iter() + .map(|lane| { + if Value::eq(&lane, &min_val)? { + Ok(min_val.clone()) + } else { + Value::int(lane.into_int()?.abs(), ctrl_ty.lane_type()) + } + }) + .collect::>>()?; + assign(vectorizelanes(&new_vec, ctrl_ty)?) + } else { + assign(if Value::eq(&arg(0)?, &min_val)? { + min_val.clone() + } else { + Value::int(arg(0)?.into_int()?.abs(), ctrl_ty.lane_type())? + }) + } + } Opcode::Imul => binary(Value::mul, arg(0)?, arg(1)?)?, Opcode::Umulhi | Opcode::Smulhi => { let double_length = match ctrl_ty.lane_bits() {