Issue 184148
Summary Copy avoidance break on laundering
Labels new issue
Assignees
Reporter SchrodingerZhu
    Consider the following LLVM IR:
```llvm
; launder-invgrp.ll
; Test interaction between llvm.launder.invariant.group and !invariant.group metadata.

declare ptr @llvm.launder.invariant.group.p0(ptr)
declare void @use_i64(i64)

!0 = !{}   ; an invariant.group marker node

; ---------------------------
; Case A: load/store through same pointer
; ---------------------------
define void @caseA(ptr %p) {
entry:
  %x  = load i64, ptr %p, align 8, !invariant.group !0
  %p8 = getelementptr i8, ptr %p, i64 8
  %y  = load i64, ptr %p8, align 8, !invariant.group !0

  ; prevent %x/%y from becoming unused and disappearing too early
  call void @use_i64(i64 %x)
  call void @use_i64(i64 %y)

  ; “store back what we loaded”
  store i64 %x, ptr %p,  align 8, !invariant.group !0
  store i64 %y, ptr %p8, align 8, !invariant.group !0
  ret void
}

; ---------------------------
; Case B: launder exists but stores are still through %p
; ---------------------------
define void @caseB_store_through_p(ptr %p) {
entry:
  %x  = load i64, ptr %p, align 8, !invariant.group !0
  %p8 = getelementptr i8, ptr %p, i64 8
  %y  = load i64, ptr %p8, align 8, !invariant.group !0

  %q = call ptr @llvm.launder.invariant.group.p0(ptr %p)

  call void @use_i64(i64 %x)
  call void @use_i64(i64 %y)

  store i64 %x, ptr %p,  align 8, !invariant.group !0
  store i64 %y, ptr %p8, align 8, !invariant.group !0

  ; keep %q live (so launder isn't trivially DCE'd)
  %qq = ptrtoint ptr %q to i64
  call void @use_i64(i64 %qq)

  ret void
}

; ---------------------------
; Case C: laundered pointer is used as store base
; ---------------------------
define void @caseC_store_through_launder(ptr %p) {
entry:
  %x  = load i64, ptr %p, align 8, !invariant.group !0
  %p8 = getelementptr i8, ptr %p, i64 8
  %y  = load i64, ptr %p8, align 8, !invariant.group !0

  %q  = call ptr @llvm.launder.invariant.group.p0(ptr %p)
  %q8 = getelementptr i8, ptr %q, i64 8

  call void @use_i64(i64 %x)
  call void @use_i64(i64 %y)

  store i64 %x, ptr %q,  align 8, !invariant.group !0
  store i64 %y, ptr %q8, align 8, !invariant.group !0
  ret void
}
```

Under `-O3`, it seems that the laundering break the analysis that avoid the redundant copying:

```llvm
; ModuleID = 'more2.ll'
source_filename = "more2.ll"

; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite)
declare ptr @llvm.launder.invariant.group.p0(ptr) #0

declare void @use_i64(i64) local_unnamed_addr

define void @caseA(ptr readonly captures(none) %p) local_unnamed_addr {
entry:
  %x = load i64, ptr %p, align 8, !invariant.group !0
  %p8 = getelementptr i8, ptr %p, i64 8
  %y = load i64, ptr %p8, align 8, !invariant.group !0
  tail call void @use_i64(i64 %x)
  tail call void @use_i64(i64 %y)
  ret void
}

define void @caseB_store_through_p(ptr %p) local_unnamed_addr {
entry:
  %x = load i64, ptr %p, align 8, !invariant.group !0
  %p8 = getelementptr i8, ptr %p, i64 8
  %y = load i64, ptr %p8, align 8, !invariant.group !0
  %q = tail call ptr @llvm.launder.invariant.group.p0(ptr nonnull %p)
  tail call void @use_i64(i64 %x)
  tail call void @use_i64(i64 %y)
  %qq = ptrtoint ptr %q to i64
  tail call void @use_i64(i64 %qq)
  ret void
}

define void @caseC_store_through_launder(ptr captures(none) %p) local_unnamed_addr {
entry:
  %x = load i64, ptr %p, align 8, !invariant.group !0
  %p8 = getelementptr i8, ptr %p, i64 8
  %y = load i64, ptr %p8, align 8, !invariant.group !0
  %q = tail call ptr @llvm.launder.invariant.group.p0(ptr nonnull %p)
  %q8 = getelementptr i8, ptr %q, i64 8
  tail call void @use_i64(i64 %x)
  tail call void @use_i64(i64 %y)
  store i64 %x, ptr %q, align 8, !invariant.group !0
  store i64 %y, ptr %q8, align 8, !invariant.group !0
  ret void
}

attributes #0 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite) }

!0 = !{}
```

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to