1; RUN: opt -basic-aa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s
2; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s
3
4; hfinkel's case
5; [entry]
6;  |
7; .....
8; (clobbering access - b)
9;  |
10; ....  ________________________________
11;  \   /                               |
12;   (x)                                |
13;  ......                              |
14;    |                                 |
15;    |    ______________________       |
16;     \   /                    |       |
17; (starting access)            |       |
18;     ...                      |       |
19; (clobbering access - a)      |       |
20;    ...                       |       |
21;    | |                       |       |
22;    | |_______________________|       |
23;    |                                 |
24;    |_________________________________|
25;
26; More specifically, one access, with multiple clobbering accesses. One of
27; which strictly dominates the access, the other of which has a backedge
28
29; readnone so we don't have a 1:1 mapping of MemorySSA edges to Instructions.
30declare void @doThingWithoutReading() readnone
31declare i8 @getValue() readnone
32declare i1 @getBool() readnone
33
34define hidden void @testcase(i8* %Arg) {
35Entry:
36  call void @doThingWithoutReading()
37  %Val.Entry = call i8 @getValue()
38; CHECK: 1 = MemoryDef(liveOnEntry)
39; CHECK-NEXT: store i8 %Val.Entry
40  store i8 %Val.Entry, i8* %Arg
41  call void @doThingWithoutReading()
42  br label %OuterLoop
43
44OuterLoop:
45; CHECK: 5 = MemoryPhi({Entry,1},{InnerLoop.Tail,3})
46; CHECK-NEXT: %Val.Outer =
47  %Val.Outer = call i8 @getValue()
48; CHECK: 2 = MemoryDef(5)
49; CHECK-NEXT: store i8 %Val.Outer
50  store i8 %Val.Outer, i8* %Arg
51  call void @doThingWithoutReading()
52  br label %InnerLoop
53
54InnerLoop:
55; CHECK: 4 = MemoryPhi({OuterLoop,2},{InnerLoop,3})
56; CHECK-NEXT: ; MemoryUse(4)
57; CHECK-NEXT: %StartingAccess = load
58  %StartingAccess = load i8, i8* %Arg, align 4
59  %Val.Inner = call i8 @getValue()
60; CHECK: 3 = MemoryDef(4)
61; CHECK-NEXT: store i8 %Val.Inner
62  store i8 %Val.Inner, i8* %Arg
63  call void @doThingWithoutReading()
64  %KeepGoing = call i1 @getBool()
65  br i1 %KeepGoing, label %InnerLoop.Tail, label %InnerLoop
66
67InnerLoop.Tail:
68  %KeepGoing.Tail = call i1 @getBool()
69  br i1 %KeepGoing.Tail, label %End, label %OuterLoop
70
71End:
72  ret void
73}
74