fix codegen riscv64 normalize_cmp_value. (#5873)
* fix issue5839 * add target. * fix normalize_cmp_value. * fix test failutre. * fix test failure. * fix parameter type. * Update cranelift/codegen/src/isa/riscv64/inst.isle Co-authored-by: Jamey Sharp <jamey@minilop.net> * Update cranelift/codegen/src/isa/riscv64/lower.isle Co-authored-by: Jamey Sharp <jamey@minilop.net> * remove convert rule from IntCC to ExtendOp --------- Co-authored-by: Jamey Sharp <jamey@minilop.net>
This commit is contained in:
@@ -1910,21 +1910,20 @@
|
||||
(decl lower_cond_br (IntCC ValueRegs VecMachLabel Type) Unit)
|
||||
(extern constructor lower_cond_br lower_cond_br)
|
||||
|
||||
(decl intcc_to_extend_op (IntCC) ExtendOp)
|
||||
(extern constructor intcc_to_extend_op intcc_to_extend_op)
|
||||
|
||||
;; Normalize a value for comparision.
|
||||
;;
|
||||
;; This ensures that types smaller than a register don't accidentally
|
||||
;; pass undefined high bits when being compared as a full register.
|
||||
(decl normalize_cmp_value (Type ValueRegs) ValueRegs)
|
||||
(decl normalize_cmp_value (Type ValueRegs ExtendOp) ValueRegs)
|
||||
|
||||
(rule (normalize_cmp_value $I8 r)
|
||||
(value_reg (alu_rr_imm12 (AluOPRRI.Andi) r (imm12_const 255))))
|
||||
(rule (normalize_cmp_value $I16 r)
|
||||
(value_reg (alu_rrr (AluOPRRR.And) r (imm $I16 65535))))
|
||||
(rule (normalize_cmp_value $I32 r)
|
||||
(value_reg (alu_rr_imm12 (AluOPRRI.Addiw) r (imm12_const 0))))
|
||||
(rule 1 (normalize_cmp_value (fits_in_32 ity) r op)
|
||||
(extend r op ity $I64))
|
||||
|
||||
(rule (normalize_cmp_value $I64 r) r)
|
||||
(rule (normalize_cmp_value $I128 r) r)
|
||||
(rule (normalize_cmp_value $I64 r _) r)
|
||||
(rule (normalize_cmp_value $I128 r _) r)
|
||||
|
||||
;; Convert a truthy value, possibly of more than one register (an
|
||||
;; I128), to one register. If narrower than 64 bits, must have already
|
||||
@@ -1940,7 +1939,7 @@
|
||||
;; Default behavior for branching based on an input value.
|
||||
(rule
|
||||
(lower_branch (brif v @ (value_type ty) _ _) targets)
|
||||
(lower_cond_br (IntCC.NotEqual) (normalize_cmp_value ty v) targets ty))
|
||||
(lower_cond_br (IntCC.NotEqual) (normalize_cmp_value ty v (ExtendOp.Zero)) targets ty))
|
||||
|
||||
;; Special case for SI128 to reify the comparison value and branch on it.
|
||||
(rule 2
|
||||
@@ -2118,7 +2117,7 @@
|
||||
(rule
|
||||
0
|
||||
(lower_bmask (fits_in_64 _) (fits_in_64 in_ty) val)
|
||||
(let ((input Reg (normalize_cmp_value in_ty val))
|
||||
(let ((input Reg (normalize_cmp_value in_ty val (ExtendOp.Zero)))
|
||||
(zero Reg (zero_reg))
|
||||
(ones Reg (load_imm12 -1)))
|
||||
(value_reg (gen_select_reg (IntCC.Equal) zero input zero ones))))
|
||||
|
||||
@@ -143,7 +143,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
format!("{:?}", fde),
|
||||
"FrameDescriptionEntry { address: Constant(4321), length: 16, lsda: None, instructions: [] }"
|
||||
"FrameDescriptionEntry { address: Constant(4321), length: 20, lsda: None, instructions: [] }"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -626,12 +626,12 @@
|
||||
;;;;; Rules for `select`;;;;;;;;;
|
||||
(rule
|
||||
(lower (has_type ty (select c @ (value_type cty) x y)))
|
||||
(gen_select ty (truthy_to_reg cty (normalize_cmp_value cty c)) x y))
|
||||
(gen_select ty (truthy_to_reg cty (normalize_cmp_value cty c (ExtendOp.Zero))) x y))
|
||||
|
||||
(rule 1
|
||||
(lower (has_type (fits_in_64 ty) (select (icmp cc a b @ (value_type in_ty)) x y)))
|
||||
(let ((a Reg (normalize_cmp_value in_ty a))
|
||||
(b Reg (normalize_cmp_value in_ty b)))
|
||||
(let ((a Reg (normalize_cmp_value in_ty a (intcc_to_extend_op cc)))
|
||||
(b Reg (normalize_cmp_value in_ty b (intcc_to_extend_op cc))))
|
||||
(gen_select_reg cc a b x y)))
|
||||
|
||||
;;;;; Rules for `bitselect`;;;;;;;;;
|
||||
@@ -851,7 +851,7 @@
|
||||
|
||||
(rule -1
|
||||
(lower (has_type ty (select_spectre_guard c @ (value_type cty) x y)))
|
||||
(gen_select ty (truthy_to_reg cty (normalize_cmp_value cty c)) x y))
|
||||
(gen_select ty (truthy_to_reg cty (normalize_cmp_value cty c (ExtendOp.Zero))) x y))
|
||||
|
||||
;;;;; Rules for `bmask`;;;;;;;;;
|
||||
(rule
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// Pull in the ISLE generated code.
|
||||
#[allow(unused)]
|
||||
pub mod generated_code;
|
||||
use generated_code::{Context, MInst};
|
||||
use generated_code::{Context, ExtendOp, MInst};
|
||||
|
||||
// Types that the generated ISLE code uses via `use super::*`.
|
||||
use super::{writable_zero_reg, zero_reg};
|
||||
@@ -60,7 +60,22 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Riscv64Backend> {
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn intcc_to_extend_op(&mut self, cc: &IntCC) -> ExtendOp {
|
||||
use IntCC::*;
|
||||
match *cc {
|
||||
Equal
|
||||
| NotEqual
|
||||
| UnsignedLessThan
|
||||
| UnsignedGreaterThanOrEqual
|
||||
| UnsignedGreaterThan
|
||||
| UnsignedLessThanOrEqual => ExtendOp::Zero,
|
||||
|
||||
SignedLessThan
|
||||
| SignedGreaterThanOrEqual
|
||||
| SignedGreaterThan
|
||||
| SignedLessThanOrEqual => ExtendOp::Signed,
|
||||
}
|
||||
}
|
||||
fn lower_cond_br(
|
||||
&mut self,
|
||||
cc: &IntCC,
|
||||
|
||||
Reference in New Issue
Block a user