Constant-fold icmp instructions (#5666)

We found examples of icmp instructions with both operands constant in
spidermonkey.wasm.
This commit is contained in:
Jamey Sharp
2023-02-01 13:55:36 -08:00
committed by GitHub
parent bdfb746548
commit ac4d28f4dd
5 changed files with 161 additions and 18 deletions

View File

@@ -134,6 +134,28 @@ macro_rules! isle_common_prelude_methods {
x & 0xffff_ffff
}
#[inline]
fn imm64_icmp(&mut self, ty: Type, cc: &IntCC, x: Imm64, y: Imm64) -> Imm64 {
let shift = u32::checked_sub(64, ty.bits()).unwrap_or(0);
let mask = u64::MAX >> shift;
let x = (x.bits() as u64) & mask;
let y = (y.bits() as u64) & mask;
let sext = |v| ((v << shift) as i64) >> shift;
let result = match cc {
IntCC::Equal => x == y,
IntCC::NotEqual => x != y,
IntCC::UnsignedGreaterThanOrEqual => x >= y,
IntCC::UnsignedGreaterThan => x > y,
IntCC::UnsignedLessThanOrEqual => x <= y,
IntCC::UnsignedLessThan => x < y,
IntCC::SignedGreaterThanOrEqual => sext(x) >= sext(y),
IntCC::SignedGreaterThan => sext(x) > sext(y),
IntCC::SignedLessThanOrEqual => sext(x) <= sext(y),
IntCC::SignedLessThan => sext(x) < sext(y),
};
Imm64::new(result.into())
}
#[inline]
fn ty_bits(&mut self, ty: Type) -> u8 {
use std::convert::TryInto;

View File

@@ -70,6 +70,14 @@
(iconst ty k2)))
(subsume (iconst ty (imm64_sshr ty k1 k2))))
(rule (simplify
(icmp result_ty
cc
(iconst ty k1)
(iconst ty k2)))
(subsume (iconst result_ty (imm64_icmp ty cc k1 k2))))
;; Canonicalize via commutativity: push immediates to the right.
;;
;; (op k x) --> (op x k)

View File

@@ -150,6 +150,9 @@
(decl pure u64_uextend_u32 (u64) u64)
(extern constructor u64_uextend_u32 u64_uextend_u32)
(decl pure imm64_icmp (Type IntCC Imm64 Imm64) Imm64)
(extern constructor imm64_icmp imm64_icmp)
(decl u64_is_zero (bool) u64)
(extern extractor infallible u64_is_zero u64_is_zero)