aarch64 isel: collect_address_addends: correctly handle ExtendOp::UXTW(negative immediate).
The current code doesn't correctly handle the case where `ExtendOp::UXTW` has as source, a constant-producing insn that produces a negative (32-bit) value. Then the value is incorrectly sign-extended to 64 bits (in fact, this has already been done by `ctx.get_constant(insn)`), whereas it needs to be zero extended. The obvious fix, done here, is just to force bits 63:32 of the extension to zero, hence zero-extending it.
This commit is contained in:
committed by
julian-seward1
parent
d07fffeb41
commit
8f34d2dc59
@@ -616,7 +616,7 @@ fn collect_address_addends<C: LowerCtx<I = Inst>>(
|
|||||||
maybe_input_insn(ctx, extendee_input, Opcode::Iconst),
|
maybe_input_insn(ctx, extendee_input, Opcode::Iconst),
|
||||||
extendop,
|
extendop,
|
||||||
) {
|
) {
|
||||||
let value = ctx.get_constant(insn).unwrap() as i64;
|
let value = (ctx.get_constant(insn).unwrap() & 0xFFFF_FFFF_u64) as i64;
|
||||||
offset += value;
|
offset += value;
|
||||||
} else {
|
} else {
|
||||||
let reg = put_input_in_reg(ctx, extendee_input, NarrowValueMode::None);
|
let reg = put_input_in_reg(ctx, extendee_input, NarrowValueMode::None);
|
||||||
|
|||||||
@@ -344,3 +344,69 @@ block0(v0: i64, v1: i32):
|
|||||||
; nextln: mov sp, fp
|
; nextln: mov sp, fp
|
||||||
; nextln: ldp fp, lr, [sp], #16
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
; nextln: ret
|
; nextln: ret
|
||||||
|
|
||||||
|
function %f18(i64, i64, i64) -> i32 {
|
||||||
|
block0(v0: i64, v1: i64, v2: i64):
|
||||||
|
v3 = iconst.i32 -4098
|
||||||
|
v6 = uextend.i64 v3
|
||||||
|
v5 = sload16.i32 v6+0
|
||||||
|
return v5
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: movn w0, #4097
|
||||||
|
; nextln: ldrsh x0, [x0]
|
||||||
|
; nextln: mov sp, fp
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
function %f19(i64, i64, i64) -> i32 {
|
||||||
|
block0(v0: i64, v1: i64, v2: i64):
|
||||||
|
v3 = iconst.i32 4098
|
||||||
|
v6 = uextend.i64 v3
|
||||||
|
v5 = sload16.i32 v6+0
|
||||||
|
return v5
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: movz x0, #4098
|
||||||
|
; nextln: ldrsh x0, [x0]
|
||||||
|
; nextln: mov sp, fp
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
function %f20(i64, i64, i64) -> i32 {
|
||||||
|
block0(v0: i64, v1: i64, v2: i64):
|
||||||
|
v3 = iconst.i32 -4098
|
||||||
|
v6 = sextend.i64 v3
|
||||||
|
v5 = sload16.i32 v6+0
|
||||||
|
return v5
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: movn w0, #4097
|
||||||
|
; nextln: sxtw x0, w0
|
||||||
|
; nextln: ldrsh x0, [x0]
|
||||||
|
; nextln: mov sp, fp
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
function %f21(i64, i64, i64) -> i32 {
|
||||||
|
block0(v0: i64, v1: i64, v2: i64):
|
||||||
|
v3 = iconst.i32 4098
|
||||||
|
v6 = sextend.i64 v3
|
||||||
|
v5 = sload16.i32 v6+0
|
||||||
|
return v5
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: movz x0, #4098
|
||||||
|
; nextln: sxtw x0, w0
|
||||||
|
; nextln: ldrsh x0, [x0]
|
||||||
|
; nextln: mov sp, fp
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|||||||
Reference in New Issue
Block a user