[Frontend] Remove unused includes (NFC) (#116927)
[llvm-project.git] / llvm / test / Analysis / MemoryDependenceAnalysis / InvariantLoad.ll
blob60c97b4c275a1c48a4cc59011969ac704fad0175
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=gvn -S | FileCheck %s
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"
5 target triple = "x86_64-unknown-linux-gnu"
7 declare void @llvm.memset.p0.i8(ptr, i8, i32, i1)
8 declare void @foo(ptr)
10 define i8 @test(i1 %cmp) {
11 ; CHECK-LABEL: @test(
12 ; CHECK-NEXT:  entry:
13 ; CHECK-NEXT:    [[P:%.*]] = alloca i8
14 ; CHECK-NEXT:    store i8 5, ptr [[P]]
15 ; CHECK-NEXT:    br label [[HEADER:%.*]]
16 ; CHECK:       header:
17 ; CHECK-NEXT:    [[V:%.*]] = phi i8 [ 5, [[ENTRY:%.*]] ], [ -5, [[ALIVE:%.*]] ]
18 ; CHECK-NEXT:    [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[I_INC:%.*]], [[ALIVE]] ]
19 ; CHECK-NEXT:    br i1 [[CMP:%.*]], label [[ALIVE]], label [[DEAD:%.*]]
20 ; CHECK:       dead:
21 ; CHECK-NEXT:    call void @foo(ptr [[P]])
22 ; CHECK-NEXT:    [[I_1:%.*]] = add i8 [[I]], [[V]]
23 ; CHECK-NEXT:    br label [[ALIVE]]
24 ; CHECK:       alive:
25 ; CHECK-NEXT:    [[I_2:%.*]] = phi i8 [ [[I]], [[HEADER]] ], [ [[I_1]], [[DEAD]] ]
26 ; CHECK-NEXT:    store i8 -5, ptr [[P]]
27 ; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr align 1 [[P]], i8 0, i32 1, i1 false)
28 ; CHECK-NEXT:    [[I_INC]] = add i8 [[I_2]], 1
29 ; CHECK-NEXT:    [[CMP_LOOP:%.*]] = icmp ugt i8 [[I_INC]], 100
30 ; CHECK-NEXT:    br i1 [[CMP_LOOP]], label [[EXIT:%.*]], label [[HEADER]]
31 ; CHECK:       exit:
32 ; CHECK-NEXT:    ret i8 0
35 entry:
36   %p = alloca i8
37   store i8 5, ptr %p
38   br label %header
39 header:
40   %i = phi i8 [0, %entry], [%i.inc, %backedge]
41   br i1 %cmp, label %alive, label %dead
42 dead:
43   call void @foo(ptr %p)
44   %v = load i8, ptr %p, !invariant.load !1
45   %i.1 = add i8 %i, %v
46   br label %alive
47 alive:
48   %i.2 = phi i8 [%i, %header], [%i.1, %dead]
49   store i8 -5, ptr %p
50   br label %backedge
51 backedge:
52   call void @llvm.memset.p0.i8(ptr align 1 %p, i8 0, i32 1, i1 false)
53   %i.inc = add i8 %i.2, 1
54   %cmp.loop = icmp ugt i8 %i.inc, 100
55   br i1 %cmp.loop, label %exit, label %header
56 exit:
57   %res = load i8, ptr %p
58   ret i8 %res
61 ; Check that first two loads are not optimized out while the one marked with
62 ; invariant.load reuses %res1
63 define i8 @test2(i1 %cmp, ptr %p) {
64 ; CHECK-LABEL: @test2(
65 ; CHECK-NEXT:  entry:
66 ; CHECK-NEXT:    [[RES1:%.*]] = load i8, ptr [[P:%.*]], align 1
67 ; CHECK-NEXT:    call void @foo(ptr [[P]])
68 ; CHECK-NEXT:    br i1 [[CMP:%.*]], label [[B2:%.*]], label [[B1:%.*]]
69 ; CHECK:       b1:
70 ; CHECK-NEXT:    [[RES2:%.*]] = load i8, ptr [[P]]
71 ; CHECK-NEXT:    [[RES3:%.*]] = add i8 [[RES1]], [[RES2]]
72 ; CHECK-NEXT:    br label [[ALIVE:%.*]]
73 ; CHECK:       b2:
74 ; CHECK-NEXT:    [[RES_DEAD:%.*]] = add i8 [[RES1]], [[RES1]]
75 ; CHECK-NEXT:    br label [[ALIVE]]
76 ; CHECK:       alive:
77 ; CHECK-NEXT:    [[RES_PHI:%.*]] = phi i8 [ [[RES3]], [[B1]] ], [ [[RES_DEAD]], [[B2]] ]
78 ; CHECK-NEXT:    ret i8 [[RES_PHI]]
81 entry:
82   %res1 = load i8, ptr %p
83   call void @foo(ptr %p)
84   br i1 %cmp, label %b2, label %b1
85 b1:
86   %res2 = load i8, ptr %p
87   %res3 = add i8 %res1, %res2
88   br label %alive
89 b2:
90   %v = load i8, ptr %p, !invariant.load !1
91   %res.dead = add i8 %v, %res1
92   br label %alive
93 alive:
94   %res.phi = phi i8 [%res3, %b1], [%res.dead, %b2]
95   ret i8 %res.phi
98 ; This is essentially the same test case as the above one but with %b1 and %b2
99 ; swapped in "br i1 %cmp, label %b1, label %b2" instruction. That helps us to
100 ; ensure that results doesn't depend on visiting order.
101 define i8 @test3(i1 %cmp, ptr %p) {
102 ; CHECK-LABEL: @test3(
103 ; CHECK-NEXT:  entry:
104 ; CHECK-NEXT:    [[RES1:%.*]] = load i8, ptr [[P:%.*]], align 1
105 ; CHECK-NEXT:    call void @foo(ptr [[P]])
106 ; CHECK-NEXT:    br i1 [[CMP:%.*]], label [[B1:%.*]], label [[B2:%.*]]
107 ; CHECK:       b1:
108 ; CHECK-NEXT:    [[RES2:%.*]] = load i8, ptr [[P]]
109 ; CHECK-NEXT:    [[RES3:%.*]] = add i8 [[RES1]], [[RES2]]
110 ; CHECK-NEXT:    br label [[ALIVE:%.*]]
111 ; CHECK:       b2:
112 ; CHECK-NEXT:    [[RES_DEAD:%.*]] = add i8 [[RES1]], [[RES1]]
113 ; CHECK-NEXT:    br label [[ALIVE]]
114 ; CHECK:       alive:
115 ; CHECK-NEXT:    [[RES_PHI:%.*]] = phi i8 [ [[RES3]], [[B1]] ], [ [[RES_DEAD]], [[B2]] ]
116 ; CHECK-NEXT:    ret i8 [[RES_PHI]]
118 entry:
119   %res1 = load i8, ptr %p
120   call void @foo(ptr %p)
121   br i1 %cmp, label %b1, label %b2
123   %res2 = load i8, ptr %p
124   %res3 = add i8 %res1, %res2
125   br label %alive
127   %v = load i8, ptr %p, !invariant.load !1
128   %res.dead = add i8 %v, %res1
129   br label %alive
130 alive:
131   %res.phi = phi i8 [%res3, %b1], [%res.dead, %b2]
132   ret i8 %res.phi
136 ; This is reduced test case catching regression in the first version of the
137 ; fix for invariant loads (https://reviews.llvm.org/D64405).
138 define void @test4() {
139 ; CHECK-LABEL: @test4(
140 ; CHECK-NEXT:  entry:
141 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr inttoptr (i64 8 to ptr), align 4
142 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], [[TMP0]]
143 ; CHECK-NEXT:    br label [[FUSION_LOOP_HEADER_DIM_1_PREHEADER:%.*]]
144 ; CHECK:       fusion.loop_header.dim.1.preheader:
145 ; CHECK-NEXT:    [[TMP2:%.*]] = phi float [ [[TMP0]], [[ENTRY:%.*]] ], [ [[DOTPRE:%.*]], [[FUSION_LOOP_HEADER_DIM_1_PREHEADER]] ]
146 ; CHECK-NEXT:    [[FUSION_INVAR_ADDRESS_DIM_0_03:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INVAR_INC3:%.*]], [[FUSION_LOOP_HEADER_DIM_1_PREHEADER]] ]
147 ; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds [2 x [1 x [4 x float]]], ptr null, i64 0, i64 [[FUSION_INVAR_ADDRESS_DIM_0_03]], i64 0, i64 2
148 ; CHECK-NEXT:    [[TMP4:%.*]] = fmul float [[TMP2]], [[TMP2]]
149 ; CHECK-NEXT:    [[INVAR_INC3]] = add nuw nsw i64 [[FUSION_INVAR_ADDRESS_DIM_0_03]], 1
150 ; CHECK-NEXT:    [[DOTPHI_TRANS_INSERT:%.*]] = getelementptr inbounds [2 x [1 x [4 x float]]], ptr null, i64 0, i64 [[INVAR_INC3]], i64 0, i64 2
151 ; CHECK-NEXT:    [[DOTPRE]] = load float, ptr [[DOTPHI_TRANS_INSERT]], align 4, !invariant.load !0
152 ; CHECK-NEXT:    br label [[FUSION_LOOP_HEADER_DIM_1_PREHEADER]]
154 entry:
155   %0 = getelementptr inbounds [2 x [1 x [4 x float]]], ptr null, i64 0, i64 0, i64 0, i64 2
156   %1 = load float, ptr %0, align 4
157   %2 = fmul float %1, %1
158   br label %fusion.loop_header.dim.1.preheader
160 fusion.loop_header.dim.1.preheader:               ; preds = %fusion.loop_header.dim.1.preheader, %entry
161   %fusion.invar_address.dim.0.03 = phi i64 [ 0, %entry ], [ %invar.inc3, %fusion.loop_header.dim.1.preheader ]
162   %3 = getelementptr inbounds [2 x [1 x [4 x float]]], ptr null, i64 0, i64 %fusion.invar_address.dim.0.03, i64 0, i64 2
163   %4 = load float, ptr %3, align 4, !invariant.load !1
164   %5 = fmul float %4, %4
165   %6 = getelementptr inbounds [2 x [1 x [4 x float]]], ptr null, i64 0, i64 %fusion.invar_address.dim.0.03, i64 0, i64 2
166   %7 = load float, ptr %6, align 4, !invariant.load !1
167   %8 = fmul float %7, %7
168   %invar.inc3 = add nuw nsw i64 %fusion.invar_address.dim.0.03, 1
169   br label %fusion.loop_header.dim.1.preheader
172 !1 = !{}