6469786d879d721508cb5bac443df5447d2989cb
[oota-llvm.git] / test / CodeGen / X86 / splat-for-size.ll
1 ; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=avx < %s | FileCheck %s -check-prefix=CHECK --check-prefix=AVX
2 ; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=avx2 < %s | FileCheck %s -check-prefix=CHECK --check-prefix=AVX2
3
4 ; Check constant loads of every 128-bit and 256-bit vector type 
5 ; for size optimization using splat ops available with AVX and AVX2.
6
7 ; There is no AVX broadcast from double to 128-bit vector because movddup has been around since SSE3 (grrr).
8 define <2 x double> @splat_v2f64(<2 x double> %x) #0 {
9   %add = fadd <2 x double> %x, <double 1.0, double 1.0>
10   ret <2 x double> %add
11 ; CHECK-LABEL: splat_v2f64
12 ; CHECK: vmovddup
13 ; CHECK: vaddpd 
14 ; CHECK-NEXT: retq
15 }
16
17 define <4 x double> @splat_v4f64(<4 x double> %x) #1 {
18   %add = fadd <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
19   ret <4 x double> %add
20 ; CHECK-LABEL: splat_v4f64
21 ; CHECK: vbroadcastsd 
22 ; CHECK-NEXT: vaddpd
23 ; CHECK-NEXT: retq
24 }
25
26 define <4 x float> @splat_v4f32(<4 x float> %x) #0 {
27   %add = fadd <4 x float> %x, <float 1.0, float 1.0, float 1.0, float 1.0>
28   ret <4 x float> %add
29 ; CHECK-LABEL: splat_v4f32
30 ; CHECK: vbroadcastss 
31 ; CHECK-NEXT: vaddps
32 ; CHECK-NEXT: retq
33 }
34
35 define <8 x float> @splat_v8f32(<8 x float> %x) #1 {
36   %add = fadd <8 x float> %x, <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>
37   ret <8 x float> %add
38 ; CHECK-LABEL: splat_v8f32
39 ; CHECK: vbroadcastss 
40 ; CHECK-NEXT: vaddps
41 ; CHECK-NEXT: retq
42 }
43
44 ; AVX can't do integer splats, so fake it: use vmovddup to splat 64-bit value.
45 ; We also generate vmovddup for AVX2 because it's one byte smaller than vpbroadcastq.
46 define <2 x i64> @splat_v2i64(<2 x i64> %x) #1 {
47   %add = add <2 x i64> %x, <i64 1, i64 1>
48   ret <2 x i64> %add
49 ; CHECK-LABEL: splat_v2i64
50 ; CHECK: vmovddup 
51 ; CHECK: vpaddq
52 ; CHECK-NEXT: retq
53 }
54
55 ; AVX can't do 256-bit integer ops, so we split this into two 128-bit vectors,
56 ; and then we fake it: use vmovddup to splat 64-bit value.
57 define <4 x i64> @splat_v4i64(<4 x i64> %x) #0 {
58   %add = add <4 x i64> %x, <i64 1, i64 1, i64 1, i64 1>
59   ret <4 x i64> %add
60 ; CHECK-LABEL: splat_v4i64
61 ; AVX: vmovddup
62 ; AVX: vpaddq 
63 ; AVX: vpaddq 
64 ; AVX2: vpbroadcastq 
65 ; AVX2: vpaddq 
66 ; CHECK: retq
67 }
68
69 ; AVX can't do integer splats, so fake it: use vbroadcastss to splat 32-bit value.
70 define <4 x i32> @splat_v4i32(<4 x i32> %x) #1 {
71   %add = add <4 x i32> %x, <i32 1, i32 1, i32 1, i32 1>
72   ret <4 x i32> %add
73 ; CHECK-LABEL: splat_v4i32
74 ; AVX: vbroadcastss
75 ; AVX2: vpbroadcastd 
76 ; CHECK-NEXT: vpaddd 
77 ; CHECK-NEXT: retq
78 }
79
80 ; AVX can't do integer splats, so fake it: use vbroadcastss to splat 32-bit value.
81 define <8 x i32> @splat_v8i32(<8 x i32> %x) #0 {
82   %add = add <8 x i32> %x, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
83   ret <8 x i32> %add
84 ; CHECK-LABEL: splat_v8i32
85 ; AVX: vbroadcastss
86 ; AVX: vpaddd 
87 ; AVX: vpaddd 
88 ; AVX2: vpbroadcastd 
89 ; AVX2: vpaddd 
90 ; CHECK: retq
91 }
92
93 ; AVX can't do integer splats, and there's no broadcast fakery for 16-bit. Could use pshuflw, etc?
94 define <8 x i16> @splat_v8i16(<8 x i16> %x) #1 {
95   %add = add <8 x i16> %x, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
96   ret <8 x i16> %add
97 ; CHECK-LABEL: splat_v8i16
98 ; AVX-NOT: broadcast
99 ; AVX2: vpbroadcastw 
100 ; CHECK: vpaddw 
101 ; CHECK-NEXT: retq
102 }
103
104 ; AVX can't do integer splats, and there's no broadcast fakery for 16-bit. Could use pshuflw, etc?
105 define <16 x i16> @splat_v16i16(<16 x i16> %x) #0 {
106   %add = add <16 x i16> %x, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
107   ret <16 x i16> %add
108 ; CHECK-LABEL: splat_v16i16
109 ; AVX-NOT: broadcast
110 ; AVX: vpaddw 
111 ; AVX: vpaddw 
112 ; AVX2: vpbroadcastw 
113 ; AVX2: vpaddw 
114 ; CHECK: retq
115 }
116
117 ; AVX can't do integer splats, and there's no broadcast fakery for 8-bit. Could use pshufb, etc?
118 define <16 x i8> @splat_v16i8(<16 x i8> %x) #1 {
119   %add = add <16 x i8> %x, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
120   ret <16 x i8> %add
121 ; CHECK-LABEL: splat_v16i8
122 ; AVX-NOT: broadcast
123 ; AVX2: vpbroadcastb 
124 ; CHECK: vpaddb 
125 ; CHECK-NEXT: retq
126 }
127
128 ; AVX can't do integer splats, and there's no broadcast fakery for 8-bit. Could use pshufb, etc?
129 define <32 x i8> @splat_v32i8(<32 x i8> %x) #0 {
130   %add = add <32 x i8> %x, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
131   ret <32 x i8> %add
132 ; CHECK-LABEL: splat_v32i8
133 ; AVX-NOT: broadcast
134 ; AVX: vpaddb 
135 ; AVX: vpaddb 
136 ; AVX2: vpbroadcastb 
137 ; AVX2: vpaddb 
138 ; CHECK: retq
139 }
140
141 ; PR23259: Verify that ISel doesn't crash with a 'fatal error in backend'
142 ; due to a missing AVX pattern to select a v2i64 X86ISD::BROADCAST of a
143 ; loadi64 with multiple uses.
144
145 @A = common global <3 x i64> zeroinitializer, align 32
146
147 define <8 x i64> @pr23259() #1 {
148 entry:
149   %0 = load <4 x i64>, <4 x i64>* bitcast (<3 x i64>* @A to <4 x i64>*), align 32
150   %1 = shufflevector <4 x i64> %0, <4 x i64> undef, <3 x i32> <i32 undef, i32 undef, i32 2>
151   %shuffle = shufflevector <3 x i64> <i64 1, i64 undef, i64 undef>, <3 x i64> %1, <8 x i32> <i32 5, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
152   ret <8 x i64> %shuffle
153 }
154
155 attributes #0 = { optsize }
156 attributes #1 = { minsize }