Skip to content

miscompile of a frozen poison by AArch64 backend #58321

@regehr

Description

@regehr

Here's a slightly modified version of a function found in the LLVM test suite:

define i32 @f(i32 %0) {
  %2 = ashr i32 %0, 32
  %3 = freeze i32 %2
  %4 = ashr i32 %3, 3
  %5 = mul i32 %3, %4
  ret i32 %5
}

It's a bit of a pain to demonstrate how it gets miscompiled, so please bear with me. %2 is poison so then %3 is an arbitrary i32, %4 is an arbitrary i32 that has 4 signbits and then %5 is (%3 * (%3 >>a 3)). This function can return any i32 that satisfies this equation.

On the AArch64 side, this is the generated code:

f:
	asr	w8, w8, #3
	mul	w0, w8, w8
	ret

Notice that it multiplies the shifted value by itself, instead of multiplying the shifted value by the unshifted value, which is what the original code does. This leads to returning impossible values such as 0x4676cf69 that are not solutions to the equation above.

A correct backend can return a constant satisfying the equation (such as 0) or it could generate code similar to this that faithfully performs the math:

f:
	asr	w9, w8, #3
	mul	w0, w8, w9
	ret

cc @nunoplopes @ryan-berger @nbushehri @Hatsunespica

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions