llvm.org GIT mirror llvm / 5f41fd6
PowerPC: More support for Altivec compare operations This patch adds more support for vector type comparisons using altivec. It adds correct support for v16i8, v8i16, v4i32, and v4f32 vector types for comparison operators ==, !=, >, >=, <, and <=. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167015 91177308-0d34-0410-b5e6-96231b3b80d8 Adhemerval Zanella 7 years ago
3 changed file(s) with 492 addition(s) and 28 deletion(s). Raw diff Collapse all Expand all
622622 }
623623 }
624624
625 // getVCmpInst: return the vector compare instruction for the specified
626 // vector type and condition code. Since this is for altivec specific code,
627 // only support the altivec types (v16i8, v8i16, v4i32, and v4f32).
628 static unsigned int getVCmpInst(MVT::SimpleValueType VecVT, ISD::CondCode CC) {
629 switch (CC) {
630 case ISD::SETEQ:
631 case ISD::SETUEQ:
632 case ISD::SETNE:
633 case ISD::SETUNE:
634 if (VecVT == MVT::v16i8)
635 return PPC::VCMPEQUB;
636 else if (VecVT == MVT::v8i16)
637 return PPC::VCMPEQUH;
638 else if (VecVT == MVT::v4i32)
639 return PPC::VCMPEQUW;
640 // v4f32 != v4f32 could be translate to unordered not equal
641 else if (VecVT == MVT::v4f32)
642 return PPC::VCMPEQFP;
643 break;
644 case ISD::SETLT:
645 case ISD::SETGT:
646 case ISD::SETLE:
647 case ISD::SETGE:
648 if (VecVT == MVT::v16i8)
649 return PPC::VCMPGTSB;
650 else if (VecVT == MVT::v8i16)
651 return PPC::VCMPGTSH;
652 else if (VecVT == MVT::v4i32)
653 return PPC::VCMPGTSW;
654 else if (VecVT == MVT::v4f32)
655 return PPC::VCMPGTFP;
656 break;
657 case ISD::SETULT:
658 case ISD::SETUGT:
659 case ISD::SETUGE:
660 case ISD::SETULE:
661 if (VecVT == MVT::v16i8)
662 return PPC::VCMPGTUB;
663 else if (VecVT == MVT::v8i16)
664 return PPC::VCMPGTUH;
665 else if (VecVT == MVT::v4i32)
666 return PPC::VCMPGTUW;
667 break;
668 case ISD::SETOEQ:
669 if (VecVT == MVT::v4f32)
670 return PPC::VCMPEQFP;
671 break;
672 case ISD::SETOLT:
673 case ISD::SETOGT:
674 case ISD::SETOLE:
675 if (VecVT == MVT::v4f32)
676 return PPC::VCMPGTFP;
677 break;
678 case ISD::SETOGE:
679 if (VecVT == MVT::v4f32)
680 return PPC::VCMPGEFP;
681 break;
682 default:
683 break;
684 }
685 llvm_unreachable("Invalid integer vector compare condition");
686 }
687
688 // getVCmpEQInst: return the equal compare instruction for the specified vector
689 // type. Since this is for altivec specific code, only support the altivec
690 // types (v16i8, v8i16, v4i32, and v4f32).
691 static unsigned int getVCmpEQInst(MVT::SimpleValueType VecVT) {
692 switch (VecVT) {
693 case MVT::v16i8:
694 return PPC::VCMPEQUB;
695 case MVT::v8i16:
696 return PPC::VCMPEQUH;
697 case MVT::v4i32:
698 return PPC::VCMPEQUW;
699 case MVT::v4f32:
700 return PPC::VCMPEQFP;
701 default:
702 llvm_unreachable("Invalid integer vector compare condition");
703 }
704 }
705
706
625707 SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
626708 DebugLoc dl = N->getDebugLoc();
627709 unsigned Imm;
705787 SDValue LHS = N->getOperand(0);
706788 SDValue RHS = N->getOperand(1);
707789
708 // Altivec Vector compare instructions do not set any CR register by default
790 // Altivec Vector compare instructions do not set any CR register by default and
791 // vector compare operations return the same type as the operands.
709792 if (LHS.getValueType().isVector()) {
710 unsigned int Opc;
711 if (LHS.getValueType() == MVT::v16i8)
712 Opc = PPC::VCMPEQUB;
713 else if (LHS.getValueType() == MVT::v4i32)
714 Opc = PPC::VCMPEQUW;
715 else if (LHS.getValueType() == MVT::v8i16)
716 Opc = PPC::VCMPEQUH;
717 else if (LHS.getValueType() == MVT::v4f32)
718 Opc = PPC::VCMPEQFP;
719 else
720 llvm_unreachable("Invalid vector compare type: should be expanded by legalize");
721 return CurDAG->SelectNodeTo(N, Opc, LHS.getValueType(), LHS, RHS);
793 EVT VecVT = LHS.getValueType();
794 MVT::SimpleValueType VT = VecVT.getSimpleVT().SimpleTy;
795 unsigned int VCmpInst = getVCmpInst(VT, CC);
796
797 switch (CC) {
798 case ISD::SETEQ:
799 case ISD::SETOEQ:
800 case ISD::SETUEQ:
801 return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, LHS, RHS);
802 case ISD::SETNE:
803 case ISD::SETONE:
804 case ISD::SETUNE: {
805 SDValue VCmp(CurDAG->getMachineNode(VCmpInst, dl, VecVT, LHS, RHS), 0);
806 return CurDAG->SelectNodeTo(N, PPC::VNOR, VecVT, VCmp, VCmp);
807 }
808 case ISD::SETLT:
809 case ISD::SETOLT:
810 case ISD::SETULT:
811 return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, RHS, LHS);
812 case ISD::SETGT:
813 case ISD::SETOGT:
814 case ISD::SETUGT:
815 return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, LHS, RHS);
816 case ISD::SETGE:
817 case ISD::SETOGE:
818 case ISD::SETUGE: {
819 // Small optimization: Altivec provides a 'Vector Compare Greater Than
820 // or Equal To' instruction (vcmpgefp), so in this case there is no
821 // need for extra logic for the equal compare.
822 if (VecVT.getSimpleVT().isFloatingPoint()) {
823 return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, LHS, RHS);
824 } else {
825 SDValue VCmpGT(CurDAG->getMachineNode(VCmpInst, dl, VecVT, LHS, RHS), 0);
826 unsigned int VCmpEQInst = getVCmpEQInst(VT);
827 SDValue VCmpEQ(CurDAG->getMachineNode(VCmpEQInst, dl, VecVT, LHS, RHS), 0);
828 return CurDAG->SelectNodeTo(N, PPC::VOR, VecVT, VCmpGT, VCmpEQ);
829 }
830 }
831 case ISD::SETLE:
832 case ISD::SETOLE:
833 case ISD::SETULE: {
834 SDValue VCmpLE(CurDAG->getMachineNode(VCmpInst, dl, VecVT, RHS, LHS), 0);
835 unsigned int VCmpEQInst = getVCmpEQInst(VT);
836 SDValue VCmpEQ(CurDAG->getMachineNode(VCmpEQInst, dl, VecVT, LHS, RHS), 0);
837 return CurDAG->SelectNodeTo(N, PPC::VOR, VecVT, VCmpLE, VCmpEQ);
838 }
839 default:
840 llvm_unreachable("Invalid vector compare type: should be expanded by legalize");
841 }
722842 }
723843
724844 bool Inv;
395395 setOperationAction(ISD::BUILD_VECTOR, MVT::v8i16, Custom);
396396 setOperationAction(ISD::BUILD_VECTOR, MVT::v4i32, Custom);
397397 setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Custom);
398
399 // Altivec does not contain unordered floating-point compare instructions
400 setCondCodeAction(ISD::SETUO, MVT::v4f32, Expand);
401 setCondCodeAction(ISD::SETUEQ, MVT::v4f32, Expand);
402 setCondCodeAction(ISD::SETUGT, MVT::v4f32, Expand);
403 setCondCodeAction(ISD::SETUGE, MVT::v4f32, Expand);
404 setCondCodeAction(ISD::SETULT, MVT::v4f32, Expand);
405 setCondCodeAction(ISD::SETULE, MVT::v4f32, Expand);
398406 }
399407
400408 if (Subtarget->has64BitSupport()) {
None ; RUN: llc -mattr=+altivec < %s | FileCheck %s
1
2 ; Check vector comparisons using altivec.
0 ; RUN: llc -mcpu=pwr6 -mattr=+altivec < %s | FileCheck %s
1
2 ; Check vector comparisons using altivec. For non native types, just basic
3 ; comparison instruction check is done. For altivec supported type (16i8,
4 ; 8i16, 4i32, and 4f32) all the comparisons operators (==, !=, >, >=, <, <=)
5 ; are checked.
36
47
58 target 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-v128:128:128-n32:64"
3235 ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
3336
3437
35 define <16 x i8> @v16si8_cmp(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
38 ; Adicional tests for v16i8 since it is a altivec native type
39
40 define <16 x i8> @v16si8_cmp_eq(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
3641 %cmp = icmp eq <16 x i8> %x, %y
3742 %sext = sext <16 x i1> %cmp to <16 x i8>
3843 ret <16 x i8> %sext
3944 }
40 ; CHECK: v16si8_cmp:
41 ; CHECK: vcmpequb {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
45 ; CHECK: v16si8_cmp_eq:
46 ; CHECK: vcmpequb 2, 2, 3
47
48 define <16 x i8> @v16si8_cmp_ne(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
49 entry:
50 %cmp = icmp ne <16 x i8> %x, %y
51 %sext = sext <16 x i1> %cmp to <16 x i8>
52 ret <16 x i8> %sext
53 }
54 ; CHECK: v16si8_cmp_ne:
55 ; CHECK: vcmpequb [[RET:[0-9]+]], 2, 3
56 ; CHECK-NOR: vnor 2, [[RET]], [[RET]]
57
58 define <16 x i8> @v16si8_cmp_le(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
59 entry:
60 %cmp = icmp sle <16 x i8> %x, %y
61 %sext = sext <16 x i1> %cmp to <16 x i8>
62 ret <16 x i8> %sext
63 }
64 ; CHECK: v16si8_cmp_le:
65 ; CHECK: vcmpequb [[RCMPEQ:[0-9]+]], 2, 3
66 ; CHECK-NEXT: vcmpgtsb [[RCMPLE:[0-9]+]], 3, 2
67 ; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
68
69 define <16 x i8> @v16ui8_cmp_le(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
70 entry:
71 %cmp = icmp ule <16 x i8> %x, %y
72 %sext = sext <16 x i1> %cmp to <16 x i8>
73 ret <16 x i8> %sext
74 }
75 ; CHECK: v16ui8_cmp_le:
76 ; CHECK: vcmpequb [[RCMPEQ:[0-9]+]], 2, 3
77 ; CHECK-NEXT: vcmpgtub [[RCMPLE:[0-9]+]], 3, 2
78 ; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
79
80 define <16 x i8> @v16si8_cmp_lt(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
81 entry:
82 %cmp = icmp slt <16 x i8> %x, %y
83 %sext = sext <16 x i1> %cmp to <16 x i8>
84 ret <16 x i8> %sext
85 }
86 ; CHECK: v16si8_cmp_lt:
87 ; CHECK: vcmpgtsb 2, 3, 2
88
89 define <16 x i8> @v16ui8_cmp_lt(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
90 entry:
91 %cmp = icmp ult <16 x i8> %x, %y
92 %sext = sext <16 x i1> %cmp to <16 x i8>
93 ret <16 x i8> %sext
94 }
95 ; CHECK: v16ui8_cmp_lt:
96 ; CHECK: vcmpgtub 2, 3, 2
97
98 define <16 x i8> @v16si8_cmp_gt(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
99 entry:
100 %cmp = icmp sgt <16 x i8> %x, %y
101 %sext = sext <16 x i1> %cmp to <16 x i8>
102 ret <16 x i8> %sext
103 }
104 ; CHECK: v16si8_cmp_gt:
105 ; CHECK: vcmpgtsb 2, 2, 3
106
107 define <16 x i8> @v16ui8_cmp_gt(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
108 entry:
109 %cmp = icmp ugt <16 x i8> %x, %y
110 %sext = sext <16 x i1> %cmp to <16 x i8>
111 ret <16 x i8> %sext
112 }
113 ; CHECK: v16ui8_cmp_gt:
114 ; CHECK: vcmpgtub 2, 2, 3
115
116 define <16 x i8> @v16si8_cmp_ge(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
117 entry:
118 %cmp = icmp sge <16 x i8> %x, %y
119 %sext = sext <16 x i1> %cmp to <16 x i8>
120 ret <16 x i8> %sext
121 }
122 ; CHECK: v16si8_cmp_ge:
123 ; CHECK: vcmpequb [[RCMPEQ:[0-9]+]], 2, 3
124 ; CHECK-NEXT: vcmpgtsb [[RCMPGT:[0-9]+]], 2, 3
125 ; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
126
127 define <16 x i8> @v16ui8_cmp_ge(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
128 entry:
129 %cmp = icmp uge <16 x i8> %x, %y
130 %sext = sext <16 x i1> %cmp to <16 x i8>
131 ret <16 x i8> %sext
132 }
133 ; CHECK: v16ui8_cmp_ge:
134 ; CHECK: vcmpequb [[RCMPEQ:[0-9]+]], 2, 3
135 ; CHECK-NEXT: vcmpgtub [[RCMPGT:[0-9]+]], 2, 3
136 ; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
42137
43138
44139 define <32 x i8> @v32si8_cmp(<32 x i8> %x, <32 x i8> %y) nounwind readnone {
69164 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
70165
71166
72 define <8 x i16> @v8si16_cmp(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
167 ; Adicional tests for v8i16 since it is an altivec native type
168
169 define <8 x i16> @v8si16_cmp_eq(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
170 entry:
73171 %cmp = icmp eq <8 x i16> %x, %y
74172 %sext = sext <8 x i1> %cmp to <8 x i16>
75173 ret <8 x i16> %sext
76174 }
77 ; CHECK: v8si16_cmp:
78 ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
175 ; CHECK: v8si16_cmp_eq:
176 ; CHECK: vcmpequh 2, 2, 3
177
178 define <8 x i16> @v8si16_cmp_ne(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
179 entry:
180 %cmp = icmp ne <8 x i16> %x, %y
181 %sext = sext <8 x i1> %cmp to <8 x i16>
182 ret <8 x i16> %sext
183 }
184 ; CHECK: v8si16_cmp_ne:
185 ; CHECK: vcmpequh [[RET:[0-9]+]], 2, 3
186 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
187
188 define <8 x i16> @v8si16_cmp_le(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
189 entry:
190 %cmp = icmp sle <8 x i16> %x, %y
191 %sext = sext <8 x i1> %cmp to <8 x i16>
192 ret <8 x i16> %sext
193 }
194 ; CHECK: v8si16_cmp_le:
195 ; CHECK: vcmpequh [[RCMPEQ:[0-9]+]], 2, 3
196 ; CHECK-NEXT: vcmpgtsh [[RCMPLE:[0-9]+]], 3, 2
197 ; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
198
199 define <8 x i16> @v8ui16_cmp_le(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
200 entry:
201 %cmp = icmp ule <8 x i16> %x, %y
202 %sext = sext <8 x i1> %cmp to <8 x i16>
203 ret <8 x i16> %sext
204 }
205 ; CHECK: v8ui16_cmp_le:
206 ; CHECK: vcmpequh [[RCMPEQ:[0-9]+]], 2, 3
207 ; CHECK-NEXT: vcmpgtuh [[RCMPLE:[0-9]+]], 3, 2
208 ; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
209
210 define <8 x i16> @v8si16_cmp_lt(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
211 entry:
212 %cmp = icmp slt <8 x i16> %x, %y
213 %sext = sext <8 x i1> %cmp to <8 x i16>
214 ret <8 x i16> %sext
215 }
216 ; CHECK: v8si16_cmp_lt:
217 ; CHECK: vcmpgtsh 2, 3, 2
218
219 define <8 x i16> @v8ui16_cmp_lt(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
220 entry:
221 %cmp = icmp ult <8 x i16> %x, %y
222 %sext = sext <8 x i1> %cmp to <8 x i16>
223 ret <8 x i16> %sext
224 }
225 ; CHECK: v8ui16_cmp_lt:
226 ; CHECK: vcmpgtuh 2, 3, 2
227
228 define <8 x i16> @v8si16_cmp_gt(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
229 entry:
230 %cmp = icmp sgt <8 x i16> %x, %y
231 %sext = sext <8 x i1> %cmp to <8 x i16>
232 ret <8 x i16> %sext
233 }
234 ; CHECK: v8si16_cmp_gt:
235 ; CHECK: vcmpgtsh 2, 2, 3
236
237 define <8 x i16> @v8ui16_cmp_gt(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
238 entry:
239 %cmp = icmp ugt <8 x i16> %x, %y
240 %sext = sext <8 x i1> %cmp to <8 x i16>
241 ret <8 x i16> %sext
242 }
243 ; CHECK: v8ui16_cmp_gt:
244 ; CHECK: vcmpgtuh 2, 2, 3
245
246 define <8 x i16> @v8si16_cmp_ge(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
247 entry:
248 %cmp = icmp sge <8 x i16> %x, %y
249 %sext = sext <8 x i1> %cmp to <8 x i16>
250 ret <8 x i16> %sext
251 }
252 ; CHECK: v8si16_cmp_ge:
253 ; CHECK: vcmpequh [[RCMPEQ:[0-9]+]], 2, 3
254 ; CHECK-NEXT: vcmpgtsh [[RCMPGT:[0-9]+]], 2, 3
255 ; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
256
257 define <8 x i16> @v8ui16_cmp_ge(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
258 entry:
259 %cmp = icmp uge <8 x i16> %x, %y
260 %sext = sext <8 x i1> %cmp to <8 x i16>
261 ret <8 x i16> %sext
262 }
263 ; CHECK: v8ui16_cmp_ge:
264 ; CHECK: vcmpequh [[RCMPEQ:[0-9]+]], 2, 3
265 ; CHECK-NEXT: vcmpgtuh [[RCMPGT:[0-9]+]], 2, 3
266 ; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
79267
80268
81269 define <16 x i16> @v16si16_cmp(<16 x i16> %x, <16 x i16> %y) nounwind readnone {
109297 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
110298
111299
112 define <4 x i32> @v4si32_cmp(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
300 ; Adicional tests for v4si32 since it is an altivec native type
301
302 define <4 x i32> @v4si32_cmp_eq(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
303 entry:
113304 %cmp = icmp eq <4 x i32> %x, %y
114305 %sext = sext <4 x i1> %cmp to <4 x i32>
115306 ret <4 x i32> %sext
116307 }
117 ; CHECK: v4si32_cmp:
118 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
308 ; CHECK: v4si32_cmp_eq:
309 ; CHECK: vcmpequw 2, 2, 3
310
311 define <4 x i32> @v4si32_cmp_ne(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
312 entry:
313 %cmp = icmp ne <4 x i32> %x, %y
314 %sext = sext <4 x i1> %cmp to <4 x i32>
315 ret <4 x i32> %sext
316 }
317 ; CHECK: v4si32_cmp_ne:
318 ; CHECK: vcmpequw [[RCMP:[0-9]+]], 2, 3
319 ; CHECK-NEXT: vnor 2, [[RCMP]], [[RCMP]]
320
321 define <4 x i32> @v4si32_cmp_le(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
322 entry:
323 %cmp = icmp sle <4 x i32> %x, %y
324 %sext = sext <4 x i1> %cmp to <4 x i32>
325 ret <4 x i32> %sext
326 }
327 ; CHECK: v4si32_cmp_le:
328 ; CHECK: vcmpequw [[RCMPEQ:[0-9]+]], 2, 3
329 ; CHECK-NEXT: vcmpgtsw [[RCMPLE:[0-9]+]], 3, 2
330 ; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
331
332 define <4 x i32> @v4ui32_cmp_le(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
333 entry:
334 %cmp = icmp ule <4 x i32> %x, %y
335 %sext = sext <4 x i1> %cmp to <4 x i32>
336 ret <4 x i32> %sext
337 }
338 ; CHECK: v4ui32_cmp_le:
339 ; CHECK: vcmpequw [[RCMPEQ:[0-9]+]], 2, 3
340 ; CHECK-NEXT: vcmpgtuw [[RCMPLE:[0-9]+]], 3, 2
341 ; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
342
343 define <4 x i32> @v4si32_cmp_lt(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
344 entry:
345 %cmp = icmp slt <4 x i32> %x, %y
346 %sext = sext <4 x i1> %cmp to <4 x i32>
347 ret <4 x i32> %sext
348 }
349 ; CHECK: v4si32_cmp_lt:
350 ; CHECK: vcmpgtsw 2, 3, 2
351
352 define <4 x i32> @v4ui32_cmp_lt(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
353 entry:
354 %cmp = icmp ult <4 x i32> %x, %y
355 %sext = sext <4 x i1> %cmp to <4 x i32>
356 ret <4 x i32> %sext
357 }
358 ; CHECK: v4ui32_cmp_lt:
359 ; CHECK: vcmpgtuw 2, 3, 2
360
361 define <4 x i32> @v4si32_cmp_gt(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
362 entry:
363 %cmp = icmp sgt <4 x i32> %x, %y
364 %sext = sext <4 x i1> %cmp to <4 x i32>
365 ret <4 x i32> %sext
366 }
367 ; CHECK: v4si32_cmp_gt:
368 ; CHECK: vcmpgtsw 2, 2, 3
369
370 define <4 x i32> @v4ui32_cmp_gt(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
371 entry:
372 %cmp = icmp ugt <4 x i32> %x, %y
373 %sext = sext <4 x i1> %cmp to <4 x i32>
374 ret <4 x i32> %sext
375 }
376 ; CHECK: v4ui32_cmp_gt:
377 ; CHECK: vcmpgtuw 2, 2, 3
378
379 define <4 x i32> @v4si32_cmp_ge(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
380 entry:
381 %cmp = icmp sge <4 x i32> %x, %y
382 %sext = sext <4 x i1> %cmp to <4 x i32>
383 ret <4 x i32> %sext
384 }
385 ; CHECK: v4si32_cmp_ge:
386 ; CHECK: vcmpequw [[RCMPEQ:[0-9]+]], 2, 3
387 ; CHECK-NEXT: vcmpgtsw [[RCMPGT:[0-9]+]], 2, 3
388 ; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
389
390 define <4 x i32> @v4ui32_cmp_ge(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
391 entry:
392 %cmp = icmp uge <4 x i32> %x, %y
393 %sext = sext <4 x i1> %cmp to <4 x i32>
394 ret <4 x i32> %sext
395 }
396 ; CHECK: v4ui32_cmp_ge:
397 ; CHECK: vcmpequw [[RCMPEQ:[0-9]+]], 2, 3
398 ; CHECK-NEXT: vcmpgtuw [[RCMPGT:[0-9]+]], 2, 3
399 ; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
119400
120401
121402 define <8 x i32> @v8si32_cmp(<8 x i32> %x, <8 x i32> %y) nounwind readnone {
167448 ; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
168449
169450
170 define <4 x float> @v4f32_cmp(<4 x float> %x, <4 x float> %y) nounwind readnone {
451 ; Adicional tests for v4f32 since it is a altivec native type
452
453 define <4 x float> @v4f32_cmp_eq(<4 x float> %x, <4 x float> %y) nounwind readnone {
171454 entry:
172455 %cmp = fcmp oeq <4 x float> %x, %y
173456 %sext = sext <4 x i1> %cmp to <4 x i32>
174457 %0 = bitcast <4 x i32> %sext to <4 x float>
175458 ret <4 x float> %0
176459 }
177 ; CHECK: v4f32_cmp:
178 ; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
460 ; CHECK: v4f32_cmp_eq:
461 ; CHECK: vcmpeqfp 2, 2, 3
462
463 define <4 x float> @v4f32_cmp_ne(<4 x float> %x, <4 x float> %y) nounwind readnone {
464 entry:
465 %cmp = fcmp une <4 x float> %x, %y
466 %sext = sext <4 x i1> %cmp to <4 x i32>
467 %0 = bitcast <4 x i32> %sext to <4 x float>
468 ret <4 x float> %0
469 }
470 ; CHECK: v4f32_cmp_ne:
471 ; CHECK: vcmpeqfp [[RET:[0-9]+]], 2, 3
472 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
473
474 define <4 x float> @v4f32_cmp_le(<4 x float> %x, <4 x float> %y) nounwind readnone {
475 entry:
476 %cmp = fcmp ole <4 x float> %x, %y
477 %sext = sext <4 x i1> %cmp to <4 x i32>
478 %0 = bitcast <4 x i32> %sext to <4 x float>
479 ret <4 x float> %0
480 }
481 ; CHECK: v4f32_cmp_le:
482 ; CHECK: vcmpeqfp [[RCMPEQ:[0-9]+]], 2, 3
483 ; CHECK-NEXT: vcmpgtfp [[RCMPLE:[0-9]+]], 3, 2
484 ; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
485
486 define <4 x float> @v4f32_cmp_lt(<4 x float> %x, <4 x float> %y) nounwind readnone {
487 entry:
488 %cmp = fcmp olt <4 x float> %x, %y
489 %sext = sext <4 x i1> %cmp to <4 x i32>
490 %0 = bitcast <4 x i32> %sext to <4 x float>
491 ret <4 x float> %0
492 }
493 ; CHECK: v4f32_cmp_lt:
494 ; CHECK: vcmpgtfp 2, 3, 2
495
496 define <4 x float> @v4f32_cmp_ge(<4 x float> %x, <4 x float> %y) nounwind readnone {
497 entry:
498 %cmp = fcmp oge <4 x float> %x, %y
499 %sext = sext <4 x i1> %cmp to <4 x i32>
500 %0 = bitcast <4 x i32> %sext to <4 x float>
501 ret <4 x float> %0
502 }
503 ; CHECK: v4f32_cmp_ge:
504 ; CHECK: vcmpgefp 2, 2, 3
505
506 define <4 x float> @v4f32_cmp_gt(<4 x float> %x, <4 x float> %y) nounwind readnone {
507 entry:
508 %cmp = fcmp ogt <4 x float> %x, %y
509 %sext = sext <4 x i1> %cmp to <4 x i32>
510 %0 = bitcast <4 x i32> %sext to <4 x float>
511 ret <4 x float> %0
512 }
513 ; CHECK: v4f32_cmp_gt:
514 ; CHECK: vcmpgtfp 2, 2, 3
179515
180516
181517 define <8 x float> @v8f32_cmp(<8 x float> %x, <8 x float> %y) nounwind readnone {