1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -basicaa -newgvn -S | FileCheck %s
3
4target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
5
6define i1 @patatino(i8* %blah, i32 %choice) {
7; CHECK-LABEL: @patatino(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
10; CHECK:       while.cond:
11; CHECK-NEXT:    [[FOO:%.*]] = phi i8* [ [[BLAH:%.*]], [[ENTRY:%.*]] ], [ null, [[WHILE_BODY:%.*]] ]
12; CHECK-NEXT:    switch i32 [[CHOICE:%.*]], label [[WHILE_BODY]] [
13; CHECK-NEXT:    i32 -1, label [[WHILE_END:%.*]]
14; CHECK-NEXT:    i32 40, label [[LAND_END:%.*]]
15; CHECK-NEXT:    ]
16; CHECK:       land.end:
17; CHECK-NEXT:    br label [[WHILE_END]]
18; CHECK:       while.body:
19; CHECK-NEXT:    br label [[WHILE_COND]]
20; CHECK:       while.end:
21; CHECK-NEXT:    store i8 0, i8* [[FOO]], align 1
22; CHECK-NEXT:    [[TMP0:%.*]] = load i8, i8* [[BLAH]], align 1
23; CHECK-NEXT:    [[LOADED:%.*]] = icmp eq i8 [[TMP0]], 0
24; CHECK-NEXT:    store i8 0, i8* [[BLAH]], align 1
25; CHECK-NEXT:    ret i1 [[LOADED]]
26;
27entry:
28  br label %while.cond
29
30while.cond:
31  %foo = phi i8* [ %blah, %entry ], [ null, %while.body ]
32  switch i32 %choice, label %while.body [
33  i32 -1, label %while.end
34  i32 40, label %land.end
35  ]
36
37land.end:
38  br label %while.end
39
40while.body:
41  br label %while.cond
42
43while.end:
44  %foo.lcssa = phi i8* [ %foo, %land.end ], [ %foo, %while.cond ]
45;; These two stores will initially be considered equivalent, but then proven not.
46;; the second store would previously end up deciding it's equivalent to a previous
47;; store, but it was really just finding an optimistic version of itself
48;; in the congruence class.
49  store i8 0, i8* %foo.lcssa, align 1
50  %0 = load i8, i8* %blah, align 1
51  %loaded = icmp eq i8 %0, 0
52  store i8 0, i8* %blah, align 1
53  ret i1 %loaded
54}
55
56
57;; This is an example of a case where the memory states are equivalent solely due to unreachability,
58;; but the stores are not equal.
59define void @foo(i8* %arg) {
60; CHECK-LABEL: @foo(
61; CHECK-NEXT:  bb:
62; CHECK-NEXT:    br label [[BB1:%.*]]
63; CHECK:       bb1:
64; CHECK-NEXT:    [[TMP:%.*]] = phi i8* [ [[ARG:%.*]], [[BB:%.*]] ], [ null, [[BB2:%.*]] ]
65; CHECK-NEXT:    br i1 undef, label [[BB3:%.*]], label [[BB2]]
66; CHECK:       bb2:
67; CHECK-NEXT:    br label [[BB1]]
68; CHECK:       bb3:
69; CHECK-NEXT:    store i8 0, i8* [[TMP]], !g !0
70; CHECK-NEXT:    br label [[BB4:%.*]]
71; CHECK:       bb4:
72; CHECK-NEXT:    br label [[BB6:%.*]]
73; CHECK:       bb6:
74; CHECK-NEXT:    br i1 undef, label [[BB9:%.*]], label [[BB7:%.*]]
75; CHECK:       bb7:
76; CHECK-NEXT:    switch i8 0, label [[BB6]] [
77; CHECK-NEXT:    i8 6, label [[BB8:%.*]]
78; CHECK-NEXT:    ]
79; CHECK:       bb8:
80; CHECK-NEXT:    store i8 undef, i8* null
81; CHECK-NEXT:    br label [[BB4]]
82; CHECK:       bb9:
83; CHECK-NEXT:    store i8 0, i8* [[ARG]], !g !0
84; CHECK-NEXT:    unreachable
85;
86bb:
87  br label %bb1
88
89bb1:                                              ; preds = %bb2, %bb
90  %tmp = phi i8* [ %arg, %bb ], [ null, %bb2 ]
91  br i1 undef, label %bb3, label %bb2
92
93bb2:                                              ; preds = %bb1
94  br label %bb1
95
96bb3:                                              ; preds = %bb1
97  store i8 0, i8* %tmp, !g !0
98  br label %bb4
99
100bb4:                                              ; preds = %bb8, %bb3
101  %tmp5 = phi i8* [ null, %bb8 ], [ %arg, %bb3 ]
102  br label %bb6
103
104bb6:                                              ; preds = %bb7, %bb4
105  br i1 undef, label %bb9, label %bb7
106
107bb7:                                              ; preds = %bb6
108  switch i8 0, label %bb6 [
109  i8 6, label %bb8
110  ]
111
112bb8:                                              ; preds = %bb7
113  store i8 undef, i8* %tmp5, !g !0
114  br label %bb4
115
116bb9:                                              ; preds = %bb6
117  %tmp10 = phi i8* [ %tmp5, %bb6 ]
118  store i8 0, i8* %tmp10, !g !0
119  unreachable
120}
121
122!0 = !{}
123