Skip to content

[SelectionDAG] Incorrect handling of lifetimes with multiple objects #104776

@nikic

Description

@nikic

The lowering in

case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end: {
treats lifetime.start/end on an argument that has multiple underlying objects by performing a lifetime start/end on each of the objects.

So if you have something like this:

define i64 @test(i1 %c, ptr %p) {
  %a = alloca i64
  %b = alloca i64
  %sel.b = select i1 %c, ptr %b, ptr %a
  call void @llvm.lifetime.start(i64 8, ptr %a)
  store i64 1, ptr %a
  call void @llvm.lifetime.end(i64 8, ptr %sel.b)
  call void @llvm.lifetime.start(i64 8, ptr %b)
  store i64 2, ptr %b
  store ptr %b, ptr %p ; prevent store from being optimized away
  %v = load i64, ptr %a
  call void @llvm.lifetime.end(i64 8, ptr %b)
  ret i64 %v
}

Then the lifetime.end on %sel.b will be lowered to a lifetime.end on both %a and %b. However, assuming %c is true at runtime, it only ends the lifetime of %b and the overall IR is well-defined.

The final assembly is incorrect as a result of stack coloring:

	movq	$1, -8(%rsp)
	movq	$2, -8(%rsp)
	leaq	-8(%rsp), %rax
	movq	%rax, (%rsi)
	movq	-8(%rsp), %rax
	retq

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