Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SLPVectorizer / X86 / odd_store.ll
blob5f2c42d5c2dec869e6d6d751f1e736396603ff81
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=slp-vectorizer,dce -slp-vectorize-non-power-of-2 -S -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck --check-prefixes=CHECK,NON-POW2 %s
3 ; RUN: opt < %s -passes=slp-vectorizer,dce -slp-vectorize-non-power-of-2=false -S -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck --check-prefixes=CHECK,POW2-ONLY %s
5 ;int foo(char * restrict A, ptr restrict B, float T) {
6 ;  A[0] = (T * B[10] + 4.0);
7 ;  A[1] = (T * B[11] + 5.0);
8 ;  A[2] = (T * B[12] + 6.0);
9 ;}
11 define i32 @foo(ptr noalias nocapture %A, ptr noalias nocapture %B, float %T) {
12 ; NON-POW2-LABEL: @foo(
13 ; NON-POW2-NEXT:    [[TMP1:%.*]] = getelementptr inbounds float, ptr [[B:%.*]], i64 10
14 ; NON-POW2-NEXT:    [[TMP2:%.*]] = load <3 x float>, ptr [[TMP1]], align 4
15 ; NON-POW2-NEXT:    [[TMP3:%.*]] = insertelement <3 x float> poison, float [[T:%.*]], i32 0
16 ; NON-POW2-NEXT:    [[TMP4:%.*]] = shufflevector <3 x float> [[TMP3]], <3 x float> poison, <3 x i32> zeroinitializer
17 ; NON-POW2-NEXT:    [[TMP5:%.*]] = fmul <3 x float> [[TMP2]], [[TMP4]]
18 ; NON-POW2-NEXT:    [[TMP6:%.*]] = fpext <3 x float> [[TMP5]] to <3 x double>
19 ; NON-POW2-NEXT:    [[TMP7:%.*]] = fadd <3 x double> [[TMP6]], <double 4.000000e+00, double 5.000000e+00, double 6.000000e+00>
20 ; NON-POW2-NEXT:    [[TMP8:%.*]] = fptosi <3 x double> [[TMP7]] to <3 x i8>
21 ; NON-POW2-NEXT:    store <3 x i8> [[TMP8]], ptr [[A:%.*]], align 1
22 ; NON-POW2-NEXT:    ret i32 undef
24 ; POW2-ONLY-LABEL: @foo(
25 ; POW2-ONLY-NEXT:    [[TMP1:%.*]] = getelementptr inbounds float, ptr [[B:%.*]], i64 10
26 ; POW2-ONLY-NEXT:    [[TMP2:%.*]] = load float, ptr [[TMP1]], align 4
27 ; POW2-ONLY-NEXT:    [[TMP3:%.*]] = fmul float [[TMP2]], [[T:%.*]]
28 ; POW2-ONLY-NEXT:    [[TMP4:%.*]] = fpext float [[TMP3]] to double
29 ; POW2-ONLY-NEXT:    [[TMP5:%.*]] = fadd double [[TMP4]], 4.000000e+00
30 ; POW2-ONLY-NEXT:    [[TMP6:%.*]] = fptosi double [[TMP5]] to i8
31 ; POW2-ONLY-NEXT:    store i8 [[TMP6]], ptr [[A:%.*]], align 1
32 ; POW2-ONLY-NEXT:    [[TMP7:%.*]] = getelementptr inbounds float, ptr [[B]], i64 11
33 ; POW2-ONLY-NEXT:    [[TMP8:%.*]] = load float, ptr [[TMP7]], align 4
34 ; POW2-ONLY-NEXT:    [[TMP9:%.*]] = fmul float [[TMP8]], [[T]]
35 ; POW2-ONLY-NEXT:    [[TMP10:%.*]] = fpext float [[TMP9]] to double
36 ; POW2-ONLY-NEXT:    [[TMP11:%.*]] = fadd double [[TMP10]], 5.000000e+00
37 ; POW2-ONLY-NEXT:    [[TMP12:%.*]] = fptosi double [[TMP11]] to i8
38 ; POW2-ONLY-NEXT:    [[TMP13:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 1
39 ; POW2-ONLY-NEXT:    store i8 [[TMP12]], ptr [[TMP13]], align 1
40 ; POW2-ONLY-NEXT:    [[TMP14:%.*]] = getelementptr inbounds float, ptr [[B]], i64 12
41 ; POW2-ONLY-NEXT:    [[TMP15:%.*]] = load float, ptr [[TMP14]], align 4
42 ; POW2-ONLY-NEXT:    [[TMP16:%.*]] = fmul float [[TMP15]], [[T]]
43 ; POW2-ONLY-NEXT:    [[TMP17:%.*]] = fpext float [[TMP16]] to double
44 ; POW2-ONLY-NEXT:    [[TMP18:%.*]] = fadd double [[TMP17]], 6.000000e+00
45 ; POW2-ONLY-NEXT:    [[TMP19:%.*]] = fptosi double [[TMP18]] to i8
46 ; POW2-ONLY-NEXT:    [[TMP20:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 2
47 ; POW2-ONLY-NEXT:    store i8 [[TMP19]], ptr [[TMP20]], align 1
48 ; POW2-ONLY-NEXT:    ret i32 undef
50   %1 = getelementptr inbounds float, ptr %B, i64 10
51   %2 = load float, ptr %1, align 4
52   %3 = fmul float %2, %T
53   %4 = fpext float %3 to double
54   %5 = fadd double %4, 4.000000e+00
55   %6 = fptosi double %5 to i8
56   store i8 %6, ptr %A, align 1
57   %7 = getelementptr inbounds float, ptr %B, i64 11
58   %8 = load float, ptr %7, align 4
59   %9 = fmul float %8, %T
60   %10 = fpext float %9 to double
61   %11 = fadd double %10, 5.000000e+00
62   %12 = fptosi double %11 to i8
63   %13 = getelementptr inbounds i8, ptr %A, i64 1
64   store i8 %12, ptr %13, align 1
65   %14 = getelementptr inbounds float, ptr %B, i64 12
66   %15 = load float, ptr %14, align 4
67   %16 = fmul float %15, %T
68   %17 = fpext float %16 to double
69   %18 = fadd double %17, 6.000000e+00
70   %19 = fptosi double %18 to i8
71   %20 = getelementptr inbounds i8, ptr %A, i64 2
72   store i8 %19, ptr %20, align 1
73   ret i32 undef
76 ; PR41892
77 define void @test_v4f32_v2f32_store(<4 x float> %f, ptr %p){
78 ; CHECK-LABEL: @test_v4f32_v2f32_store(
79 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[F:%.*]], <4 x float> poison, <2 x i32> <i32 0, i32 1>
80 ; CHECK-NEXT:    store <2 x float> [[TMP1]], ptr [[P:%.*]], align 4
81 ; CHECK-NEXT:    ret void
83   %x0 = extractelement <4 x float> %f, i64 0
84   %x1 = extractelement <4 x float> %f, i64 1
85   %p1 = getelementptr inbounds float, ptr %p, i64 1
86   store float %x0, ptr %p, align 4
87   store float %x1, ptr %p1, align 4
88   ret void
91 define void @test_v4f32_v2f32_splat_store(<4 x float> %f, ptr %p){
92 ; CHECK-LABEL: @test_v4f32_v2f32_splat_store(
93 ; CHECK-NEXT:    [[X0:%.*]] = extractelement <4 x float> [[F:%.*]], i64 0
94 ; CHECK-NEXT:    [[P1:%.*]] = getelementptr inbounds float, ptr [[P:%.*]], i64 1
95 ; CHECK-NEXT:    store float [[X0]], ptr [[P]], align 4
96 ; CHECK-NEXT:    store float [[X0]], ptr [[P1]], align 4
97 ; CHECK-NEXT:    ret void
99   %x0 = extractelement <4 x float> %f, i64 0
100   %p1 = getelementptr inbounds float, ptr %p, i64 1
101   store float %x0, ptr %p, align 4
102   store float %x0, ptr %p1, align 4
103   ret void
106 define void @test_v4f32_v3f32_store(<4 x float> %f, ptr %p){
107 ; NON-POW2-LABEL: @test_v4f32_v3f32_store(
108 ; NON-POW2-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[F:%.*]], <4 x float> poison, <3 x i32> <i32 0, i32 1, i32 2>
109 ; NON-POW2-NEXT:    store <3 x float> [[TMP1]], ptr [[P:%.*]], align 4
110 ; NON-POW2-NEXT:    ret void
112 ; POW2-ONLY-LABEL: @test_v4f32_v3f32_store(
113 ; POW2-ONLY-NEXT:    [[X2:%.*]] = extractelement <4 x float> [[F:%.*]], i64 2
114 ; POW2-ONLY-NEXT:    [[P2:%.*]] = getelementptr inbounds float, ptr [[P:%.*]], i64 2
115 ; POW2-ONLY-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[F]], <4 x float> poison, <2 x i32> <i32 0, i32 1>
116 ; POW2-ONLY-NEXT:    store <2 x float> [[TMP1]], ptr [[P]], align 4
117 ; POW2-ONLY-NEXT:    store float [[X2]], ptr [[P2]], align 4
118 ; POW2-ONLY-NEXT:    ret void
120   %x0 = extractelement <4 x float> %f, i64 0
121   %x1 = extractelement <4 x float> %f, i64 1
122   %x2 = extractelement <4 x float> %f, i64 2
123   %p1 = getelementptr inbounds float, ptr %p, i64 1
124   %p2 = getelementptr inbounds float, ptr %p, i64 2
125   store float %x0, ptr %p, align 4
126   store float %x1, ptr %p1, align 4
127   store float %x2, ptr %p2, align 4
128   ret void
131 define void @test_v4f32_v3f32_splat_store(<4 x float> %f, ptr %p){
132 ; CHECK-LABEL: @test_v4f32_v3f32_splat_store(
133 ; CHECK-NEXT:    [[X0:%.*]] = extractelement <4 x float> [[F:%.*]], i64 0
134 ; CHECK-NEXT:    [[P1:%.*]] = getelementptr inbounds float, ptr [[P:%.*]], i64 1
135 ; CHECK-NEXT:    [[P2:%.*]] = getelementptr inbounds float, ptr [[P]], i64 2
136 ; CHECK-NEXT:    store float [[X0]], ptr [[P]], align 4
137 ; CHECK-NEXT:    store float [[X0]], ptr [[P1]], align 4
138 ; CHECK-NEXT:    store float [[X0]], ptr [[P2]], align 4
139 ; CHECK-NEXT:    ret void
141   %x0 = extractelement <4 x float> %f, i64 0
142   %p1 = getelementptr inbounds float, ptr %p, i64 1
143   %p2 = getelementptr inbounds float, ptr %p, i64 2
144   store float %x0, ptr %p, align 4
145   store float %x0, ptr %p1, align 4
146   store float %x0, ptr %p2, align 4
147   ret void
150 define void @test_v4f32_v4f32_store(<4 x float> %f, ptr %p){
151 ; CHECK-LABEL: @test_v4f32_v4f32_store(
152 ; CHECK-NEXT:    store <4 x float> [[F:%.*]], ptr [[P:%.*]], align 4
153 ; CHECK-NEXT:    ret void
155   %x0 = extractelement <4 x float> %f, i64 0
156   %x1 = extractelement <4 x float> %f, i64 1
157   %x2 = extractelement <4 x float> %f, i64 2
158   %x3 = extractelement <4 x float> %f, i64 3
159   %p1 = getelementptr inbounds float, ptr %p, i64 1
160   %p2 = getelementptr inbounds float, ptr %p, i64 2
161   %p3 = getelementptr inbounds float, ptr %p, i64 3
162   store float %x0, ptr %p, align 4
163   store float %x1, ptr %p1, align 4
164   store float %x2, ptr %p2, align 4
165   store float %x3, ptr %p3, align 4
166   ret void
169 define void @test_v4f32_v4f32_splat_store(<4 x float> %f, ptr %p){
170 ; CHECK-LABEL: @test_v4f32_v4f32_splat_store(
171 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[F:%.*]], <4 x float> poison, <4 x i32> zeroinitializer
172 ; CHECK-NEXT:    store <4 x float> [[TMP1]], ptr [[P:%.*]], align 4
173 ; CHECK-NEXT:    ret void
175   %x0 = extractelement <4 x float> %f, i64 0
176   %p1 = getelementptr inbounds float, ptr %p, i64 1
177   %p2 = getelementptr inbounds float, ptr %p, i64 2
178   %p3 = getelementptr inbounds float, ptr %p, i64 3
179   store float %x0, ptr %p, align 4
180   store float %x0, ptr %p1, align 4
181   store float %x0, ptr %p2, align 4
182   store float %x0, ptr %p3, align 4
183   ret void