1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=slp-vectorizer,dce -S -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck %s
4 ;int foo(char * restrict A, ptr restrict B, float T) {
5 ; A[0] = (T * B[10] + 4.0);
6 ; A[1] = (T * B[11] + 5.0);
7 ; A[2] = (T * B[12] + 6.0);
10 define i32 @foo(ptr noalias nocapture %A, ptr noalias nocapture %B, float %T) {
12 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds float, ptr [[B:%.*]], i64 10
13 ; CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[TMP1]], align 4
14 ; CHECK-NEXT: [[TMP3:%.*]] = fmul float [[TMP2]], [[T:%.*]]
15 ; CHECK-NEXT: [[TMP4:%.*]] = fpext float [[TMP3]] to double
16 ; CHECK-NEXT: [[TMP5:%.*]] = fadd double [[TMP4]], 4.000000e+00
17 ; CHECK-NEXT: [[TMP6:%.*]] = fptosi double [[TMP5]] to i8
18 ; CHECK-NEXT: store i8 [[TMP6]], ptr [[A:%.*]], align 1
19 ; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds float, ptr [[B]], i64 11
20 ; CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[TMP7]], align 4
21 ; CHECK-NEXT: [[TMP9:%.*]] = fmul float [[TMP8]], [[T]]
22 ; CHECK-NEXT: [[TMP10:%.*]] = fpext float [[TMP9]] to double
23 ; CHECK-NEXT: [[TMP11:%.*]] = fadd double [[TMP10]], 5.000000e+00
24 ; CHECK-NEXT: [[TMP12:%.*]] = fptosi double [[TMP11]] to i8
25 ; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 1
26 ; CHECK-NEXT: store i8 [[TMP12]], ptr [[TMP13]], align 1
27 ; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds float, ptr [[B]], i64 12
28 ; CHECK-NEXT: [[TMP15:%.*]] = load float, ptr [[TMP14]], align 4
29 ; CHECK-NEXT: [[TMP16:%.*]] = fmul float [[TMP15]], [[T]]
30 ; CHECK-NEXT: [[TMP17:%.*]] = fpext float [[TMP16]] to double
31 ; CHECK-NEXT: [[TMP18:%.*]] = fadd double [[TMP17]], 6.000000e+00
32 ; CHECK-NEXT: [[TMP19:%.*]] = fptosi double [[TMP18]] to i8
33 ; CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 2
34 ; CHECK-NEXT: store i8 [[TMP19]], ptr [[TMP20]], align 1
35 ; CHECK-NEXT: ret i32 undef
37 %1 = getelementptr inbounds float, ptr %B, i64 10
38 %2 = load float, ptr %1, align 4
39 %3 = fmul float %2, %T
40 %4 = fpext float %3 to double
41 %5 = fadd double %4, 4.000000e+00
42 %6 = fptosi double %5 to i8
43 store i8 %6, ptr %A, align 1
44 %7 = getelementptr inbounds float, ptr %B, i64 11
45 %8 = load float, ptr %7, align 4
46 %9 = fmul float %8, %T
47 %10 = fpext float %9 to double
48 %11 = fadd double %10, 5.000000e+00
49 %12 = fptosi double %11 to i8
50 %13 = getelementptr inbounds i8, ptr %A, i64 1
51 store i8 %12, ptr %13, align 1
52 %14 = getelementptr inbounds float, ptr %B, i64 12
53 %15 = load float, ptr %14, align 4
54 %16 = fmul float %15, %T
55 %17 = fpext float %16 to double
56 %18 = fadd double %17, 6.000000e+00
57 %19 = fptosi double %18 to i8
58 %20 = getelementptr inbounds i8, ptr %A, i64 2
59 store i8 %19, ptr %20, align 1
64 define void @test_v4f32_v2f32_store(<4 x float> %f, ptr %p){
65 ; CHECK-LABEL: @test_v4f32_v2f32_store(
66 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x float> [[F:%.*]], <4 x float> poison, <2 x i32> <i32 0, i32 1>
67 ; CHECK-NEXT: store <2 x float> [[TMP1]], ptr [[P:%.*]], align 4
68 ; CHECK-NEXT: ret void
70 %x0 = extractelement <4 x float> %f, i64 0
71 %x1 = extractelement <4 x float> %f, i64 1
72 %p1 = getelementptr inbounds float, ptr %p, i64 1
73 store float %x0, ptr %p, align 4
74 store float %x1, ptr %p1, align 4
78 define void @test_v4f32_v2f32_splat_store(<4 x float> %f, ptr %p){
79 ; CHECK-LABEL: @test_v4f32_v2f32_splat_store(
80 ; CHECK-NEXT: [[X0:%.*]] = extractelement <4 x float> [[F:%.*]], i64 0
81 ; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float, ptr [[P:%.*]], i64 1
82 ; CHECK-NEXT: store float [[X0]], ptr [[P]], align 4
83 ; CHECK-NEXT: store float [[X0]], ptr [[P1]], align 4
84 ; CHECK-NEXT: ret void
86 %x0 = extractelement <4 x float> %f, i64 0
87 %p1 = getelementptr inbounds float, ptr %p, i64 1
88 store float %x0, ptr %p, align 4
89 store float %x0, ptr %p1, align 4
93 define void @test_v4f32_v3f32_store(<4 x float> %f, ptr %p){
94 ; CHECK-LABEL: @test_v4f32_v3f32_store(
95 ; CHECK-NEXT: [[X2:%.*]] = extractelement <4 x float> [[F:%.*]], i64 2
96 ; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds float, ptr [[P:%.*]], i64 2
97 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x float> [[F]], <4 x float> poison, <2 x i32> <i32 0, i32 1>
98 ; CHECK-NEXT: store <2 x float> [[TMP1]], ptr [[P]], align 4
99 ; CHECK-NEXT: store float [[X2]], ptr [[P2]], align 4
100 ; CHECK-NEXT: ret void
102 %x0 = extractelement <4 x float> %f, i64 0
103 %x1 = extractelement <4 x float> %f, i64 1
104 %x2 = extractelement <4 x float> %f, i64 2
105 %p1 = getelementptr inbounds float, ptr %p, i64 1
106 %p2 = getelementptr inbounds float, ptr %p, i64 2
107 store float %x0, ptr %p, align 4
108 store float %x1, ptr %p1, align 4
109 store float %x2, ptr %p2, align 4
113 define void @test_v4f32_v3f32_splat_store(<4 x float> %f, ptr %p){
114 ; CHECK-LABEL: @test_v4f32_v3f32_splat_store(
115 ; CHECK-NEXT: [[X0:%.*]] = extractelement <4 x float> [[F:%.*]], i64 0
116 ; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float, ptr [[P:%.*]], i64 1
117 ; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds float, ptr [[P]], i64 2
118 ; CHECK-NEXT: store float [[X0]], ptr [[P]], align 4
119 ; CHECK-NEXT: store float [[X0]], ptr [[P1]], align 4
120 ; CHECK-NEXT: store float [[X0]], ptr [[P2]], align 4
121 ; CHECK-NEXT: ret void
123 %x0 = extractelement <4 x float> %f, i64 0
124 %p1 = getelementptr inbounds float, ptr %p, i64 1
125 %p2 = getelementptr inbounds float, ptr %p, i64 2
126 store float %x0, ptr %p, align 4
127 store float %x0, ptr %p1, align 4
128 store float %x0, ptr %p2, align 4
132 define void @test_v4f32_v4f32_store(<4 x float> %f, ptr %p){
133 ; CHECK-LABEL: @test_v4f32_v4f32_store(
134 ; CHECK-NEXT: store <4 x float> [[F:%.*]], ptr [[P:%.*]], align 4
135 ; CHECK-NEXT: ret void
137 %x0 = extractelement <4 x float> %f, i64 0
138 %x1 = extractelement <4 x float> %f, i64 1
139 %x2 = extractelement <4 x float> %f, i64 2
140 %x3 = extractelement <4 x float> %f, i64 3
141 %p1 = getelementptr inbounds float, ptr %p, i64 1
142 %p2 = getelementptr inbounds float, ptr %p, i64 2
143 %p3 = getelementptr inbounds float, ptr %p, i64 3
144 store float %x0, ptr %p, align 4
145 store float %x1, ptr %p1, align 4
146 store float %x2, ptr %p2, align 4
147 store float %x3, ptr %p3, align 4
151 define void @test_v4f32_v4f32_splat_store(<4 x float> %f, ptr %p){
152 ; CHECK-LABEL: @test_v4f32_v4f32_splat_store(
153 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x float> [[F:%.*]], <4 x float> poison, <4 x i32> zeroinitializer
154 ; CHECK-NEXT: store <4 x float> [[TMP1]], ptr [[P:%.*]], align 4
155 ; CHECK-NEXT: ret void
157 %x0 = extractelement <4 x float> %f, i64 0
158 %p1 = getelementptr inbounds float, ptr %p, i64 1
159 %p2 = getelementptr inbounds float, ptr %p, i64 2
160 %p3 = getelementptr inbounds float, ptr %p, i64 3
161 store float %x0, ptr %p, align 4
162 store float %x0, ptr %p1, align 4
163 store float %x0, ptr %p2, align 4
164 store float %x0, ptr %p3, align 4