Skip to content

DSEPass incorrectly eliminates store to captured (and later read) pointer #140997

Open
@mhjacobson

Description

@mhjacobson

llvm v20.1.3
macOS "Big Sur" 11.7.10 (20G1427)

I have this code:

declare i32 @printf(i8* noalias readonly, ...)
@fmt = constant [6 x i8] c"%hhd\0a\00"

define ptr @makeValue(ptr %p) noinline optnone memory(none) {
  ret ptr %p
}

define void @useValue(ptr %value) noinline optnone memory(argmem: read) {
  %val = load i8, ptr %value
  call i32 @printf(ptr @fmt, i8 %val)
  ret void
}

define i32 @main() {
entry:
  %1 = alloca i8, align 4
  store i8 42, ptr %1
  %value = call i64 @makeValue(ptr %1)
  call void @useValue(i64 %value)
  ret i32 0
}

opt --passes=dse transforms @main() to (https://godbolt.org/z/rhx1z9K4W):

define i32 @main() {
entry:
  %0 = alloca i8, align 4
  %value = call i64 @makeValue(ptr %0)
  call void @useValue(i64 %value)
  ret i32 0
}

i.e., it eliminates the store to %1, even though %1 is captured by the call to @makeValue() and ultimately read in @useValue().

I believe the memory annotations on @makeValue() and @useValue() are legal. Note that the noinline optnone are just to prevent the optimizer from seeing into the contents of the function, equivalent to if the functions were simply declared and implemented in another module.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions