Merge pull request #2148 from bjorn3/aarch64_fix_put_input_in_rsa

Fix put_input_in_reg
This commit is contained in:
Chris Fallin
2020-08-20 11:41:35 -07:00
committed by GitHub
2 changed files with 72 additions and 23 deletions

View File

@@ -348,6 +348,45 @@ fn put_input_in_rse<C: LowerCtx<I = Inst>>(
let out_ty = ctx.output_ty(insn, 0);
let out_bits = ty_bits(out_ty);
// Is this a zero-extend or sign-extend and can we handle that with a register-mode operator?
if op == Opcode::Uextend || op == Opcode::Sextend {
let sign_extend = op == Opcode::Sextend;
let inner_ty = ctx.input_ty(insn, 0);
let inner_bits = ty_bits(inner_ty);
assert!(inner_bits < out_bits);
if match (sign_extend, narrow_mode) {
// A single zero-extend or sign-extend is equal to itself.
(_, NarrowValueMode::None) => true,
// Two zero-extends or sign-extends in a row is equal to a single zero-extend or sign-extend.
(false, NarrowValueMode::ZeroExtend32) | (false, NarrowValueMode::ZeroExtend64) => {
true
}
(true, NarrowValueMode::SignExtend32) | (true, NarrowValueMode::SignExtend64) => {
true
}
// A zero-extend and a sign-extend in a row is not equal to a single zero-extend or sign-extend
(false, NarrowValueMode::SignExtend32) | (false, NarrowValueMode::SignExtend64) => {
false
}
(true, NarrowValueMode::ZeroExtend32) | (true, NarrowValueMode::ZeroExtend64) => {
false
}
} {
let extendop = match (sign_extend, inner_bits) {
(true, 8) => ExtendOp::SXTB,
(false, 8) => ExtendOp::UXTB,
(true, 16) => ExtendOp::SXTH,
(false, 16) => ExtendOp::UXTH,
(true, 32) => ExtendOp::SXTW,
(false, 32) => ExtendOp::UXTW,
_ => unreachable!(),
};
let reg =
put_input_in_reg(ctx, InsnInput { insn, input: 0 }, NarrowValueMode::None);
return ResultRSE::RegExtend(reg, extendop);
}
}
// If `out_ty` is smaller than 32 bits and we need to zero- or sign-extend,
// then get the result into a register and return an Extend-mode operand on
// that register.
@@ -355,7 +394,7 @@ fn put_input_in_rse<C: LowerCtx<I = Inst>>(
&& ((narrow_mode.is_32bit() && out_bits < 32)
|| (!narrow_mode.is_32bit() && out_bits < 64))
{
let reg = put_input_in_reg(ctx, InsnInput { insn, input: 0 }, NarrowValueMode::None);
let reg = put_input_in_reg(ctx, input, NarrowValueMode::None);
let extendop = match (narrow_mode, out_bits) {
(NarrowValueMode::SignExtend32, 1) | (NarrowValueMode::SignExtend64, 1) => {
ExtendOp::SXTB
@@ -381,28 +420,6 @@ fn put_input_in_rse<C: LowerCtx<I = Inst>>(
};
return ResultRSE::RegExtend(reg, extendop);
}
// Is this a zero-extend or sign-extend and can we handle that with a register-mode operator?
if op == Opcode::Uextend || op == Opcode::Sextend {
assert!(out_bits == 32 || out_bits == 64);
let sign_extend = op == Opcode::Sextend;
let inner_ty = ctx.input_ty(insn, 0);
let inner_bits = ty_bits(inner_ty);
assert!(inner_bits < out_bits);
let extendop = match (sign_extend, inner_bits) {
(true, 1) => ExtendOp::SXTB,
(false, 1) => ExtendOp::UXTB,
(true, 8) => ExtendOp::SXTB,
(false, 8) => ExtendOp::UXTB,
(true, 16) => ExtendOp::SXTH,
(false, 16) => ExtendOp::UXTH,
(true, 32) => ExtendOp::SXTW,
(false, 32) => ExtendOp::UXTW,
_ => unreachable!(),
};
let reg = put_input_in_reg(ctx, InsnInput { insn, input: 0 }, NarrowValueMode::None);
return ResultRSE::RegExtend(reg, extendop);
}
}
ResultRSE::from_rs(put_input_in_rs(ctx, input, narrow_mode))

View File

@@ -0,0 +1,32 @@
; Test that `put_input_in_rse` doesn't try to put the input of the `iconst` into a register, which
; would result in an out-of-bounds panic. (#2147)
test compile
target aarch64
function u0:0() -> i8 system_v {
block0:
v0 = iconst.i16 0xddcc
v1 = icmp.i16 ne v0, v0
v2 = bint.i8 v1
return v2
}
; check: VCode_ShowWithRRU {{
; nextln: Entry block: 0
; nextln: Block 0:
; nextln: (original IR block: block0)
; nextln: (instruction range: 0 .. 11)
; nextln: Inst 0: stp fp, lr, [sp, #-16]!
; nextln: Inst 1: mov fp, sp
; nextln: Inst 2: movz x0, #56780
; nextln: Inst 3: uxth w0, w0
; nextln: Inst 4: movz x1, #56780
; nextln: Inst 5: subs wzr, w0, w1, UXTH
; nextln: Inst 6: cset x0, ne
; nextln: Inst 7: and w0, w0, #1
; nextln: Inst 8: mov sp, fp
; nextln: Inst 9: ldp fp, lr, [sp], #16
; nextln: Inst 10: ret
; nextln: }}