Cranelift: ISLE: aarch64: fix imm12_from_negated_value for i32, i16 (#6078)
* Fix the semantics of imm12_from_negated_value, swapping to a partial term + rule * wrapping_neg
This commit is contained in:
@@ -1704,9 +1704,6 @@
|
|||||||
(decl fpu_op_ri_sli (u8 u8) FPUOpRIMod)
|
(decl fpu_op_ri_sli (u8 u8) FPUOpRIMod)
|
||||||
(extern constructor fpu_op_ri_sli fpu_op_ri_sli)
|
(extern constructor fpu_op_ri_sli fpu_op_ri_sli)
|
||||||
|
|
||||||
(decl imm12_from_negated_u64 (Imm12) u64)
|
|
||||||
(extern extractor imm12_from_negated_u64 imm12_from_negated_u64)
|
|
||||||
|
|
||||||
(decl pure partial lshr_from_u64 (Type u64) ShiftOpAndAmt)
|
(decl pure partial lshr_from_u64 (Type u64) ShiftOpAndAmt)
|
||||||
(extern constructor lshr_from_u64 lshr_from_u64)
|
(extern constructor lshr_from_u64 lshr_from_u64)
|
||||||
|
|
||||||
@@ -1734,11 +1731,13 @@
|
|||||||
(imm12_from_value n)
|
(imm12_from_value n)
|
||||||
(iconst (u64_from_imm64 (imm12_from_u64 n))))
|
(iconst (u64_from_imm64 (imm12_from_u64 n))))
|
||||||
|
|
||||||
;; Same as `imm12_from_value`, but tries negating the constant value.
|
;; Conceptually the same as `imm12_from_value`, but tries negating the constant
|
||||||
(decl imm12_from_negated_value (Imm12) Value)
|
;; value (first sign-extending to handle narrow widths).
|
||||||
(extractor
|
(decl pure partial imm12_from_negated_value (Value) Imm12)
|
||||||
(imm12_from_negated_value n)
|
(rule
|
||||||
(iconst (u64_from_imm64 (imm12_from_negated_u64 n))))
|
(imm12_from_negated_value (has_type ty (iconst n)))
|
||||||
|
(if-let (imm12_from_u64 imm) (i64_as_u64 (i64_neg (i64_sextend_imm64 ty n))))
|
||||||
|
imm)
|
||||||
|
|
||||||
;; Helper type to represent a value and an extend operation fused together.
|
;; Helper type to represent a value and an extend operation fused together.
|
||||||
(type ExtendedValue extern (enum))
|
(type ExtendedValue extern (enum))
|
||||||
|
|||||||
@@ -56,11 +56,13 @@
|
|||||||
|
|
||||||
;; Same as the previous special cases, except we can switch the addition to a
|
;; Same as the previous special cases, except we can switch the addition to a
|
||||||
;; subtraction if the negated immediate fits in 12 bits.
|
;; subtraction if the negated immediate fits in 12 bits.
|
||||||
(rule 2 (lower (has_type (fits_in_64 ty) (iadd x (imm12_from_negated_value y))))
|
(rule 2 (lower (has_type (fits_in_64 ty) (iadd x y)))
|
||||||
(sub_imm ty x y))
|
(if-let imm12_neg (imm12_from_negated_value y))
|
||||||
|
(sub_imm ty x imm12_neg))
|
||||||
|
|
||||||
(rule 3 (lower (has_type (fits_in_64 ty) (iadd (imm12_from_negated_value x) y)))
|
(rule 3 (lower (has_type (fits_in_64 ty) (iadd x y)))
|
||||||
(sub_imm ty y x))
|
(if-let imm12_neg (imm12_from_negated_value x))
|
||||||
|
(sub_imm ty y imm12_neg))
|
||||||
|
|
||||||
;; Special cases for when we're adding an extended register where the extending
|
;; Special cases for when we're adding an extended register where the extending
|
||||||
;; operation can get folded into the add itself.
|
;; operation can get folded into the add itself.
|
||||||
@@ -650,8 +652,9 @@
|
|||||||
|
|
||||||
;; Same as the previous special case, except we can switch the subtraction to an
|
;; Same as the previous special case, except we can switch the subtraction to an
|
||||||
;; addition if the negated immediate fits in 12 bits.
|
;; addition if the negated immediate fits in 12 bits.
|
||||||
(rule 2 (lower (has_type (fits_in_64 ty) (isub x (imm12_from_negated_value y))))
|
(rule 2 (lower (has_type (fits_in_64 ty) (isub x y)))
|
||||||
(add_imm ty x y))
|
(if-let imm12_neg (imm12_from_negated_value y))
|
||||||
|
(add_imm ty x imm12_neg))
|
||||||
|
|
||||||
;; Special cases for when we're subtracting an extended register where the
|
;; Special cases for when we're subtracting an extended register where the
|
||||||
;; extending operation can get folded into the sub itself.
|
;; extending operation can get folded into the sub itself.
|
||||||
|
|||||||
@@ -126,10 +126,6 @@ impl Context for IsleContext<'_, '_, MInst, AArch64Backend> {
|
|||||||
Imm12::maybe_from_u64(n)
|
Imm12::maybe_from_u64(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn imm12_from_negated_u64(&mut self, n: u64) -> Option<Imm12> {
|
|
||||||
Imm12::maybe_from_u64((n as i64).wrapping_neg() as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn imm_shift_from_u8(&mut self, n: u8) -> ImmShift {
|
fn imm_shift_from_u8(&mut self, n: u8) -> ImmShift {
|
||||||
ImmShift::maybe_from_u64(n.into()).unwrap()
|
ImmShift::maybe_from_u64(n.into()).unwrap()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ macro_rules! isle_common_prelude_methods {
|
|||||||
x as u64
|
x as u64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn i64_neg(&mut self, x: i64) -> i64 {
|
||||||
|
x.wrapping_neg()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn u64_add(&mut self, x: u64, y: u64) -> u64 {
|
fn u64_add(&mut self, x: u64, y: u64) -> u64 {
|
||||||
x.wrapping_add(y)
|
x.wrapping_add(y)
|
||||||
|
|||||||
@@ -93,6 +93,9 @@
|
|||||||
(decl pure i64_as_u64 (i64) u64)
|
(decl pure i64_as_u64 (i64) u64)
|
||||||
(extern constructor i64_as_u64 i64_as_u64)
|
(extern constructor i64_as_u64 i64_as_u64)
|
||||||
|
|
||||||
|
(decl pure i64_neg (i64) i64)
|
||||||
|
(extern constructor i64_neg i64_neg)
|
||||||
|
|
||||||
(decl u128_as_u64 (u64) u128)
|
(decl u128_as_u64 (u64) u128)
|
||||||
(extern extractor u128_as_u64 u128_as_u64)
|
(extern extractor u128_as_u64 u128_as_u64)
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ block0(v0: i64):
|
|||||||
; ret
|
; ret
|
||||||
|
|
||||||
;; 4294967295 is zero-extended i32 -1
|
;; 4294967295 is zero-extended i32 -1
|
||||||
;; Result should use immediate but currently doesn't
|
|
||||||
function %b(i32) -> i32 {
|
function %b(i32) -> i32 {
|
||||||
block0(v0: i32):
|
block0(v0: i32):
|
||||||
v1 = iconst.i32 4294967295
|
v1 = iconst.i32 4294967295
|
||||||
@@ -34,18 +33,15 @@ block0(v0: i32):
|
|||||||
|
|
||||||
; VCode:
|
; VCode:
|
||||||
; block0:
|
; block0:
|
||||||
; movn w2, #0
|
; sub w0, w0, #1
|
||||||
; add w0, w0, w2
|
|
||||||
; ret
|
; ret
|
||||||
;
|
;
|
||||||
; Disassembled:
|
; Disassembled:
|
||||||
; block0: ; offset 0x0
|
; block0: ; offset 0x0
|
||||||
; mov w2, #-1
|
; sub w0, w0, #1
|
||||||
; add w0, w0, w2
|
|
||||||
; ret
|
; ret
|
||||||
|
|
||||||
;; 65535 is zero-extended i16 -1
|
;; 65535 is zero-extended i16 -1
|
||||||
;; Result should use immediate but currently doesn't
|
|
||||||
function %a(i16) -> i16 {
|
function %a(i16) -> i16 {
|
||||||
block0(v0: i16):
|
block0(v0: i16):
|
||||||
v1 = iconst.i16 65535
|
v1 = iconst.i16 65535
|
||||||
@@ -55,12 +51,122 @@ block0(v0: i16):
|
|||||||
|
|
||||||
; VCode:
|
; VCode:
|
||||||
; block0:
|
; block0:
|
||||||
; movz w2, #65535
|
; sub w0, w0, #1
|
||||||
; add w0, w0, w2
|
|
||||||
; ret
|
; ret
|
||||||
;
|
;
|
||||||
; Disassembled:
|
; Disassembled:
|
||||||
; block0: ; offset 0x0
|
; block0: ; offset 0x0
|
||||||
; mov w2, #0xffff
|
; sub w0, w0, #1
|
||||||
; add w0, w0, w2
|
; ret
|
||||||
|
|
||||||
|
;; Swapped order to trigger commutative rule
|
||||||
|
function %c(i64) -> i64 {
|
||||||
|
block0(v0: i64):
|
||||||
|
v1 = iconst.i64 -1
|
||||||
|
v3 = iadd v1, v0
|
||||||
|
return v3
|
||||||
|
}
|
||||||
|
|
||||||
|
; VCode:
|
||||||
|
; block0:
|
||||||
|
; sub x0, x0, #1
|
||||||
|
; ret
|
||||||
|
;
|
||||||
|
; Disassembled:
|
||||||
|
; block0: ; offset 0x0
|
||||||
|
; sub x0, x0, #1
|
||||||
|
; ret
|
||||||
|
|
||||||
|
;; Swapped order to trigger commutative rule
|
||||||
|
;; 4294967295 is zero-extended i32 -1
|
||||||
|
function %b(i32) -> i32 {
|
||||||
|
block0(v0: i32):
|
||||||
|
v1 = iconst.i32 4294967295
|
||||||
|
v3 = iadd v1, v0
|
||||||
|
return v3
|
||||||
|
}
|
||||||
|
|
||||||
|
; VCode:
|
||||||
|
; block0:
|
||||||
|
; sub w0, w0, #1
|
||||||
|
; ret
|
||||||
|
;
|
||||||
|
; Disassembled:
|
||||||
|
; block0: ; offset 0x0
|
||||||
|
; sub w0, w0, #1
|
||||||
|
; ret
|
||||||
|
|
||||||
|
;; Swapped order to trigger commutative rule
|
||||||
|
;; 65535 is zero-extended i16 -1
|
||||||
|
function %a(i16) -> i16 {
|
||||||
|
block0(v0: i16):
|
||||||
|
v1 = iconst.i16 65535
|
||||||
|
v3 = iadd v1, v0
|
||||||
|
return v3
|
||||||
|
}
|
||||||
|
|
||||||
|
; VCode:
|
||||||
|
; block0:
|
||||||
|
; sub w0, w0, #1
|
||||||
|
; ret
|
||||||
|
;
|
||||||
|
; Disassembled:
|
||||||
|
; block0: ; offset 0x0
|
||||||
|
; sub w0, w0, #1
|
||||||
|
; ret
|
||||||
|
|
||||||
|
;; Version sub -> add
|
||||||
|
function %c(i64) -> i64 {
|
||||||
|
block0(v0: i64):
|
||||||
|
v1 = iconst.i64 -1
|
||||||
|
v3 = isub v0, v1
|
||||||
|
return v3
|
||||||
|
}
|
||||||
|
|
||||||
|
; VCode:
|
||||||
|
; block0:
|
||||||
|
; add x0, x0, #1
|
||||||
|
; ret
|
||||||
|
;
|
||||||
|
; Disassembled:
|
||||||
|
; block0: ; offset 0x0
|
||||||
|
; add x0, x0, #1
|
||||||
|
; ret
|
||||||
|
|
||||||
|
;; Version sub -> add
|
||||||
|
;; 4294967295 is zero-extended i32 -1
|
||||||
|
function %b(i32) -> i32 {
|
||||||
|
block0(v0: i32):
|
||||||
|
v1 = iconst.i32 4294967295
|
||||||
|
v3 = isub v0, v1
|
||||||
|
return v3
|
||||||
|
}
|
||||||
|
|
||||||
|
; VCode:
|
||||||
|
; block0:
|
||||||
|
; add w0, w0, #1
|
||||||
|
; ret
|
||||||
|
;
|
||||||
|
; Disassembled:
|
||||||
|
; block0: ; offset 0x0
|
||||||
|
; add w0, w0, #1
|
||||||
|
; ret
|
||||||
|
|
||||||
|
;; Version sub -> add
|
||||||
|
;; 65535 is zero-extended i16 -1
|
||||||
|
function %a(i16) -> i16 {
|
||||||
|
block0(v0: i16):
|
||||||
|
v1 = iconst.i16 65535
|
||||||
|
v3 = isub v0, v1
|
||||||
|
return v3
|
||||||
|
}
|
||||||
|
|
||||||
|
; VCode:
|
||||||
|
; block0:
|
||||||
|
; add w0, w0, #1
|
||||||
|
; ret
|
||||||
|
;
|
||||||
|
; Disassembled:
|
||||||
|
; block0: ; offset 0x0
|
||||||
|
; add w0, w0, #1
|
||||||
; ret
|
; ret
|
||||||
|
|||||||
Reference in New Issue
Block a user