Add commutative addition cases
This commit is contained in:
@@ -30,26 +30,39 @@
|
||||
(rule (lower (has_type (fits_in_64 ty) (iadd x y)))
|
||||
(value_reg (alu_rrr (iadd_op ty) (put_in_reg x) (put_in_reg y))))
|
||||
|
||||
;; Special case for when one operand is an immediate that fits in 12 bits.
|
||||
;; Special cases for when one operand is an immediate that fits in 12 bits.
|
||||
(rule (lower (has_type (fits_in_64 ty) (iadd x (imm12_from_value y))))
|
||||
(value_reg (alu_rr_imm12 (iadd_op ty) (put_in_reg x) y)))
|
||||
|
||||
;; Same as the previous special case, except we can switch the addition to a
|
||||
(rule (lower (has_type (fits_in_64 ty) (iadd (imm12_from_value x) y)))
|
||||
(value_reg (alu_rr_imm12 (iadd_op ty) (put_in_reg y) x)))
|
||||
|
||||
;; Same as the previous special cases, except we can switch the addition to a
|
||||
;; subtraction if the negated immediate fits in 12 bits.
|
||||
(rule (lower (has_type (fits_in_64 ty) (iadd x (imm12_from_negated_value y))))
|
||||
(value_reg (alu_rr_imm12 (isub_op ty) (put_in_reg x) y)))
|
||||
|
||||
;; Special case for when we're adding an extended register where the extending
|
||||
(rule (lower (has_type (fits_in_64 ty) (iadd (imm12_from_negated_value x) y)))
|
||||
(value_reg (alu_rr_imm12 (isub_op ty) (put_in_reg y) x)))
|
||||
|
||||
;; Special cases for when we're adding an extended register where the extending
|
||||
;; operation can get folded into the add itself.
|
||||
(rule (lower (has_type (fits_in_64 ty) (iadd x (extended_value_from_value y))))
|
||||
(value_reg (alu_rr_extend_reg (iadd_op ty) (put_in_reg x) y)))
|
||||
|
||||
;; Special case for when we're adding the shift of a different
|
||||
(rule (lower (has_type (fits_in_64 ty) (iadd (extended_value_from_value x) y)))
|
||||
(value_reg (alu_rr_extend_reg (iadd_op ty) (put_in_reg y) x)))
|
||||
|
||||
;; Special cases for when we're adding the shift of a different
|
||||
;; register by a constant amount and the shift can get folded into the add.
|
||||
(rule (lower (has_type (fits_in_64 ty)
|
||||
(iadd x (def_inst (ishl y (def_inst (iconst (lshl_from_imm64 <ty amt))))))))
|
||||
(value_reg (alu_rrr_shift (iadd_op ty) (put_in_reg x) (put_in_reg y) amt)))
|
||||
|
||||
(rule (lower (has_type (fits_in_64 ty)
|
||||
(iadd (def_inst (ishl x (def_inst (iconst (lshl_from_imm64 <ty amt))))) y)))
|
||||
(value_reg (alu_rrr_shift (iadd_op ty) (put_in_reg y) (put_in_reg x) amt)))
|
||||
|
||||
;; Fold an `iadd` and `imul` combination into a `madd` instruction.
|
||||
(rule (lower (has_type (fits_in_64 ty) (iadd x (def_inst (imul y z)))))
|
||||
(value_reg (alu_rrrr (madd_op ty) (put_in_reg y) (put_in_reg z) (put_in_reg x))))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
src/clif.isle 9c0563583e5500de00ec5e226edc0547ac3ea789c8d76f1da0401c80ec619320fdc9a6f17fd76bbcac74a5894f85385c1f51c900c2b83bc9906d03d0f29bf5cb
|
||||
src/prelude.isle 6ae74a46b3b1f8099397cb8472d75359bc100a05a9bf38532cc41b423f7e600618d83bdb1f5565e0167696e94df2a18e489e6faabb6cc1b3e3af301ab8de55b8
|
||||
src/isa/aarch64/inst.isle 11e77cbb9a0f9c7779dea64db47aaa0b2a90bc1fac851dd0a7f0a37b4234c22b6543469f2a8d477116b2feab563fbf499eb71e414c6e2615e4cc8719e8c0ab1c
|
||||
src/isa/aarch64/lower.isle 25146b36406baa91f81b44b0f54a5948e688af72946f0b70495c22396e275f60d038c52632e5a9fa173cbbd2b901959721679e95f8f6177ec89a7ec04b5f2a30
|
||||
src/isa/aarch64/lower.isle 5a36aa28fabb75cb281e67cf23313feaec5e7e08471af9be03253903c7e33531cf3b42c2ed57c7a1864d7dfb923adcd47971d8ad88d66a1df35ad8edb06a1f9a
|
||||
|
||||
@@ -1273,7 +1273,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
match &pattern5_0 {
|
||||
&Opcode::Iadd => {
|
||||
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
||||
// Rule at src/isa/aarch64/lower.isle line 81.
|
||||
// Rule at src/isa/aarch64/lower.isle line 94.
|
||||
let expr0_0 = C::put_in_regs(ctx, pattern7_0);
|
||||
let expr1_0: usize = 0;
|
||||
let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0);
|
||||
@@ -1293,7 +1293,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
}
|
||||
&Opcode::Isub => {
|
||||
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
||||
// Rule at src/isa/aarch64/lower.isle line 132.
|
||||
// Rule at src/isa/aarch64/lower.isle line 145.
|
||||
let expr0_0 = C::put_in_regs(ctx, pattern7_0);
|
||||
let expr1_0: usize = 0;
|
||||
let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0);
|
||||
@@ -1373,7 +1373,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
match &pattern5_0 {
|
||||
&Opcode::Iadd => {
|
||||
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
||||
// Rule at src/isa/aarch64/lower.isle line 77.
|
||||
// Rule at src/isa/aarch64/lower.isle line 90.
|
||||
let expr0_0 = VecALUOp::Add;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
||||
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
||||
@@ -1385,7 +1385,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
}
|
||||
&Opcode::Isub => {
|
||||
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
||||
// Rule at src/isa/aarch64/lower.isle line 128.
|
||||
// Rule at src/isa/aarch64/lower.isle line 141.
|
||||
let expr0_0 = VecALUOp::Sub;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
||||
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
||||
@@ -1411,27 +1411,127 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
||||
if let Some(pattern8_0) = C::def_inst(ctx, pattern7_0) {
|
||||
let pattern9_0 = C::inst_data(ctx, pattern8_0);
|
||||
if let &InstructionData::Binary {
|
||||
opcode: ref pattern10_0,
|
||||
args: ref pattern10_1,
|
||||
} = &pattern9_0
|
||||
{
|
||||
if let &Opcode::Imul = &pattern10_0 {
|
||||
let (pattern12_0, pattern12_1) =
|
||||
C::unpack_value_array_2(ctx, &pattern10_1);
|
||||
// Rule at src/isa/aarch64/lower.isle line 57.
|
||||
let expr0_0 = constructor_madd_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern12_0);
|
||||
let expr2_0 = C::put_in_reg(ctx, pattern12_1);
|
||||
let expr3_0 = C::put_in_reg(ctx, pattern7_1);
|
||||
let expr4_0 = constructor_alu_rrrr(
|
||||
ctx, &expr0_0, expr1_0, expr2_0, expr3_0,
|
||||
)?;
|
||||
let expr5_0 = C::value_reg(ctx, expr4_0);
|
||||
return Some(expr5_0);
|
||||
match &pattern9_0 {
|
||||
&InstructionData::UnaryImm {
|
||||
opcode: ref pattern10_0,
|
||||
imm: pattern10_1,
|
||||
} => {
|
||||
if let &Opcode::Iconst = &pattern10_0 {
|
||||
let pattern12_0 = C::u64_from_imm64(ctx, pattern10_1);
|
||||
if let Some(pattern13_0) =
|
||||
C::imm12_from_u64(ctx, pattern12_0)
|
||||
{
|
||||
// Rule at src/isa/aarch64/lower.isle line 37.
|
||||
let expr0_0 = constructor_iadd_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern7_1);
|
||||
let expr2_0 = constructor_alu_rr_imm12(
|
||||
ctx,
|
||||
&expr0_0,
|
||||
expr1_0,
|
||||
pattern13_0,
|
||||
)?;
|
||||
let expr3_0 = C::value_reg(ctx, expr2_0);
|
||||
return Some(expr3_0);
|
||||
}
|
||||
if let Some(pattern13_0) =
|
||||
C::imm12_from_negated_u64(ctx, pattern12_0)
|
||||
{
|
||||
// Rule at src/isa/aarch64/lower.isle line 45.
|
||||
let expr0_0 = constructor_isub_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern7_1);
|
||||
let expr2_0 = constructor_alu_rr_imm12(
|
||||
ctx,
|
||||
&expr0_0,
|
||||
expr1_0,
|
||||
pattern13_0,
|
||||
)?;
|
||||
let expr3_0 = C::value_reg(ctx, expr2_0);
|
||||
return Some(expr3_0);
|
||||
}
|
||||
}
|
||||
}
|
||||
&InstructionData::Binary {
|
||||
opcode: ref pattern10_0,
|
||||
args: ref pattern10_1,
|
||||
} => {
|
||||
match &pattern10_0 {
|
||||
&Opcode::Imul => {
|
||||
let (pattern12_0, pattern12_1) =
|
||||
C::unpack_value_array_2(ctx, &pattern10_1);
|
||||
// Rule at src/isa/aarch64/lower.isle line 70.
|
||||
let expr0_0 = constructor_madd_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern12_0);
|
||||
let expr2_0 = C::put_in_reg(ctx, pattern12_1);
|
||||
let expr3_0 = C::put_in_reg(ctx, pattern7_1);
|
||||
let expr4_0 = constructor_alu_rrrr(
|
||||
ctx, &expr0_0, expr1_0, expr2_0, expr3_0,
|
||||
)?;
|
||||
let expr5_0 = C::value_reg(ctx, expr4_0);
|
||||
return Some(expr5_0);
|
||||
}
|
||||
&Opcode::Ishl => {
|
||||
let (pattern12_0, pattern12_1) =
|
||||
C::unpack_value_array_2(ctx, &pattern10_1);
|
||||
if let Some(pattern13_0) = C::def_inst(ctx, pattern12_1)
|
||||
{
|
||||
let pattern14_0 = C::inst_data(ctx, pattern13_0);
|
||||
if let &InstructionData::UnaryImm {
|
||||
opcode: ref pattern15_0,
|
||||
imm: pattern15_1,
|
||||
} = &pattern14_0
|
||||
{
|
||||
if let &Opcode::Iconst = &pattern15_0 {
|
||||
let closure17 = || {
|
||||
return Some(pattern3_0);
|
||||
};
|
||||
if let Some(pattern17_0) = closure17() {
|
||||
if let Some(pattern18_0) =
|
||||
C::lshl_from_imm64(
|
||||
ctx,
|
||||
pattern15_1,
|
||||
pattern17_0,
|
||||
)
|
||||
{
|
||||
// Rule at src/isa/aarch64/lower.isle line 62.
|
||||
let expr0_0 = constructor_iadd_op(
|
||||
ctx, pattern3_0,
|
||||
)?;
|
||||
let expr1_0 =
|
||||
C::put_in_reg(ctx, pattern7_1);
|
||||
let expr2_0 =
|
||||
C::put_in_reg(ctx, pattern12_0);
|
||||
let expr3_0 =
|
||||
constructor_alu_rrr_shift(
|
||||
ctx,
|
||||
&expr0_0,
|
||||
expr1_0,
|
||||
expr2_0,
|
||||
pattern18_0,
|
||||
)?;
|
||||
let expr4_0 =
|
||||
C::value_reg(ctx, expr3_0);
|
||||
return Some(expr4_0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if let Some(pattern8_0) = C::extended_value_from_value(ctx, pattern7_0) {
|
||||
// Rule at src/isa/aarch64/lower.isle line 53.
|
||||
let expr0_0 = constructor_iadd_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern7_1);
|
||||
let expr2_0 =
|
||||
constructor_alu_rr_extend_reg(ctx, &expr0_0, expr1_0, &pattern8_0)?;
|
||||
let expr3_0 = C::value_reg(ctx, expr2_0);
|
||||
return Some(expr3_0);
|
||||
}
|
||||
if let Some(pattern8_0) = C::def_inst(ctx, pattern7_1) {
|
||||
let pattern9_0 = C::inst_data(ctx, pattern8_0);
|
||||
match &pattern9_0 {
|
||||
@@ -1459,7 +1559,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
if let Some(pattern13_0) =
|
||||
C::imm12_from_negated_u64(ctx, pattern12_0)
|
||||
{
|
||||
// Rule at src/isa/aarch64/lower.isle line 39.
|
||||
// Rule at src/isa/aarch64/lower.isle line 42.
|
||||
let expr0_0 = constructor_isub_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
||||
let expr2_0 = constructor_alu_rr_imm12(
|
||||
@@ -1481,7 +1581,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
&Opcode::Imul => {
|
||||
let (pattern12_0, pattern12_1) =
|
||||
C::unpack_value_array_2(ctx, &pattern10_1);
|
||||
// Rule at src/isa/aarch64/lower.isle line 54.
|
||||
// Rule at src/isa/aarch64/lower.isle line 67.
|
||||
let expr0_0 = constructor_madd_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern12_0);
|
||||
let expr2_0 = C::put_in_reg(ctx, pattern12_1);
|
||||
@@ -1515,7 +1615,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
pattern17_0,
|
||||
)
|
||||
{
|
||||
// Rule at src/isa/aarch64/lower.isle line 49.
|
||||
// Rule at src/isa/aarch64/lower.isle line 58.
|
||||
let expr0_0 = constructor_iadd_op(
|
||||
ctx, pattern3_0,
|
||||
)?;
|
||||
@@ -1547,7 +1647,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
}
|
||||
}
|
||||
if let Some(pattern8_0) = C::extended_value_from_value(ctx, pattern7_1) {
|
||||
// Rule at src/isa/aarch64/lower.isle line 44.
|
||||
// Rule at src/isa/aarch64/lower.isle line 50.
|
||||
let expr0_0 = constructor_iadd_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
||||
let expr2_0 =
|
||||
@@ -1577,7 +1677,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
if let Some(pattern13_0) =
|
||||
C::imm12_from_u64(ctx, pattern12_0)
|
||||
{
|
||||
// Rule at src/isa/aarch64/lower.isle line 108.
|
||||
// Rule at src/isa/aarch64/lower.isle line 121.
|
||||
let expr0_0 = constructor_isub_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
||||
let expr2_0 = constructor_alu_rr_imm12(
|
||||
@@ -1592,7 +1692,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
if let Some(pattern13_0) =
|
||||
C::imm12_from_negated_u64(ctx, pattern12_0)
|
||||
{
|
||||
// Rule at src/isa/aarch64/lower.isle line 113.
|
||||
// Rule at src/isa/aarch64/lower.isle line 126.
|
||||
let expr0_0 = constructor_iadd_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
||||
let expr2_0 = constructor_alu_rr_imm12(
|
||||
@@ -1632,7 +1732,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
pattern17_0,
|
||||
)
|
||||
{
|
||||
// Rule at src/isa/aarch64/lower.isle line 123.
|
||||
// Rule at src/isa/aarch64/lower.isle line 136.
|
||||
let expr0_0 = constructor_isub_op(
|
||||
ctx, pattern3_0,
|
||||
)?;
|
||||
@@ -1662,7 +1762,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
}
|
||||
}
|
||||
if let Some(pattern8_0) = C::extended_value_from_value(ctx, pattern7_1) {
|
||||
// Rule at src/isa/aarch64/lower.isle line 118.
|
||||
// Rule at src/isa/aarch64/lower.isle line 131.
|
||||
let expr0_0 = constructor_isub_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
||||
let expr2_0 =
|
||||
@@ -1670,7 +1770,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
let expr3_0 = C::value_reg(ctx, expr2_0);
|
||||
return Some(expr3_0);
|
||||
}
|
||||
// Rule at src/isa/aarch64/lower.isle line 104.
|
||||
// Rule at src/isa/aarch64/lower.isle line 117.
|
||||
let expr0_0 = constructor_isub_op(ctx, pattern3_0)?;
|
||||
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
||||
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
||||
@@ -1690,11 +1790,11 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg
|
||||
pub fn constructor_iadd_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<ALUOp> {
|
||||
let pattern0_0 = arg0;
|
||||
if let Some(pattern1_0) = C::fits_in_32(ctx, pattern0_0) {
|
||||
// Rule at src/isa/aarch64/lower.isle line 62.
|
||||
// Rule at src/isa/aarch64/lower.isle line 75.
|
||||
let expr0_0 = ALUOp::Add32;
|
||||
return Some(expr0_0);
|
||||
}
|
||||
// Rule at src/isa/aarch64/lower.isle line 63.
|
||||
// Rule at src/isa/aarch64/lower.isle line 76.
|
||||
let expr0_0 = ALUOp::Add64;
|
||||
return Some(expr0_0);
|
||||
}
|
||||
@@ -1703,11 +1803,11 @@ pub fn constructor_iadd_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<ALUOp>
|
||||
pub fn constructor_isub_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<ALUOp> {
|
||||
let pattern0_0 = arg0;
|
||||
if let Some(pattern1_0) = C::fits_in_32(ctx, pattern0_0) {
|
||||
// Rule at src/isa/aarch64/lower.isle line 67.
|
||||
// Rule at src/isa/aarch64/lower.isle line 80.
|
||||
let expr0_0 = ALUOp::Sub32;
|
||||
return Some(expr0_0);
|
||||
}
|
||||
// Rule at src/isa/aarch64/lower.isle line 68.
|
||||
// Rule at src/isa/aarch64/lower.isle line 81.
|
||||
let expr0_0 = ALUOp::Sub64;
|
||||
return Some(expr0_0);
|
||||
}
|
||||
@@ -1716,11 +1816,11 @@ pub fn constructor_isub_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<ALUOp>
|
||||
pub fn constructor_madd_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<ALUOp3> {
|
||||
let pattern0_0 = arg0;
|
||||
if let Some(pattern1_0) = C::fits_in_32(ctx, pattern0_0) {
|
||||
// Rule at src/isa/aarch64/lower.isle line 72.
|
||||
// Rule at src/isa/aarch64/lower.isle line 85.
|
||||
let expr0_0 = ALUOp3::MAdd32;
|
||||
return Some(expr0_0);
|
||||
}
|
||||
// Rule at src/isa/aarch64/lower.isle line 73.
|
||||
// Rule at src/isa/aarch64/lower.isle line 86.
|
||||
let expr0_0 = ALUOp3::MAdd64;
|
||||
return Some(expr0_0);
|
||||
}
|
||||
|
||||
@@ -10,8 +10,19 @@ block0(v0: i8):
|
||||
return v3
|
||||
}
|
||||
|
||||
; check: movz x1, #42
|
||||
; nextln: add x0, x1, x0, SXTB
|
||||
; check: sxtb x0, w0
|
||||
; nextln: add x0, x0, #42
|
||||
; nextln: ret
|
||||
|
||||
|
||||
function %f2(i8, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64):
|
||||
v2 = sextend.i64 v0
|
||||
v3 = iadd.i64 v2, v1
|
||||
return v3
|
||||
}
|
||||
|
||||
; check: add x0, x1, x0, SXTB
|
||||
; nextln: ret
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user