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