From 7c5a56b8365817dfdb6724e7fa89541a139506da Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Wed, 11 May 2022 11:10:02 -0700 Subject: [PATCH] Cranelift: division/remainder CLIF ops are scalar-only. (#4141) In #4104 we discussed whether it makes sense for the division and remainder ops to support vector types. We concluded that because most hardware doesn't support it directly, it probably is not ideal to force all backends to polyfill it. In the future we can always reverse this decision, perhaps with a platform-independent legalization. This PR restricts the allowed types on the CLIF ops to integer types only. --- .../codegen/meta/src/shared/instructions.rs | 119 ++++++++++-------- 1 file changed, 64 insertions(+), 55 deletions(-) diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs index c563e29086..901c48748e 100644 --- a/cranelift/codegen/meta/src/shared/instructions.rs +++ b/cranelift/codegen/meta/src/shared/instructions.rs @@ -1913,68 +1913,77 @@ pub(crate) fn define( .operands_out(vec![qa]), ); - ig.push( - Inst::new( - "udiv", - r#" - Unsigned integer division: `a := \lfloor {x \over y} \rfloor`. + { + // Integer division and remainder are scalar-only; most + // hardware does not directly support vector integer division. - This operation traps if the divisor is zero. - "#, - &formats.binary, - ) - .operands_in(vec![x, y]) - .operands_out(vec![a]) - .can_trap(true), - ); + let x = &Operand::new("x", iB); + let y = &Operand::new("y", iB); + let a = &Operand::new("a", iB); - ig.push( - Inst::new( - "sdiv", - r#" - Signed integer division rounded toward zero: `a := sign(xy) - \lfloor {|x| \over |y|}\rfloor`. + ig.push( + Inst::new( + "udiv", + r#" + Unsigned integer division: `a := \lfloor {x \over y} \rfloor`. - This operation traps if the divisor is zero, or if the result is not - representable in `B` bits two's complement. This only happens - when `x = -2^{B-1}, y = -1`. - "#, - &formats.binary, - ) - .operands_in(vec![x, y]) - .operands_out(vec![a]) - .can_trap(true), - ); + This operation traps if the divisor is zero. + "#, + &formats.binary, + ) + .operands_in(vec![x, y]) + .operands_out(vec![a]) + .can_trap(true), + ); - ig.push( - Inst::new( - "urem", - r#" - Unsigned integer remainder. + ig.push( + Inst::new( + "sdiv", + r#" + Signed integer division rounded toward zero: `a := sign(xy) + \lfloor {|x| \over |y|}\rfloor`. - This operation traps if the divisor is zero. - "#, - &formats.binary, - ) - .operands_in(vec![x, y]) - .operands_out(vec![a]) - .can_trap(true), - ); + This operation traps if the divisor is zero, or if the result is not + representable in `B` bits two's complement. This only happens + when `x = -2^{B-1}, y = -1`. + "#, + &formats.binary, + ) + .operands_in(vec![x, y]) + .operands_out(vec![a]) + .can_trap(true), + ); - ig.push( - Inst::new( - "srem", - r#" - Signed integer remainder. The result has the sign of the dividend. + ig.push( + Inst::new( + "urem", + r#" + Unsigned integer remainder. - This operation traps if the divisor is zero. - "#, - &formats.binary, - ) - .operands_in(vec![x, y]) - .operands_out(vec![a]) - .can_trap(true), - ); + This operation traps if the divisor is zero. + "#, + &formats.binary, + ) + .operands_in(vec![x, y]) + .operands_out(vec![a]) + .can_trap(true), + ); + + ig.push( + Inst::new( + "srem", + r#" + Signed integer remainder. The result has the sign of the dividend. + + This operation traps if the divisor is zero. + "#, + &formats.binary, + ) + .operands_in(vec![x, y]) + .operands_out(vec![a]) + .can_trap(true), + ); + } let a = &Operand::new("a", iB); let x = &Operand::new("x", iB);