• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -memcpyopt -S -enable-memcpyopt-memoryssa=0 | FileCheck %s
3; RUN: opt < %s -memcpyopt -S -enable-memcpyopt-memoryssa=1 -verify-memoryssa | FileCheck %s
4
5; All the stores in this example should be merged into a single memset.
6
7target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
8target triple = "i386-apple-darwin8"
9
10define void @test1(i8 signext  %c) nounwind  {
11; CHECK-LABEL: @test1(
12; CHECK-NEXT:  entry:
13; CHECK-NEXT:    [[X:%.*]] = alloca [19 x i8], align 1
14; CHECK-NEXT:    [[TMP:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 0
15; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 1
16; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 2
17; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 3
18; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 4
19; CHECK-NEXT:    [[TMP21:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 5
20; CHECK-NEXT:    [[TMP25:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 6
21; CHECK-NEXT:    [[TMP29:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 7
22; CHECK-NEXT:    [[TMP33:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 8
23; CHECK-NEXT:    [[TMP37:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 9
24; CHECK-NEXT:    [[TMP41:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 10
25; CHECK-NEXT:    [[TMP45:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 11
26; CHECK-NEXT:    [[TMP49:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 12
27; CHECK-NEXT:    [[TMP53:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 13
28; CHECK-NEXT:    [[TMP57:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 14
29; CHECK-NEXT:    [[TMP61:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 15
30; CHECK-NEXT:    [[TMP65:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 16
31; CHECK-NEXT:    [[TMP69:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 17
32; CHECK-NEXT:    [[TMP73:%.*]] = getelementptr [19 x i8], [19 x i8]* [[X]], i32 0, i32 18
33; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP]], i8 [[C:%.*]], i64 19, i1 false)
34; CHECK-NEXT:    [[TMP76:%.*]] = call i32 (...) @bar([19 x i8]* [[X]]) [[ATTR0:#.*]]
35; CHECK-NEXT:    ret void
36;
37entry:
38  %x = alloca [19 x i8]		; <[19 x i8]*> [#uses=20]
39  %tmp = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 0		; <i8*> [#uses=1]
40  store i8 %c, i8* %tmp, align 1
41  %tmp5 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 1		; <i8*> [#uses=1]
42  store i8 %c, i8* %tmp5, align 1
43  %tmp9 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 2		; <i8*> [#uses=1]
44  store i8 %c, i8* %tmp9, align 1
45  %tmp13 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 3		; <i8*> [#uses=1]
46  store i8 %c, i8* %tmp13, align 1
47  %tmp17 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 4		; <i8*> [#uses=1]
48  store i8 %c, i8* %tmp17, align 1
49  %tmp21 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 5		; <i8*> [#uses=1]
50  store i8 %c, i8* %tmp21, align 1
51  %tmp25 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 6		; <i8*> [#uses=1]
52  store i8 %c, i8* %tmp25, align 1
53  %tmp29 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 7		; <i8*> [#uses=1]
54  store i8 %c, i8* %tmp29, align 1
55  %tmp33 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 8		; <i8*> [#uses=1]
56  store i8 %c, i8* %tmp33, align 1
57  %tmp37 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 9		; <i8*> [#uses=1]
58  store i8 %c, i8* %tmp37, align 1
59  %tmp41 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 10		; <i8*> [#uses=1]
60  store i8 %c, i8* %tmp41, align 1
61  %tmp45 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 11		; <i8*> [#uses=1]
62  store i8 %c, i8* %tmp45, align 1
63  %tmp49 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 12		; <i8*> [#uses=1]
64  store i8 %c, i8* %tmp49, align 1
65  %tmp53 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 13		; <i8*> [#uses=1]
66  store i8 %c, i8* %tmp53, align 1
67  %tmp57 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 14		; <i8*> [#uses=1]
68  store i8 %c, i8* %tmp57, align 1
69  %tmp61 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 15		; <i8*> [#uses=1]
70  store i8 %c, i8* %tmp61, align 1
71  %tmp65 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 16		; <i8*> [#uses=1]
72  store i8 %c, i8* %tmp65, align 1
73  %tmp69 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 17		; <i8*> [#uses=1]
74  store i8 %c, i8* %tmp69, align 1
75  %tmp73 = getelementptr [19 x i8], [19 x i8]* %x, i32 0, i32 18		; <i8*> [#uses=1]
76  store i8 %c, i8* %tmp73, align 1
77  %tmp76 = call i32 (...) @bar( [19 x i8]* %x ) nounwind
78  ret void
79}
80
81declare i32 @bar(...)
82
83%struct.MV = type { i16, i16 }
84
85
86define void @test2() nounwind  {
87; CHECK-LABEL: @test2(
88; CHECK-NEXT:  entry:
89; CHECK-NEXT:    [[REF_IDX:%.*]] = alloca [8 x i8], align 1
90; CHECK-NEXT:    [[LEFT_MVD:%.*]] = alloca [8 x %struct.MV], align 8
91; CHECK-NEXT:    [[UP_MVD:%.*]] = alloca [8 x %struct.MV], align 8
92; CHECK-NEXT:    [[TMP20:%.*]] = getelementptr [8 x i8], [8 x i8]* [[REF_IDX]], i32 0, i32 7
93; CHECK-NEXT:    [[TMP23:%.*]] = getelementptr [8 x i8], [8 x i8]* [[REF_IDX]], i32 0, i32 6
94; CHECK-NEXT:    [[TMP26:%.*]] = getelementptr [8 x i8], [8 x i8]* [[REF_IDX]], i32 0, i32 5
95; CHECK-NEXT:    [[TMP29:%.*]] = getelementptr [8 x i8], [8 x i8]* [[REF_IDX]], i32 0, i32 4
96; CHECK-NEXT:    [[TMP32:%.*]] = getelementptr [8 x i8], [8 x i8]* [[REF_IDX]], i32 0, i32 3
97; CHECK-NEXT:    [[TMP35:%.*]] = getelementptr [8 x i8], [8 x i8]* [[REF_IDX]], i32 0, i32 2
98; CHECK-NEXT:    [[TMP38:%.*]] = getelementptr [8 x i8], [8 x i8]* [[REF_IDX]], i32 0, i32 1
99; CHECK-NEXT:    [[TMP41:%.*]] = getelementptr [8 x i8], [8 x i8]* [[REF_IDX]], i32 0, i32 0
100; CHECK-NEXT:    [[TMP43:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 7, i32 0
101; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP41]], i8 -1, i64 8, i1 false)
102; CHECK-NEXT:    [[TMP46:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 7, i32 1
103; CHECK-NEXT:    [[TMP57:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 6, i32 0
104; CHECK-NEXT:    [[TMP60:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 6, i32 1
105; CHECK-NEXT:    [[TMP71:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 5, i32 0
106; CHECK-NEXT:    [[TMP74:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 5, i32 1
107; CHECK-NEXT:    [[TMP85:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 4, i32 0
108; CHECK-NEXT:    [[TMP88:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 4, i32 1
109; CHECK-NEXT:    [[TMP99:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 3, i32 0
110; CHECK-NEXT:    [[TMP102:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 3, i32 1
111; CHECK-NEXT:    [[TMP113:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 2, i32 0
112; CHECK-NEXT:    [[TMP116:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 2, i32 1
113; CHECK-NEXT:    [[TMP127:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 1, i32 0
114; CHECK-NEXT:    [[TMP130:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 1, i32 1
115; CHECK-NEXT:    [[TMP141:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 0, i32 0
116; CHECK-NEXT:    [[TMP144:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 0, i32 1
117; CHECK-NEXT:    [[TMP148:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 7, i32 0
118; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16* [[TMP141]] to i8*
119; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 32, i1 false)
120; CHECK-NEXT:    [[TMP151:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 7, i32 1
121; CHECK-NEXT:    [[TMP162:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 6, i32 0
122; CHECK-NEXT:    [[TMP165:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 6, i32 1
123; CHECK-NEXT:    [[TMP176:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 5, i32 0
124; CHECK-NEXT:    [[TMP179:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 5, i32 1
125; CHECK-NEXT:    [[TMP190:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 4, i32 0
126; CHECK-NEXT:    [[TMP193:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 4, i32 1
127; CHECK-NEXT:    [[TMP204:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 3, i32 0
128; CHECK-NEXT:    [[TMP207:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 3, i32 1
129; CHECK-NEXT:    [[TMP218:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 2, i32 0
130; CHECK-NEXT:    [[TMP221:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 2, i32 1
131; CHECK-NEXT:    [[TMP232:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 1, i32 0
132; CHECK-NEXT:    [[TMP235:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 1, i32 1
133; CHECK-NEXT:    [[TMP246:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 0, i32 0
134; CHECK-NEXT:    [[TMP249:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 0, i32 1
135; CHECK-NEXT:    [[UP_MVD252:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[UP_MVD]], i32 0, i32 0
136; CHECK-NEXT:    [[LEFT_MVD253:%.*]] = getelementptr [8 x %struct.MV], [8 x %struct.MV]* [[LEFT_MVD]], i32 0, i32 0
137; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i16* [[TMP246]] to i8*
138; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 8 [[TMP1]], i8 0, i64 32, i1 false)
139; CHECK-NEXT:    call void @foo(%struct.MV* [[UP_MVD252]], %struct.MV* [[LEFT_MVD253]], i8* [[TMP41]]) [[ATTR0]]
140; CHECK-NEXT:    ret void
141;
142entry:
143  %ref_idx = alloca [8 x i8]		; <[8 x i8]*> [#uses=8]
144  %left_mvd = alloca [8 x %struct.MV]		; <[8 x %struct.MV]*> [#uses=17]
145  %up_mvd = alloca [8 x %struct.MV]		; <[8 x %struct.MV]*> [#uses=17]
146  %tmp20 = getelementptr [8 x i8], [8 x i8]* %ref_idx, i32 0, i32 7		; <i8*> [#uses=1]
147  store i8 -1, i8* %tmp20, align 1
148  %tmp23 = getelementptr [8 x i8], [8 x i8]* %ref_idx, i32 0, i32 6		; <i8*> [#uses=1]
149  store i8 -1, i8* %tmp23, align 1
150  %tmp26 = getelementptr [8 x i8], [8 x i8]* %ref_idx, i32 0, i32 5		; <i8*> [#uses=1]
151  store i8 -1, i8* %tmp26, align 1
152  %tmp29 = getelementptr [8 x i8], [8 x i8]* %ref_idx, i32 0, i32 4		; <i8*> [#uses=1]
153  store i8 -1, i8* %tmp29, align 1
154  %tmp32 = getelementptr [8 x i8], [8 x i8]* %ref_idx, i32 0, i32 3		; <i8*> [#uses=1]
155  store i8 -1, i8* %tmp32, align 1
156  %tmp35 = getelementptr [8 x i8], [8 x i8]* %ref_idx, i32 0, i32 2		; <i8*> [#uses=1]
157  store i8 -1, i8* %tmp35, align 1
158  %tmp38 = getelementptr [8 x i8], [8 x i8]* %ref_idx, i32 0, i32 1		; <i8*> [#uses=1]
159  store i8 -1, i8* %tmp38, align 1
160  %tmp41 = getelementptr [8 x i8], [8 x i8]* %ref_idx, i32 0, i32 0		; <i8*> [#uses=2]
161  store i8 -1, i8* %tmp41, align 1
162  %tmp43 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 7, i32 0		; <i16*> [#uses=1]
163  store i16 0, i16* %tmp43, align 2
164  %tmp46 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 7, i32 1		; <i16*> [#uses=1]
165  store i16 0, i16* %tmp46, align 2
166  %tmp57 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 6, i32 0		; <i16*> [#uses=1]
167  store i16 0, i16* %tmp57, align 2
168  %tmp60 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 6, i32 1		; <i16*> [#uses=1]
169  store i16 0, i16* %tmp60, align 2
170  %tmp71 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 5, i32 0		; <i16*> [#uses=1]
171  store i16 0, i16* %tmp71, align 2
172  %tmp74 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 5, i32 1		; <i16*> [#uses=1]
173  store i16 0, i16* %tmp74, align 2
174  %tmp85 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 4, i32 0		; <i16*> [#uses=1]
175  store i16 0, i16* %tmp85, align 2
176  %tmp88 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 4, i32 1		; <i16*> [#uses=1]
177  store i16 0, i16* %tmp88, align 2
178  %tmp99 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 3, i32 0		; <i16*> [#uses=1]
179  store i16 0, i16* %tmp99, align 2
180  %tmp102 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 3, i32 1		; <i16*> [#uses=1]
181  store i16 0, i16* %tmp102, align 2
182  %tmp113 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 2, i32 0		; <i16*> [#uses=1]
183  store i16 0, i16* %tmp113, align 2
184  %tmp116 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 2, i32 1		; <i16*> [#uses=1]
185  store i16 0, i16* %tmp116, align 2
186  %tmp127 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 1, i32 0		; <i16*> [#uses=1]
187  store i16 0, i16* %tmp127, align 2
188  %tmp130 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 1, i32 1		; <i16*> [#uses=1]
189  store i16 0, i16* %tmp130, align 2
190  %tmp141 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 0, i32 0		; <i16*> [#uses=1]
191  store i16 0, i16* %tmp141, align 8
192  %tmp144 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 0, i32 1		; <i16*> [#uses=1]
193  store i16 0, i16* %tmp144, align 2
194  %tmp148 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 7, i32 0		; <i16*> [#uses=1]
195  store i16 0, i16* %tmp148, align 2
196  %tmp151 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 7, i32 1		; <i16*> [#uses=1]
197  store i16 0, i16* %tmp151, align 2
198  %tmp162 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 6, i32 0		; <i16*> [#uses=1]
199  store i16 0, i16* %tmp162, align 2
200  %tmp165 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 6, i32 1		; <i16*> [#uses=1]
201  store i16 0, i16* %tmp165, align 2
202  %tmp176 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 5, i32 0		; <i16*> [#uses=1]
203  store i16 0, i16* %tmp176, align 2
204  %tmp179 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 5, i32 1		; <i16*> [#uses=1]
205  store i16 0, i16* %tmp179, align 2
206  %tmp190 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 4, i32 0		; <i16*> [#uses=1]
207  store i16 0, i16* %tmp190, align 2
208  %tmp193 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 4, i32 1		; <i16*> [#uses=1]
209  store i16 0, i16* %tmp193, align 2
210  %tmp204 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 3, i32 0		; <i16*> [#uses=1]
211  store i16 0, i16* %tmp204, align 2
212  %tmp207 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 3, i32 1		; <i16*> [#uses=1]
213  store i16 0, i16* %tmp207, align 2
214  %tmp218 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 2, i32 0		; <i16*> [#uses=1]
215  store i16 0, i16* %tmp218, align 2
216  %tmp221 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 2, i32 1		; <i16*> [#uses=1]
217  store i16 0, i16* %tmp221, align 2
218  %tmp232 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 1, i32 0		; <i16*> [#uses=1]
219  store i16 0, i16* %tmp232, align 2
220  %tmp235 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 1, i32 1		; <i16*> [#uses=1]
221  store i16 0, i16* %tmp235, align 2
222  %tmp246 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 0, i32 0		; <i16*> [#uses=1]
223  store i16 0, i16* %tmp246, align 8
224  %tmp249 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 0, i32 1		; <i16*> [#uses=1]
225  store i16 0, i16* %tmp249, align 2
226  %up_mvd252 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %up_mvd, i32 0, i32 0		; <%struct.MV*> [#uses=1]
227  %left_mvd253 = getelementptr [8 x %struct.MV], [8 x %struct.MV]* %left_mvd, i32 0, i32 0		; <%struct.MV*> [#uses=1]
228  call void @foo( %struct.MV* %up_mvd252, %struct.MV* %left_mvd253, i8* %tmp41 ) nounwind
229  ret void
230
231}
232
233declare void @foo(%struct.MV*, %struct.MV*, i8*)
234
235
236; Store followed by memset.
237define void @test3(i32* nocapture %P) nounwind ssp {
238; CHECK-LABEL: @test3(
239; CHECK-NEXT:  entry:
240; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
241; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 2
242; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[ADD_PTR]] to i8*
243; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[ARRAYIDX]] to i8*
244; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP1]], i8 0, i64 15, i1 false)
245; CHECK-NEXT:    ret void
246;
247entry:
248  %arrayidx = getelementptr inbounds i32, i32* %P, i64 1
249  store i32 0, i32* %arrayidx, align 4
250  %add.ptr = getelementptr inbounds i32, i32* %P, i64 2
251  %0 = bitcast i32* %add.ptr to i8*
252  tail call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 11, i1 false)
253  ret void
254}
255
256; store followed by memset, different offset scenario
257define void @test4(i32* nocapture %P) nounwind ssp {
258; CHECK-LABEL: @test4(
259; CHECK-NEXT:  entry:
260; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
261; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[ADD_PTR]] to i8*
262; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[P]] to i8*
263; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP1]], i8 0, i64 15, i1 false)
264; CHECK-NEXT:    ret void
265;
266entry:
267  store i32 0, i32* %P, align 4
268  %add.ptr = getelementptr inbounds i32, i32* %P, i64 1
269  %0 = bitcast i32* %add.ptr to i8*
270  tail call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 11, i1 false)
271  ret void
272}
273
274declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
275
276; Memset followed by store.
277define void @test5(i32* nocapture %P) nounwind ssp {
278; CHECK-LABEL: @test5(
279; CHECK-NEXT:  entry:
280; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 2
281; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[ADD_PTR]] to i8*
282; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
283; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[ARRAYIDX]] to i8*
284; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP1]], i8 0, i64 15, i1 false)
285; CHECK-NEXT:    ret void
286;
287entry:
288  %add.ptr = getelementptr inbounds i32, i32* %P, i64 2
289  %0 = bitcast i32* %add.ptr to i8*
290  tail call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 11, i1 false)
291  %arrayidx = getelementptr inbounds i32, i32* %P, i64 1
292  store i32 0, i32* %arrayidx, align 4
293  ret void
294}
295
296;; Memset followed by memset.
297define void @test6(i32* nocapture %P) nounwind ssp {
298; CHECK-LABEL: @test6(
299; CHECK-NEXT:  entry:
300; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[P:%.*]] to i8*
301; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 3
302; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[ADD_PTR]] to i8*
303; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i32* [[P]] to i8*
304; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[TMP2]], i8 0, i64 24, i1 false)
305; CHECK-NEXT:    ret void
306;
307entry:
308  %0 = bitcast i32* %P to i8*
309  tail call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 12, i1 false)
310  %add.ptr = getelementptr inbounds i32, i32* %P, i64 3
311  %1 = bitcast i32* %add.ptr to i8*
312  tail call void @llvm.memset.p0i8.i64(i8* %1, i8 0, i64 12, i1 false)
313  ret void
314}
315
316; More aggressive heuristic
317; rdar://9892684
318define void @test7(i32* nocapture %c) nounwind optsize {
319; CHECK-LABEL: @test7(
320; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i32, i32* [[C:%.*]], i32 1
321; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[C]], i32 2
322; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, i32* [[C]], i32 3
323; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i32, i32* [[C]], i32 4
324; CHECK-NEXT:    [[TMP5:%.*]] = bitcast i32* [[C]] to i8*
325; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP5]], i8 -1, i64 20, i1 false)
326; CHECK-NEXT:    ret void
327;
328  store i32 -1, i32* %c, align 4
329  %1 = getelementptr inbounds i32, i32* %c, i32 1
330  store i32 -1, i32* %1, align 4
331  %2 = getelementptr inbounds i32, i32* %c, i32 2
332  store i32 -1, i32* %2, align 4
333  %3 = getelementptr inbounds i32, i32* %c, i32 3
334  store i32 -1, i32* %3, align 4
335  %4 = getelementptr inbounds i32, i32* %c, i32 4
336  store i32 -1, i32* %4, align 4
337  ret void
338}
339
340%struct.test8 = type { [4 x i32] }
341
342define void @test8() {
343; CHECK-LABEL: @test8(
344; CHECK-NEXT:  entry:
345; CHECK-NEXT:    [[MEMTMP:%.*]] = alloca [[STRUCT_TEST8:%.*]], align 16
346; CHECK-NEXT:    [[TMP0:%.*]] = bitcast %struct.test8* [[MEMTMP]] to <4 x i32>*
347; CHECK-NEXT:    store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32>* [[TMP0]], align 16
348; CHECK-NEXT:    ret void
349;
350entry:
351  %memtmp = alloca %struct.test8, align 16
352  %0 = bitcast %struct.test8* %memtmp to <4 x i32>*
353  store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32>* %0, align 16
354  ret void
355}
356
357@test9buf = internal unnamed_addr global [16 x i64] zeroinitializer, align 16
358
359define void @test9() nounwind {
360; CHECK-LABEL: @test9(
361; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 16 bitcast ([16 x i64]* @test9buf to i8*), i8 -1, i64 16, i1 false)
362; CHECK-NEXT:    ret void
363;
364  store i8 -1, i8* bitcast ([16 x i64]* @test9buf to i8*), align 16
365  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 1), align 1
366  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 2), align 2
367  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 3), align 1
368  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 4), align 4
369  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 5), align 1
370  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 6), align 2
371  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 7), align 1
372  store i8 -1, i8* bitcast (i64* getelementptr inbounds ([16 x i64], [16 x i64]* @test9buf, i64 0, i64 1) to i8*), align 8
373  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 9), align 1
374  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 10), align 2
375  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 11), align 1
376  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 12), align 4
377  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 13), align 1
378  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 14), align 2
379  store i8 -1, i8* getelementptr (i8, i8* bitcast ([16 x i64]* @test9buf to i8*), i64 15), align 1
380  ret void
381}
382
383; PR19092
384define void @test10(i8* nocapture %P) nounwind {
385; CHECK-LABEL: @test10(
386; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[P:%.*]], i8 0, i64 42, i1 false)
387; CHECK-NEXT:    ret void
388;
389  tail call void @llvm.memset.p0i8.i64(i8* %P, i8 0, i64 42, i1 false)
390  tail call void @llvm.memset.p0i8.i64(i8* %P, i8 0, i64 23, i1 false)
391  ret void
392}
393
394; Memset followed by odd store.
395define void @test11(i32* nocapture %P) nounwind ssp {
396; CHECK-LABEL: @test11(
397; CHECK-NEXT:  entry:
398; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 3
399; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[ADD_PTR]] to i8*
400; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 0
401; CHECK-NEXT:    [[ARRAYIDX_CAST:%.*]] = bitcast i32* [[ARRAYIDX]] to i96*
402; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i96* [[ARRAYIDX_CAST]] to i8*
403; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP1]], i8 1, i64 23, i1 false)
404; CHECK-NEXT:    ret void
405;
406entry:
407  %add.ptr = getelementptr inbounds i32, i32* %P, i64 3
408  %0 = bitcast i32* %add.ptr to i8*
409  tail call void @llvm.memset.p0i8.i64(i8* %0, i8 1, i64 11, i1 false)
410  %arrayidx = getelementptr inbounds i32, i32* %P, i64 0
411  %arrayidx.cast = bitcast i32* %arrayidx to i96*
412  store i96 310698676526526814092329217, i96* %arrayidx.cast, align 4
413  ret void
414}
415
416; Alignment should be preserved when there is a store with default align
417define void @test12(i32* nocapture %P) nounwind ssp {
418; CHECK-LABEL: @test12(
419; CHECK-NEXT:  entry:
420; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
421; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[ADD_PTR]] to i8*
422; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[P]] to i8*
423; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP1]], i8 0, i64 15, i1 false)
424; CHECK-NEXT:    ret void
425;
426entry:
427  store i32 0, i32* %P
428  %add.ptr = getelementptr inbounds i32, i32* %P, i64 1
429  %0 = bitcast i32* %add.ptr to i8*
430  tail call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 11, i1 false)
431  ret void
432}
433