| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 
 | ; RUN: opt -o %t %s -instcombine -simplifycfg -thinlto-bc -verify-assumption-cache
; RUN: llvm-dis -o - %t | FileCheck %s
; Test that the simplifycfg pass correctly updates the assumption cache
; when it clones the llvm.assume call as part of creating a critical
; edge. To do that, we set up a pass pipeline such that (1) an assumption
; cache is created for foo before simplifycfg updates it, and (2) foo's
; assumption cache is verified after simplifycfg has run. To satisfy 1, we
; run the instcombine pass first in our pipeline. To satisfy 2, we use the
; ThinLTOBitcodeWriter pass to write bitcode (that pass uses the assumption
; cache). That ensures that the pass manager does not call releaseMemory()
; on the AssumptionCacheTracker before the end of the pipeline, which would
; wipe out the bad assumption cache before it is verified.
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%class.F = type { i8 }
%class.B = type { i8 }
%class.A = type { %class.C }
%class.C = type { i32 (...)** }
define void @foo(%class.F* %this, %class.B* %out) {
entry:
  %call = tail call i32 @_ZNK1F5beginEv(%class.F* %this)
  %call2 = tail call i32 @_ZNK1F3endEv(%class.F* %this)
  %cmp.i22 = icmp eq i32 %call, %call2
  br i1 %cmp.i22, label %while.end, label %while.body.preheader
while.body.preheader:
  br label %while.body
while.body:
  %frame_node.sroa.0.023 = phi i32 [ %inc.i, %_ZN10unique_ptrD2Ev.exit ], [ %call, %while.body.preheader ]
  %call8 = tail call i8* @_Znwm(i64 8)
  %inc.i = add nsw i32 %frame_node.sroa.0.023, 1
  %cmp = icmp eq i32 %inc.i, %call2
  br i1 %cmp, label %_ZN10unique_ptrD2Ev.exit, label %if.then
if.then:
  tail call void @_ZN1B6appendEv(%class.B* %out)
  br label %_ZN10unique_ptrD2Ev.exit
_ZN10unique_ptrD2Ev.exit:
  %x1 = bitcast i8* %call8 to void (%class.A*)***
  %vtable.i.i = load void (%class.A*)**, void (%class.A*)*** %x1, align 8
  %x2 = bitcast void (%class.A*)** %vtable.i.i to i8*
  %x3 = tail call i1 @llvm.type.test(i8* %x2, metadata !"foo")
  ; CHECK: call void @llvm.assume
  ; CHECK: call void @llvm.assume
  tail call void @llvm.assume(i1 %x3) #5
  br i1 %cmp, label %while.end.loopexit, label %while.body
while.end.loopexit:
  br label %while.end
while.end:
  ret void
}
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
declare i32 @_ZNK1F5beginEv(%class.F*)
declare i32 @_ZNK1F3endEv(%class.F*)
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1)
declare noalias nonnull i8* @_Znwm(i64)
declare void @_ZN1B6appendEv(%class.B*)
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
declare i1 @llvm.type.test(i8*, metadata)
declare void @llvm.assume(i1)
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"PIC Level", i32 2}
!1 = !{!"clang version 5.0.0 "}
 |