1; RUN: opt < %s -mcpu=corei7 -O1 -S -unroll-allow-partial=0 | FileCheck %s --check-prefix=O1
2; RUN: opt < %s -mcpu=corei7 -O2 -S -unroll-allow-partial=0 | FileCheck %s --check-prefix=O2
3; RUN: opt < %s -mcpu=corei7 -O3 -S -unroll-threshold=150 -unroll-allow-partial=0 | FileCheck %s --check-prefix=O3
4; RUN: opt < %s -mcpu=corei7 -O3 -S -unroll-allow-partial=0 | FileCheck %s --check-prefix=O3DEFAULT
5; RUN: opt < %s -mcpu=corei7 -Os -S -unroll-allow-partial=0 | FileCheck %s --check-prefix=Os
6; RUN: opt < %s -mcpu=corei7 -Oz -S -unroll-allow-partial=0 | FileCheck %s --check-prefix=Oz
7; RUN: opt < %s -mcpu=corei7 -O1 -vectorize-loops -S -unroll-allow-partial=0 | FileCheck %s --check-prefix=O1VEC
8; RUN: opt < %s -mcpu=corei7 -Oz -vectorize-loops -S -unroll-allow-partial=0 | FileCheck %s --check-prefix=OzVEC
9; RUN: opt < %s -mcpu=corei7 -O1 -loop-vectorize -S -unroll-allow-partial=0 | FileCheck %s --check-prefix=O1VEC2
10; RUN: opt < %s -mcpu=corei7 -Oz -loop-vectorize -S -unroll-allow-partial=0 | FileCheck %s --check-prefix=OzVEC2
11; RUN: opt < %s -mcpu=corei7 -O3 -unroll-threshold=150 -disable-loop-vectorization -S -unroll-allow-partial=0 | FileCheck %s --check-prefix=O3DIS
12
13; This file tests the llvm.loop.vectorize.enable metadata forcing
14; vectorization even when optimization levels are too low, or when
15; vectorization is disabled.
16
17target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
18target triple = "x86_64-unknown-linux-gnu"
19
20; O1-LABEL: @enabled(
21; O1: store <4 x i32>
22; O1: ret i32
23; O2-LABEL: @enabled(
24; O2: store <4 x i32>
25; O2: ret i32
26; O3-LABEL: @enabled(
27; O3: store <4 x i32>
28; O3: ret i32
29; O3DEFAULT-LABEL: @enabled(
30; O3DEFAULT: store <4 x i32>
31; O3DEFAULT: ret i32
32; Pragma always wins!
33; O3DIS-LABEL: @enabled(
34; O3DIS: store <4 x i32>
35; O3DIS: ret i32
36; Os-LABEL: @enabled(
37; Os: store <4 x i32>
38; Os: ret i32
39; Oz-LABEL: @enabled(
40; Oz: store <4 x i32>
41; Oz: ret i32
42; O1VEC-LABEL: @enabled(
43; O1VEC: store <4 x i32>
44; O1VEC: ret i32
45; OzVEC-LABEL: @enabled(
46; OzVEC: store <4 x i32>
47; OzVEC: ret i32
48; O1VEC2-LABEL: @enabled(
49; O1VEC2: store <4 x i32>
50; O1VEC2: ret i32
51; OzVEC2-LABEL: @enabled(
52; OzVEC2: store <4 x i32>
53; OzVEC2: ret i32
54
55define i32 @enabled(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32 %N) {
56entry:
57  br label %for.body
58
59for.body:                                         ; preds = %for.body, %entry
60  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
61  %arrayidx = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
62  %0 = load i32, i32* %arrayidx, align 4
63  %add = add nsw i32 %0, %N
64  %arrayidx2 = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
65  store i32 %add, i32* %arrayidx2, align 4
66  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
67  %exitcond = icmp eq i64 %indvars.iv.next, 64
68  br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !0
69
70for.end:                                          ; preds = %for.body
71  %1 = load i32, i32* %a, align 4
72  ret i32 %1
73}
74
75; O1-LABEL: @nopragma(
76; O1-NOT: store <4 x i32>
77; O1: ret i32
78; O2-LABEL: @nopragma(
79; O2: store <4 x i32>
80; O2: ret i32
81; O3-LABEL: @nopragma(
82; O3: store <4 x i32>
83; O3: ret i32
84; O3DEFAULT-LABEL: @nopragma(
85; O3DEFAULT: store <4 x i32>
86; O3DEFAULT: ret i32
87; O3DIS-LABEL: @nopragma(
88; O3DIS-NOT: store <4 x i32>
89; O3DIS: ret i32
90; Os-LABEL: @nopragma(
91; Os: store <4 x i32>
92; Os: ret i32
93; Oz-LABEL: @nopragma(
94; Oz-NOT: store <4 x i32>
95; Oz: ret i32
96; O1VEC-LABEL: @nopragma(
97; O1VEC: store <4 x i32>
98; O1VEC: ret i32
99; OzVEC-LABEL: @nopragma(
100; OzVEC: store <4 x i32>
101; OzVEC: ret i32
102; O1VEC2-LABEL: @nopragma(
103; O1VEC2: store <4 x i32>
104; O1VEC2: ret i32
105; OzVEC2-LABEL: @nopragma(
106; OzVEC2: store <4 x i32>
107; OzVEC2: ret i32
108
109define i32 @nopragma(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32 %N) {
110entry:
111  br label %for.body
112
113for.body:                                         ; preds = %for.body, %entry
114  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
115  %arrayidx = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
116  %0 = load i32, i32* %arrayidx, align 4
117  %add = add nsw i32 %0, %N
118  %arrayidx2 = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
119  store i32 %add, i32* %arrayidx2, align 4
120  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
121  %exitcond = icmp eq i64 %indvars.iv.next, 64
122  br i1 %exitcond, label %for.end, label %for.body
123
124for.end:                                          ; preds = %for.body
125  %1 = load i32, i32* %a, align 4
126  ret i32 %1
127}
128
129; O1-LABEL: @disabled(
130; O1-NOT: store <4 x i32>
131; O1: ret i32
132; O2-LABEL: @disabled(
133; O2-NOT: store <4 x i32>
134; O2: ret i32
135; O3-LABEL: @disabled(
136; O3-NOT: store <4 x i32>
137; O3: ret i32
138; O3DEFAULT-LABEL: @disabled(
139; O3DEFAULT: store <4 x i32>
140; O3DEFAULT: ret i32
141; O3DIS-LABEL: @disabled(
142; O3DIS-NOT: store <4 x i32>
143; O3DIS: ret i32
144; Os-LABEL: @disabled(
145; Os-NOT: store <4 x i32>
146; Os: ret i32
147; Oz-LABEL: @disabled(
148; Oz-NOT: store <4 x i32>
149; Oz: ret i32
150; O1VEC-LABEL: @disabled(
151; O1VEC-NOT: store <4 x i32>
152; O1VEC: ret i32
153; OzVEC-LABEL: @disabled(
154; OzVEC-NOT: store <4 x i32>
155; OzVEC: ret i32
156; O1VEC2-LABEL: @disabled(
157; O1VEC2-NOT: store <4 x i32>
158; O1VEC2: ret i32
159; OzVEC2-LABEL: @disabled(
160; OzVEC2-NOT: store <4 x i32>
161; OzVEC2: ret i32
162
163define i32 @disabled(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32 %N) {
164entry:
165  br label %for.body
166
167for.body:                                         ; preds = %for.body, %entry
168  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
169  %arrayidx = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
170  %0 = load i32, i32* %arrayidx, align 4
171  %add = add nsw i32 %0, %N
172  %arrayidx2 = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
173  store i32 %add, i32* %arrayidx2, align 4
174  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
175  %exitcond = icmp eq i64 %indvars.iv.next, 48
176  br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !2
177
178for.end:                                          ; preds = %for.body
179  %1 = load i32, i32* %a, align 4
180  ret i32 %1
181}
182
183!0 = !{!0, !1}
184!1 = !{!"llvm.loop.vectorize.enable", i1 1}
185!2 = !{!2, !3}
186!3 = !{!"llvm.loop.vectorize.enable", i1 0}
187