1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=sse2 | FileCheck %s --check-prefixes=CHECK,SSE
3 ; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=avx2 | FileCheck %s --check-prefixes=CHECK,AVX
5 define i1 @fcmp_and_v2f64(<2 x double> %a) {
6 ; SSE-LABEL: @fcmp_and_v2f64(
7 ; SSE-NEXT: [[E1:%.*]] = extractelement <2 x double> [[A:%.*]], i32 0
8 ; SSE-NEXT: [[E2:%.*]] = extractelement <2 x double> [[A]], i32 1
9 ; SSE-NEXT: [[CMP1:%.*]] = fcmp olt double [[E1]], 4.200000e+01
10 ; SSE-NEXT: [[CMP2:%.*]] = fcmp olt double [[E2]], -8.000000e+00
11 ; SSE-NEXT: [[R:%.*]] = and i1 [[CMP1]], [[CMP2]]
12 ; SSE-NEXT: ret i1 [[R]]
14 ; AVX-LABEL: @fcmp_and_v2f64(
15 ; AVX-NEXT: [[TMP1:%.*]] = fcmp olt <2 x double> [[A:%.*]], <double 4.200000e+01, double -8.000000e+00>
16 ; AVX-NEXT: [[SHIFT:%.*]] = shufflevector <2 x i1> [[TMP1]], <2 x i1> poison, <2 x i32> <i32 1, i32 undef>
17 ; AVX-NEXT: [[TMP2:%.*]] = and <2 x i1> [[TMP1]], [[SHIFT]]
18 ; AVX-NEXT: [[R:%.*]] = extractelement <2 x i1> [[TMP2]], i64 0
19 ; AVX-NEXT: ret i1 [[R]]
21 %e1 = extractelement <2 x double> %a, i32 0
22 %e2 = extractelement <2 x double> %a, i32 1
23 %cmp1 = fcmp olt double %e1, 42.0
24 %cmp2 = fcmp olt double %e2, -8.0
25 %r = and i1 %cmp1, %cmp2
29 define i1 @fcmp_or_v4f64(<4 x double> %a) {
30 ; SSE-LABEL: @fcmp_or_v4f64(
31 ; SSE-NEXT: [[E1:%.*]] = extractelement <4 x double> [[A:%.*]], i32 0
32 ; SSE-NEXT: [[E2:%.*]] = extractelement <4 x double> [[A]], i64 2
33 ; SSE-NEXT: [[CMP1:%.*]] = fcmp olt double [[E1]], 4.200000e+01
34 ; SSE-NEXT: [[CMP2:%.*]] = fcmp olt double [[E2]], -8.000000e+00
35 ; SSE-NEXT: [[R:%.*]] = or i1 [[CMP1]], [[CMP2]]
36 ; SSE-NEXT: ret i1 [[R]]
38 ; AVX-LABEL: @fcmp_or_v4f64(
39 ; AVX-NEXT: [[TMP1:%.*]] = fcmp olt <4 x double> [[A:%.*]], <double 4.200000e+01, double undef, double -8.000000e+00, double undef>
40 ; AVX-NEXT: [[SHIFT:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> poison, <4 x i32> <i32 2, i32 undef, i32 undef, i32 undef>
41 ; AVX-NEXT: [[TMP2:%.*]] = or <4 x i1> [[TMP1]], [[SHIFT]]
42 ; AVX-NEXT: [[R:%.*]] = extractelement <4 x i1> [[TMP2]], i64 0
43 ; AVX-NEXT: ret i1 [[R]]
45 %e1 = extractelement <4 x double> %a, i32 0
46 %e2 = extractelement <4 x double> %a, i64 2
47 %cmp1 = fcmp olt double %e1, 42.0
48 %cmp2 = fcmp olt double %e2, -8.0
49 %r = or i1 %cmp1, %cmp2
53 define i1 @icmp_xor_v4i32(<4 x i32> %a) {
54 ; CHECK-LABEL: @icmp_xor_v4i32(
55 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[A:%.*]], <i32 undef, i32 -8, i32 undef, i32 42>
56 ; CHECK-NEXT: [[SHIFT:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> poison, <4 x i32> <i32 undef, i32 3, i32 undef, i32 undef>
57 ; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i1> [[TMP1]], [[SHIFT]]
58 ; CHECK-NEXT: [[R:%.*]] = extractelement <4 x i1> [[TMP2]], i64 1
59 ; CHECK-NEXT: ret i1 [[R]]
61 %e1 = extractelement <4 x i32> %a, i32 3
62 %e2 = extractelement <4 x i32> %a, i32 1
63 %cmp1 = icmp sgt i32 %e1, 42
64 %cmp2 = icmp sgt i32 %e2, -8
65 %r = xor i1 %cmp1, %cmp2
69 ; add is not canonical (should be xor), but that is ok.
71 define i1 @icmp_add_v8i32(<8 x i32> %a) {
72 ; SSE-LABEL: @icmp_add_v8i32(
73 ; SSE-NEXT: [[E1:%.*]] = extractelement <8 x i32> [[A:%.*]], i32 7
74 ; SSE-NEXT: [[E2:%.*]] = extractelement <8 x i32> [[A]], i32 2
75 ; SSE-NEXT: [[CMP1:%.*]] = icmp eq i32 [[E1]], 42
76 ; SSE-NEXT: [[CMP2:%.*]] = icmp eq i32 [[E2]], -8
77 ; SSE-NEXT: [[R:%.*]] = add i1 [[CMP1]], [[CMP2]]
78 ; SSE-NEXT: ret i1 [[R]]
80 ; AVX-LABEL: @icmp_add_v8i32(
81 ; AVX-NEXT: [[TMP1:%.*]] = icmp eq <8 x i32> [[A:%.*]], <i32 undef, i32 undef, i32 -8, i32 undef, i32 undef, i32 undef, i32 undef, i32 42>
82 ; AVX-NEXT: [[SHIFT:%.*]] = shufflevector <8 x i1> [[TMP1]], <8 x i1> poison, <8 x i32> <i32 undef, i32 undef, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
83 ; AVX-NEXT: [[TMP2:%.*]] = add <8 x i1> [[TMP1]], [[SHIFT]]
84 ; AVX-NEXT: [[R:%.*]] = extractelement <8 x i1> [[TMP2]], i64 2
85 ; AVX-NEXT: ret i1 [[R]]
87 %e1 = extractelement <8 x i32> %a, i32 7
88 %e2 = extractelement <8 x i32> %a, i32 2
89 %cmp1 = icmp eq i32 %e1, 42
90 %cmp2 = icmp eq i32 %e2, -8
91 %r = add i1 %cmp1, %cmp2
95 ; Negative test - this could CSE/simplify.
97 define i1 @same_extract_index(<4 x i32> %a) {
98 ; CHECK-LABEL: @same_extract_index(
99 ; CHECK-NEXT: [[E1:%.*]] = extractelement <4 x i32> [[A:%.*]], i32 2
100 ; CHECK-NEXT: [[E2:%.*]] = extractelement <4 x i32> [[A]], i32 2
101 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[E1]], 42
102 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[E2]], -8
103 ; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP1]], [[CMP2]]
104 ; CHECK-NEXT: ret i1 [[R]]
106 %e1 = extractelement <4 x i32> %a, i32 2
107 %e2 = extractelement <4 x i32> %a, i32 2
108 %cmp1 = icmp ugt i32 %e1, 42
109 %cmp2 = icmp ugt i32 %e2, -8
110 %r = and i1 %cmp1, %cmp2
114 ; Negative test - need identical predicates.
116 define i1 @different_preds(<4 x i32> %a) {
117 ; CHECK-LABEL: @different_preds(
118 ; CHECK-NEXT: [[E1:%.*]] = extractelement <4 x i32> [[A:%.*]], i32 1
119 ; CHECK-NEXT: [[E2:%.*]] = extractelement <4 x i32> [[A]], i32 2
120 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[E1]], 42
121 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[E2]], -8
122 ; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP1]], [[CMP2]]
123 ; CHECK-NEXT: ret i1 [[R]]
125 %e1 = extractelement <4 x i32> %a, i32 1
126 %e2 = extractelement <4 x i32> %a, i32 2
127 %cmp1 = icmp sgt i32 %e1, 42
128 %cmp2 = icmp ugt i32 %e2, -8
129 %r = and i1 %cmp1, %cmp2
133 ; Negative test - need 1 source vector.
135 define i1 @different_source_vec(<4 x i32> %a, <4 x i32> %b) {
136 ; CHECK-LABEL: @different_source_vec(
137 ; CHECK-NEXT: [[E1:%.*]] = extractelement <4 x i32> [[A:%.*]], i32 1
138 ; CHECK-NEXT: [[E2:%.*]] = extractelement <4 x i32> [[B:%.*]], i32 2
139 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[E1]], 42
140 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[E2]], -8
141 ; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP1]], [[CMP2]]
142 ; CHECK-NEXT: ret i1 [[R]]
144 %e1 = extractelement <4 x i32> %a, i32 1
145 %e2 = extractelement <4 x i32> %b, i32 2
146 %cmp1 = icmp sgt i32 %e1, 42
147 %cmp2 = icmp sgt i32 %e2, -8
148 %r = and i1 %cmp1, %cmp2