[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / EarlyCSE / preserve_memoryssa.ll
blob946293df6ca16f9b974fd0d8e078f5d450529cb7
1 ; RUN: opt < %s -early-cse-memssa -verify-memoryssa -disable-output
2 ; REQUIRES: asserts
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5 target triple = "x86_64-unknown-linux-gnu"
7 ; Tests below highlight scenarios where EarlyCSE does not preserve MemorySSA
8 ; optimized accesses. Current MemorySSA verify will accept these.
10 ; Test 1:
11 ; AA cannot tell here that the last load does not alias the only store.
12 ; The first two loads are a common expression, EarlyCSE removes the second one,
13 ; and then AA can see that the last load is a Use(LoE). Hence not optimized as
14 ; it claims. Note that if we replace the GEP indices 2 and 1, AA sees NoAlias
15 ; for the last load, before CSE-ing the first 2 loads.
16 %struct.ImageParameters = type { i32, i32, i32 }
17 @img = external global %struct.ImageParameters*, align 8
18 define void @test1_macroblock() {
19 entry:
20   ; MemoryUse(LoE)
21   %0 = load %struct.ImageParameters*, %struct.ImageParameters** @img, align 8
23   %Pos_2 = getelementptr inbounds %struct.ImageParameters, %struct.ImageParameters* %0, i64 0, i32 2
24   ; 1 = MemoryDef(LoE)
25   store i32 undef, i32* %Pos_2, align 8
27   ; MemoryUse(LoE)
28   %1 = load %struct.ImageParameters*, %struct.ImageParameters** @img, align 8
30   %Pos_1 = getelementptr inbounds %struct.ImageParameters, %struct.ImageParameters* %1, i64 0, i32 1
31   ; MemoryUse(1) MayAlias
32   %2 = load i32, i32* %Pos_1, align 4
33   unreachable
36 ; Test 2:
37 ; EarlyCSE simplifies %string to undef. Def and Use used to be MustAlias, with
38 ; undef they are NoAlias. The Use can be optimized further to LoE. We can
39 ; de-optimize uses of replaced instructions, but in general this is not enough
40 ; (see next tests).
41 %struct.TermS = type { i32, i32, i32, i32, i32, i8* }
42 define fastcc void @test2_term_string() {
43 entry:
44   %string = getelementptr inbounds %struct.TermS, %struct.TermS* undef, i64 0, i32 5
45   ; 1 = MemoryDef(LoE)
46   store i8* undef, i8** %string, align 8
47   ; MemoryUse(1) MustAlias
48   %0 = load i8*, i8** %string, align 8
49   unreachable
52 ; Test 3:
53 ; EarlyCSE simplifies %0 to undef. So the second Def now stores to undef.
54 ; We now find the second load (Use(2) can be optimized further to LoE)
55 ; When replacing instructions, we can deoptimize all uses of the replaced
56 ; instruction and all uses of transitive accesses. However this does not stop
57 ; MemorySSA from being tripped by AA (see test4).
58 %struct.Grammar = type { i8*, i8*, %struct.anon }
59 %struct.anon = type { i32, i32, %struct.Term**, [3 x %struct.Term*] }
60 %struct.Term = type { i32 }
62 define fastcc void @test3_term_string(%struct.Grammar* %g) {
63 entry:
64   ; 1 = MemoryDef(LoE)
65   store i8* undef, i8** undef, align 8
66   ; MemoryUse(LoE)
67   %0 = load i8*, i8** undef, align 8
68   %arrayidx = getelementptr inbounds i8, i8* %0, i64 undef
69   ; 2 = MemoryDef(1)
70   store i8 0, i8* %arrayidx, align 1
71   %v = getelementptr inbounds %struct.Grammar, %struct.Grammar* %g, i64 0, i32 2, i32 2
72   ; MemoryUse(2) MayAlias
73   %1 = load %struct.Term**, %struct.Term*** %v, align 8
74   unreachable
77 ; Test 4:
78 ; Removing dead/unused instructions in if.then274 makes AA smarter. Before
79 ; removal, it finds %4 MayAlias the store above. After removal this can be
80 ; optimized to LoE. Hence after EarlyCSE, there is an access who claims is
81 ; optimized and it can be optimized further.
83 ; We can't escape such cases in general when relying on Alias Analysis.
84 ; The only fail-safe way to actually preserve MemorySSA when removing or
85 ; replacing instructions (i.e. get the *same* MemorySSA as if it was computed
86 ; for the updated IR) is to recompute it from scratch. What we get now is still
87 ; a correct update, but with accesses that claim to be optimized and can be
88 ; optimized further if we were to re-run MemorySSA on the IR.
89 %struct.gnode.0.1.3.6.9.18.20.79 = type { i32, i32, i32, i32, i32, i32, i32, %struct.gnode.0.1.3.6.9.18.20.79* }
90 @gnodeArray = external global %struct.gnode.0.1.3.6.9.18.20.79**, align 8
92 define void @test4_shortest() {
93 entry:
94   %exl.i = alloca [5 x i32], align 16
95   br i1 undef, label %if.then274, label %for.cond404
97 if.then274:                                       ; preds = %if.end256
98   %0 = bitcast [5 x i32]* %exl.i to i8*
99   %arrayidx.i = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 1
100   %arrayidx1.i = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 2
101   %arrayidx2.i = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 3
102   %arrayidx3.i = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 4
103   %1 = bitcast [5 x i32]* %exl.i to i8*
104   %arrayidx.i1034 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 1
105   %arrayidx1.i1035 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 2
106   %arrayidx2.i1036 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 3
107   %arrayidx3.i1037 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 4
108   unreachable
110 for.cond404:                                      ; preds = %if.end256
111   %2 = bitcast [5 x i32]* %exl.i to i8*
112   %arrayidx.i960 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 1
113   %arrayidx1.i961 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 2
114   %arrayidx2.i962 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 3
115   ; 1 = MemoryDef(LoE)
116   store i32 undef, i32* %arrayidx2.i962, align 4
117   %arrayidx3.i963 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 4
119   ; MemoryUse(LoE)
120   %3 = load %struct.gnode.0.1.3.6.9.18.20.79**, %struct.gnode.0.1.3.6.9.18.20.79*** @gnodeArray, align 8
121   %arrayidx6.i968 = getelementptr inbounds %struct.gnode.0.1.3.6.9.18.20.79*, %struct.gnode.0.1.3.6.9.18.20.79** %3, i64 undef
122   ; MemoryUse(1) MayAlias
123   %4 = load %struct.gnode.0.1.3.6.9.18.20.79*, %struct.gnode.0.1.3.6.9.18.20.79** %arrayidx6.i968, align 8
124   br i1 undef, label %for.cond26.preheader.i974, label %if.then20.for.body_crit_edge.i999
126 for.cond26.preheader.i974:                        ; preds = %if.then20.i996
127   %5 = bitcast [5 x i32]* %exl.i to i8*
128   %arrayidx.i924 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 1
129   %arrayidx1.i925 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 2
130   %arrayidx2.i926 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 3
131   %arrayidx3.i927 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 4
132   unreachable
134 if.then20.for.body_crit_edge.i999:                ; preds = %if.then20.i996
135   %arrayidx9.phi.trans.insert.i997 = getelementptr inbounds [5 x i32], [5 x i32]* %exl.i, i64 0, i64 undef
136   unreachable