llvm-capstone/llvm/test/Analysis/ValueTracking/invariant.group.ll
Piotr Padlewski c63b492bcd Simplify recursive launder.invariant.group and strip
Summary:
This patch is crucial for proving equality laundered/stripped
pointers. eg:

  bool foo(A *a) {
    return a == std::launder(a);
  }

Clang with -fstrict-vtable-pointers will emit something like:

    define dso_local zeroext i1 @_Z3fooP1A(%struct.A* %a) {
    entry:
      %c = bitcast %struct.A* %a to i8*
      %call = tail call i8* @llvm.launder.invariant.group.p0i8(i8* %c)
      %0 = bitcast %struct.A* %a to i8*
      %1 = tail call i8* @llvm.strip.invariant.group.p0i8(i8* %0)
      %2 = tail call i8* @llvm.strip.invariant.group.p0i8(i8* %call)
      %cmp = icmp eq i8* %1, %2
      ret i1 %cmp
    }

and because %2 can be replaced with @llvm.strip.invariant.group(%0)
and that %2 and %1 will produce the same value (because strip is readnone)
we can replace compare with true.

Reviewers: rsmith, hfinkel, majnemer, amharc, kuhar

Subscribers: llvm-commits, hiraditya

Differential Revision: https://reviews.llvm.org/D47423

llvm-svn: 336963
2018-07-12 23:55:20 +00:00

35 lines
998 B
LLVM

; RUN: opt -S -instsimplify -instcombine < %s | FileCheck %s
; CHECK-LABEL: define void @checkNonnullLaunder()
define void @checkNonnullLaunder() {
; CHECK: %[[p:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nonnull %0)
; CHECK: call void @use(i8* nonnull %[[p]])
entry:
%0 = alloca i8, align 8
%p = call i8* @llvm.launder.invariant.group.p0i8(i8* %0)
%p2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
call void @use(i8* %p2)
ret void
}
; CHECK-LABEL: define void @checkNonnullStrip()
define void @checkNonnullStrip() {
; CHECK: %[[p:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* nonnull %0)
; CHECK: call void @use(i8* nonnull %[[p]])
entry:
%0 = alloca i8, align 8
%p = call i8* @llvm.strip.invariant.group.p0i8(i8* %0)
%p2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %p)
call void @use(i8* %p2)
ret void
}
declare i8* @llvm.launder.invariant.group.p0i8(i8*)
declare i8* @llvm.strip.invariant.group.p0i8(i8*)
declare void @use(i8*)