Signed arithmetic miscompiled on AArch64
Currently the AArch64 NCG miscompiles signed, sub-word arithmetic. For instance, consider this program:
test(bits64 buffer) {
return (%zx64(%quot(%lobits8(%neg(bits64[buffer + (1 :: bits64)])), (2 :: bits8))));
}
This should evaluate to -1 /[signed] 2 == 0
.
However, with %9.2.1 it produces the incorrect result of 127
via following assembler:
test:
.Lc3:
# Load W64 from `buffer`
mov x18, x22
ldr x18, [ x18, 1 ]
# Negate
neg x18, x18
# Narrow W64 -> W8
ubfm x18, x18, #0, #7
# Signed Divide by 2
mov w17, #2
sdiv w18, w18, w17
# The above division is wrong: it encodes word-sized division but w18 contains
# a (non-signed-extended) W8
ubfm x18, x18, #0, #7
mov x22, x18
ldr x18, [ x20 ]
br x18