Skip to content

Miscompile from AArch64 Global ISel backend: UDiv on LLVM>17 #71440

@tanmaytirpankar

Description

@tanmaytirpankar

Look at the function f below:

target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-linux-gnu"

define i2 @f(i2 %0) {
  %2 = sext i1 true to i2
  %3 = udiv i2 1, %2
  ret i2 %3
}

For the invocation f(-1), the expectation is that f will return a 0.

Lets look at the assembly generated by llc.

tanmay@revenant:~/llvm-clone/llvm/build-release/bin$ llc --march=aarch64 foo.ll -o -
	.text
	.file	"foo.ll"
	.globl	f                               // -- Begin function f
	.p2align	2
	.type	f,@function
f:                                      // @f
	.cfi_startproc
// %bb.0:
	mov	w0, wzr
	ret
.Lfunc_end0:
	.size	f, .Lfunc_end0-f
	.cfi_endproc
                                        // -- End function
	.section	".note.GNU-stack","",@progbits

Look at %bb.0. It stores a 0 in w0. According to the procedure call standard for AArch64 the function returns the value stored in w0 which as expected is 0.

Let us look at the assembly after running --global-isel:

tanmay@revenant:~/llvm-clone/llvm/build-release/bin$ llc --global-isel --march=aarch64 foo.ll -o -
	.text
	.file	"foo.ll"
	.globl	f                               // -- Begin function f
	.p2align	2
	.type	f,@function
f:                                      // @f
	.cfi_startproc
// %bb.0:
	ret
.Lfunc_end0:
	.size	f, .Lfunc_end0-f
	.cfi_endproc
                                        // -- End function
	.section	".note.GNU-stack","",@progbits

As can be seen here in %bb.0, there are no instructions. the function returns the value stored in w0 which has the first argument stored in it so -1.

The behavior was correct up until llvm-17.

cc @regehr

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions