@@ -1072,6 +1072,7 @@ pub enum Insn {
10721072 FixnumAnd { left : InsnId , right : InsnId } ,
10731073 FixnumOr { left : InsnId , right : InsnId } ,
10741074 FixnumXor { left : InsnId , right : InsnId } ,
1075+ IntAnd { left : InsnId , right : InsnId } ,
10751076 IntOr { left : InsnId , right : InsnId } ,
10761077 FixnumLShift { left : InsnId , right : InsnId , state : InsnId } ,
10771078 FixnumRShift { left : InsnId , right : InsnId } ,
@@ -1275,6 +1276,7 @@ macro_rules! for_each_operand_impl {
12751276 | Insn :: FixnumAnd { left, right }
12761277 | Insn :: FixnumOr { left, right }
12771278 | Insn :: FixnumXor { left, right }
1279+ | Insn :: IntAnd { left, right }
12781280 | Insn :: IntOr { left, right }
12791281 | Insn :: FixnumRShift { left, right }
12801282 | Insn :: IsBitEqual { left, right }
@@ -1617,6 +1619,7 @@ impl Insn {
16171619 Insn :: FixnumAnd { .. } => effects:: Empty ,
16181620 Insn :: FixnumOr { .. } => effects:: Empty ,
16191621 Insn :: FixnumXor { .. } => effects:: Empty ,
1622+ Insn :: IntAnd { .. } => effects:: Empty ,
16201623 Insn :: IntOr { .. } => effects:: Empty ,
16211624 Insn :: FixnumLShift { .. } => effects:: Empty ,
16221625 Insn :: FixnumRShift { .. } => effects:: Empty ,
@@ -2006,6 +2009,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
20062009 Insn :: FixnumAnd { left, right, .. } => { write ! ( f, "FixnumAnd {left}, {right}" ) } ,
20072010 Insn :: FixnumOr { left, right, .. } => { write ! ( f, "FixnumOr {left}, {right}" ) } ,
20082011 Insn :: FixnumXor { left, right, .. } => { write ! ( f, "FixnumXor {left}, {right}" ) } ,
2012+ Insn :: IntAnd { left, right } => { write ! ( f, "IntAnd {left}, {right}" ) } ,
20092013 Insn :: IntOr { left, right } => { write ! ( f, "IntOr {left}, {right}" ) } ,
20102014 Insn :: FixnumLShift { left, right, .. } => { write ! ( f, "FixnumLShift {left}, {right}" ) } ,
20112015 Insn :: FixnumRShift { left, right, .. } => { write ! ( f, "FixnumRShift {left}, {right}" ) } ,
@@ -2795,6 +2799,7 @@ impl Function {
27952799 & FixnumAnd { left, right } => FixnumAnd { left : find ! ( left) , right : find ! ( right) } ,
27962800 & FixnumOr { left, right } => FixnumOr { left : find ! ( left) , right : find ! ( right) } ,
27972801 & FixnumXor { left, right } => FixnumXor { left : find ! ( left) , right : find ! ( right) } ,
2802+ & IntAnd { left, right } => IntAnd { left : find ! ( left) , right : find ! ( right) } ,
27982803 & IntOr { left, right } => IntOr { left : find ! ( left) , right : find ! ( right) } ,
27992804 & FixnumLShift { left, right, state } => FixnumLShift { left : find ! ( left) , right : find ! ( right) , state } ,
28002805 & FixnumRShift { left, right } => FixnumRShift { left : find ! ( left) , right : find ! ( right) } ,
@@ -3057,6 +3062,7 @@ impl Function {
30573062 Insn :: FixnumAnd { .. } => types:: Fixnum ,
30583063 Insn :: FixnumOr { .. } => types:: Fixnum ,
30593064 Insn :: FixnumXor { .. } => types:: Fixnum ,
3065+ Insn :: IntAnd { .. } => types:: CInt64 ,
30603066 Insn :: IntOr { left, .. } => self . type_of ( * left) . unspecialized ( ) ,
30613067 Insn :: FixnumLShift { .. } => types:: Fixnum ,
30623068 Insn :: FixnumRShift { .. } => types:: Fixnum ,
@@ -6248,7 +6254,8 @@ impl Function {
62486254 Err ( ValidationError :: MiscValidationError ( insn_id, "IsBitEqual can only compare CInt/CInt or RubyValue/RubyValue" . to_string ( ) ) )
62496255 }
62506256 }
6251- Insn :: IntOr { left, right } => {
6257+ Insn :: IntAnd { left, right }
6258+ | Insn :: IntOr { left, right } => {
62526259 // TODO: Expand this to other matching C integer sizes when we need them.
62536260 self . assert_subtype ( insn_id, left, types:: CInt64 ) ?;
62546261 self . assert_subtype ( insn_id, right, types:: CInt64 )
@@ -8161,20 +8168,13 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
81618168 return_type : types:: CInt64 ,
81628169 } ) ;
81638170
8164- // Guard that the block handler is an IFUNC (tag bits & 0x3 == 0x3)
8165- // bit 0x1 must be set (iseq or ifunc)
8166- fun. push_insn ( block, Insn :: GuardAnyBitSet {
8167- val : block_handler,
8168- mask : Const :: CUInt64 ( 0x1 ) ,
8169- mask_name : None ,
8170- reason : SideExitReason :: InvokeBlockNotIfunc ,
8171- state : exit_id,
8172- } ) ;
8173- // bit 0x2 must be set (ifunc specifically, not iseq)
8174- fun. push_insn ( block, Insn :: GuardAnyBitSet {
8175- val : block_handler,
8176- mask : Const :: CUInt64 ( 0x2 ) ,
8177- mask_name : None ,
8171+ // Guard that the block handler is an IFUNC (tag bits & 0x3 == 0x3),
8172+ // matching VM_BH_IFUNC_P() in the interpreter.
8173+ let tag_mask = fun. push_insn ( block, Insn :: Const { val : Const :: CInt64 ( 0x3 ) } ) ;
8174+ let tag_bits = fun. push_insn ( block, Insn :: IntAnd { left : block_handler, right : tag_mask } ) ;
8175+ fun. push_insn ( block, Insn :: GuardBitEquals {
8176+ val : tag_bits,
8177+ expected : Const :: CInt64 ( 0x3 ) ,
81788178 reason : SideExitReason :: InvokeBlockNotIfunc ,
81798179 state : exit_id,
81808180 } ) ;
0 commit comments