cranelift: Enable compiling br_tables for types larger than i32

This commit is contained in:
Afonso Bordado
2021-09-02 15:32:14 +01:00
parent f9ada24bcf
commit 20913a7473

View File

@@ -264,27 +264,22 @@ impl Switch {
} }
}; };
let discr = if bx.func.dfg.value_type(discr).bits() > 32 { let discr = if bx.func.dfg.value_type(discr).bits() > 64 {
// Check for overflow of cast to u32. // Check for overflow of cast to u32. This is the max supported jump table entries.
let new_block = bx.create_block(); let new_block = bx.create_block();
let bigger_than_u32 = let bigger_than_u32 =
bx.ins() bx.ins()
.icmp_imm(IntCC::UnsignedGreaterThan, discr, u32::max_value() as i64); .icmp_imm(IntCC::UnsignedGreaterThan, discr, u32::MAX as i64);
bx.ins().brnz(bigger_than_u32, otherwise, &[]); bx.ins().brnz(bigger_than_u32, otherwise, &[]);
bx.ins().jump(new_block, &[]); bx.ins().jump(new_block, &[]);
bx.seal_block(new_block); bx.seal_block(new_block);
bx.switch_to_block(new_block); bx.switch_to_block(new_block);
// Cast to u32, as br_table is not implemented for integers bigger than 32bits. // Cast to u64, as br_table is not implemented for i128
let discr = if bx.func.dfg.value_type(discr) == types::I128 {
bx.ins().isplit(discr).0 bx.ins().isplit(discr).0
} else { } else {
discr discr
}; };
bx.ins().ireduce(types::I32, discr)
} else {
discr
};
bx.ins().br_table(discr, otherwise, jump_table); bx.ins().br_table(discr, otherwise, jump_table);
} }
@@ -616,13 +611,7 @@ block0:
jump block4 jump block4
block4: block4:
v1 = icmp_imm.i64 ugt v0, 0xffff_ffff br_table.i64 v0, block3, jt0"
brnz v1, block3
jump block5
block5:
v2 = ireduce.i32 v0
br_table v2, block3, jt0"
); );
} }
@@ -663,8 +652,7 @@ block4:
block5: block5:
v2, v3 = isplit.i128 v0 v2, v3 = isplit.i128 v0
v4 = ireduce.i32 v2 br_table v2, block3, jt0"
br_table v4, block3, jt0"
); );
} }
} }