llvm.org GIT mirror llvm / 39f807f
Merging r214714: ------------------------------------------------------------------------ r214714 | uweigand | 2014-08-04 08:13:57 -0500 (Mon, 04 Aug 2014) | 19 lines [PowerPC] Fix and improve vector comparisons This patch refactors code generation of vector comparisons. This fixes a wrong code-gen bug for ISD::SETGE for floating-point types, and improves generated code for vector comparisons in general. Specifically, the patch moves all logic deciding how to implement vector comparisons into getVCmpInst, which gets two extra boolean outputs indicating to its caller whether its needs to swap the input operands and/or negate the result of the comparison. Apart from implementing these two modifications as directed by getVCmpInst, there is no need to ever implement vector comparisons in any other manner; in particular, there is never a need to perform two separate comparisons (e.g. one for equal and one for greater-than, as code used to do before this patch). Reviewed by Bill Schmidt. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@214817 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Schmidt 5 years ago
3 changed file(s) with 182 addition(s) and 191 deletion(s). Raw diff Collapse all Expand all
662662 // getVCmpInst: return the vector compare instruction for the specified
663663 // vector type and condition code. Since this is for altivec specific code,
664664 // only support the altivec types (v16i8, v8i16, v4i32, and v4f32).
665 static unsigned int getVCmpInst(MVT::SimpleValueType VecVT, ISD::CondCode CC,
666 bool HasVSX) {
667 switch (CC) {
668 case ISD::SETEQ:
669 case ISD::SETUEQ:
670 case ISD::SETNE:
671 case ISD::SETUNE:
672 if (VecVT == MVT::v16i8)
673 return PPC::VCMPEQUB;
674 else if (VecVT == MVT::v8i16)
675 return PPC::VCMPEQUH;
676 else if (VecVT == MVT::v4i32)
677 return PPC::VCMPEQUW;
678 // v4f32 != v4f32 could be translate to unordered not equal
679 else if (VecVT == MVT::v4f32)
680 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
681 else if (VecVT == MVT::v2f64)
682 return PPC::XVCMPEQDP;
683 break;
684 case ISD::SETLT:
685 case ISD::SETGT:
686 case ISD::SETLE:
687 case ISD::SETGE:
688 if (VecVT == MVT::v16i8)
689 return PPC::VCMPGTSB;
690 else if (VecVT == MVT::v8i16)
691 return PPC::VCMPGTSH;
692 else if (VecVT == MVT::v4i32)
693 return PPC::VCMPGTSW;
694 else if (VecVT == MVT::v4f32)
695 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
696 else if (VecVT == MVT::v2f64)
697 return PPC::XVCMPGTDP;
698 break;
699 case ISD::SETULT:
700 case ISD::SETUGT:
701 case ISD::SETUGE:
702 case ISD::SETULE:
703 if (VecVT == MVT::v16i8)
704 return PPC::VCMPGTUB;
705 else if (VecVT == MVT::v8i16)
706 return PPC::VCMPGTUH;
707 else if (VecVT == MVT::v4i32)
708 return PPC::VCMPGTUW;
709 break;
710 case ISD::SETOEQ:
711 if (VecVT == MVT::v4f32)
712 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
713 else if (VecVT == MVT::v2f64)
714 return PPC::XVCMPEQDP;
715 break;
716 case ISD::SETOLT:
717 case ISD::SETOGT:
718 case ISD::SETOLE:
719 if (VecVT == MVT::v4f32)
720 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
721 else if (VecVT == MVT::v2f64)
722 return PPC::XVCMPGTDP;
723 break;
724 case ISD::SETOGE:
725 if (VecVT == MVT::v4f32)
726 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
727 else if (VecVT == MVT::v2f64)
728 return PPC::XVCMPGEDP;
729 break;
730 default:
731 break;
732 }
733 llvm_unreachable("Invalid integer vector compare condition");
734 }
735
736 // getVCmpEQInst: return the equal compare instruction for the specified vector
737 // type. Since this is for altivec specific code, only support the altivec
738 // types (v16i8, v8i16, v4i32, and v4f32).
739 static unsigned int getVCmpEQInst(MVT::SimpleValueType VecVT, bool HasVSX) {
740 switch (VecVT) {
741 case MVT::v16i8:
742 return PPC::VCMPEQUB;
743 case MVT::v8i16:
744 return PPC::VCMPEQUH;
745 case MVT::v4i32:
746 return PPC::VCMPEQUW;
747 case MVT::v4f32:
748 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
749 case MVT::v2f64:
750 return PPC::XVCMPEQDP;
751 default:
752 llvm_unreachable("Invalid integer vector compare condition");
665 static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC,
666 bool HasVSX, bool &Swap, bool &Negate) {
667 Swap = false;
668 Negate = false;
669
670 if (VecVT.isFloatingPoint()) {
671 /* Handle some cases by swapping input operands. */
672 switch (CC) {
673 case ISD::SETLE: CC = ISD::SETGE; Swap = true; break;
674 case ISD::SETLT: CC = ISD::SETGT; Swap = true; break;
675 case ISD::SETOLE: CC = ISD::SETOGE; Swap = true; break;
676 case ISD::SETOLT: CC = ISD::SETOGT; Swap = true; break;
677 case ISD::SETUGE: CC = ISD::SETULE; Swap = true; break;
678 case ISD::SETUGT: CC = ISD::SETULT; Swap = true; break;
679 default: break;
680 }
681 /* Handle some cases by negating the result. */
682 switch (CC) {
683 case ISD::SETNE: CC = ISD::SETEQ; Negate = true; break;
684 case ISD::SETUNE: CC = ISD::SETOEQ; Negate = true; break;
685 case ISD::SETULE: CC = ISD::SETOGT; Negate = true; break;
686 case ISD::SETULT: CC = ISD::SETOGE; Negate = true; break;
687 default: break;
688 }
689 /* We have instructions implementing the remaining cases. */
690 switch (CC) {
691 case ISD::SETEQ:
692 case ISD::SETOEQ:
693 if (VecVT == MVT::v4f32)
694 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
695 else if (VecVT == MVT::v2f64)
696 return PPC::XVCMPEQDP;
697 break;
698 case ISD::SETGT:
699 case ISD::SETOGT:
700 if (VecVT == MVT::v4f32)
701 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
702 else if (VecVT == MVT::v2f64)
703 return PPC::XVCMPGTDP;
704 break;
705 case ISD::SETGE:
706 case ISD::SETOGE:
707 if (VecVT == MVT::v4f32)
708 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
709 else if (VecVT == MVT::v2f64)
710 return PPC::XVCMPGEDP;
711 break;
712 default:
713 break;
714 }
715 llvm_unreachable("Invalid floating-point vector compare condition");
716 } else {
717 /* Handle some cases by swapping input operands. */
718 switch (CC) {
719 case ISD::SETGE: CC = ISD::SETLE; Swap = true; break;
720 case ISD::SETLT: CC = ISD::SETGT; Swap = true; break;
721 case ISD::SETUGE: CC = ISD::SETULE; Swap = true; break;
722 case ISD::SETULT: CC = ISD::SETUGT; Swap = true; break;
723 default: break;
724 }
725 /* Handle some cases by negating the result. */
726 switch (CC) {
727 case ISD::SETNE: CC = ISD::SETEQ; Negate = true; break;
728 case ISD::SETUNE: CC = ISD::SETUEQ; Negate = true; break;
729 case ISD::SETLE: CC = ISD::SETGT; Negate = true; break;
730 case ISD::SETULE: CC = ISD::SETUGT; Negate = true; break;
731 default: break;
732 }
733 /* We have instructions implementing the remaining cases. */
734 switch (CC) {
735 case ISD::SETEQ:
736 case ISD::SETUEQ:
737 if (VecVT == MVT::v16i8)
738 return PPC::VCMPEQUB;
739 else if (VecVT == MVT::v8i16)
740 return PPC::VCMPEQUH;
741 else if (VecVT == MVT::v4i32)
742 return PPC::VCMPEQUW;
743 break;
744 case ISD::SETGT:
745 if (VecVT == MVT::v16i8)
746 return PPC::VCMPGTSB;
747 else if (VecVT == MVT::v8i16)
748 return PPC::VCMPGTSH;
749 else if (VecVT == MVT::v4i32)
750 return PPC::VCMPGTSW;
751 break;
752 case ISD::SETUGT:
753 if (VecVT == MVT::v16i8)
754 return PPC::VCMPGTUB;
755 else if (VecVT == MVT::v8i16)
756 return PPC::VCMPGTUH;
757 else if (VecVT == MVT::v4i32)
758 return PPC::VCMPGTUW;
759 break;
760 default:
761 break;
762 }
763 llvm_unreachable("Invalid integer vector compare condition");
753764 }
754765 }
755766
841852 // vector compare operations return the same type as the operands.
842853 if (LHS.getValueType().isVector()) {
843854 EVT VecVT = LHS.getValueType();
844 MVT::SimpleValueType VT = VecVT.getSimpleVT().SimpleTy;
845 unsigned int VCmpInst = getVCmpInst(VT, CC, PPCSubTarget->hasVSX());
846
847 switch (CC) {
848 case ISD::SETEQ:
849 case ISD::SETOEQ:
850 case ISD::SETUEQ:
851 return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, LHS, RHS);
852 case ISD::SETNE:
853 case ISD::SETONE:
854 case ISD::SETUNE: {
855 SDValue VCmp(CurDAG->getMachineNode(VCmpInst, dl, VecVT, LHS, RHS), 0);
856 return CurDAG->SelectNodeTo(N, PPCSubTarget->hasVSX() ? PPC::XXLNOR :
857 PPC::VNOR,
858 VecVT, VCmp, VCmp);
859 }
860 case ISD::SETLT:
861 case ISD::SETOLT:
862 case ISD::SETULT:
863 return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, RHS, LHS);
864 case ISD::SETGT:
865 case ISD::SETOGT:
866 case ISD::SETUGT:
867 return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, LHS, RHS);
868 case ISD::SETGE:
869 case ISD::SETOGE:
870 case ISD::SETUGE: {
871 // Small optimization: Altivec provides a 'Vector Compare Greater Than
872 // or Equal To' instruction (vcmpgefp), so in this case there is no
873 // need for extra logic for the equal compare.
874 if (VecVT.getSimpleVT().isFloatingPoint()) {
875 return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, LHS, RHS);
876 } else {
877 SDValue VCmpGT(CurDAG->getMachineNode(VCmpInst, dl, VecVT, LHS, RHS), 0);
878 unsigned int VCmpEQInst = getVCmpEQInst(VT, PPCSubTarget->hasVSX());
879 SDValue VCmpEQ(CurDAG->getMachineNode(VCmpEQInst, dl, VecVT, LHS, RHS), 0);
880 return CurDAG->SelectNodeTo(N, PPCSubTarget->hasVSX() ? PPC::XXLOR :
881 PPC::VOR,
882 VecVT, VCmpGT, VCmpEQ);
883 }
884 }
885 case ISD::SETLE:
886 case ISD::SETOLE:
887 case ISD::SETULE: {
888 SDValue VCmpLE(CurDAG->getMachineNode(VCmpInst, dl, VecVT, RHS, LHS), 0);
889 unsigned int VCmpEQInst = getVCmpEQInst(VT, PPCSubTarget->hasVSX());
890 SDValue VCmpEQ(CurDAG->getMachineNode(VCmpEQInst, dl, VecVT, LHS, RHS), 0);
891 return CurDAG->SelectNodeTo(N, PPCSubTarget->hasVSX() ? PPC::XXLOR :
892 PPC::VOR,
893 VecVT, VCmpLE, VCmpEQ);
894 }
895 default:
896 llvm_unreachable("Invalid vector compare type: should be expanded by legalize");
897 }
855 bool Swap, Negate;
856 unsigned int VCmpInst = getVCmpInst(VecVT.getSimpleVT(), CC,
857 PPCSubTarget->hasVSX(), Swap, Negate);
858 if (Swap)
859 std::swap(LHS, RHS);
860
861 if (Negate) {
862 SDValue VCmp(CurDAG->getMachineNode(VCmpInst, dl, VecVT, LHS, RHS), 0);
863 return CurDAG->SelectNodeTo(N, PPCSubTarget->hasVSX() ? PPC::XXLNOR :
864 PPC::VNOR,
865 VecVT, VCmp, VCmp);
866 }
867
868 return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, LHS, RHS);
898869 }
899870
900871 if (PPCSubTarget->useCRBits())
525525 // Altivec does not contain unordered floating-point compare instructions
526526 setCondCodeAction(ISD::SETUO, MVT::v4f32, Expand);
527527 setCondCodeAction(ISD::SETUEQ, MVT::v4f32, Expand);
528 setCondCodeAction(ISD::SETUGT, MVT::v4f32, Expand);
529 setCondCodeAction(ISD::SETUGE, MVT::v4f32, Expand);
530 setCondCodeAction(ISD::SETULT, MVT::v4f32, Expand);
531 setCondCodeAction(ISD::SETULE, MVT::v4f32, Expand);
532
533528 setCondCodeAction(ISD::SETO, MVT::v4f32, Expand);
534529 setCondCodeAction(ISD::SETONE, MVT::v4f32, Expand);
535530
560555 // Share the Altivec comparison restrictions.
561556 setCondCodeAction(ISD::SETUO, MVT::v2f64, Expand);
562557 setCondCodeAction(ISD::SETUEQ, MVT::v2f64, Expand);
563 setCondCodeAction(ISD::SETUGT, MVT::v2f64, Expand);
564 setCondCodeAction(ISD::SETUGE, MVT::v2f64, Expand);
565 setCondCodeAction(ISD::SETULT, MVT::v2f64, Expand);
566 setCondCodeAction(ISD::SETULE, MVT::v2f64, Expand);
567
568558 setCondCodeAction(ISD::SETO, MVT::v2f64, Expand);
569559 setCondCodeAction(ISD::SETONE, MVT::v2f64, Expand);
570560
6262 ret <16 x i8> %sext
6363 }
6464 ; CHECK-LABEL: 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]]
65 ; CHECK: vcmpgtsb [[RET:[0-9]+]], 2, 3
66 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
6867
6968 define <16 x i8> @v16ui8_cmp_le(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
7069 entry:
7372 ret <16 x i8> %sext
7473 }
7574 ; CHECK-LABEL: 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]]
75 ; CHECK: vcmpgtub [[RET:[0-9]+]], 2, 3
76 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
7977
8078 define <16 x i8> @v16si8_cmp_lt(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
8179 entry:
120118 ret <16 x i8> %sext
121119 }
122120 ; CHECK-LABEL: 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]]
121 ; CHECK: vcmpgtsb [[RET:[0-9]+]], 3, 2
122 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
126123
127124 define <16 x i8> @v16ui8_cmp_ge(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
128125 entry:
131128 ret <16 x i8> %sext
132129 }
133130 ; CHECK-LABEL: 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]]
131 ; CHECK: vcmpgtub [[RET:[0-9]+]], 3, 2
132 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
137133
138134
139135 define <32 x i8> @v32si8_cmp(<32 x i8> %x, <32 x i8> %y) nounwind readnone {
192188 ret <8 x i16> %sext
193189 }
194190 ; CHECK-LABEL: 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]]
191 ; CHECK: vcmpgtsh [[RET:[0-9]+]], 2, 3
192 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
198193
199194 define <8 x i16> @v8ui16_cmp_le(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
200195 entry:
203198 ret <8 x i16> %sext
204199 }
205200 ; CHECK-LABEL: 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]]
201 ; CHECK: vcmpgtuh [[RET:[0-9]+]], 2, 3
202 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
209203
210204 define <8 x i16> @v8si16_cmp_lt(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
211205 entry:
250244 ret <8 x i16> %sext
251245 }
252246 ; CHECK-LABEL: 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]]
247 ; CHECK: vcmpgtsh [[RET:[0-9]+]], 3, 2
248 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
256249
257250 define <8 x i16> @v8ui16_cmp_ge(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
258251 entry:
261254 ret <8 x i16> %sext
262255 }
263256 ; CHECK-LABEL: 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]]
257 ; CHECK: vcmpgtuh [[RET:[0-9]+]], 3, 2
258 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
267259
268260
269261 define <16 x i16> @v16si16_cmp(<16 x i16> %x, <16 x i16> %y) nounwind readnone {
325317 ret <4 x i32> %sext
326318 }
327319 ; CHECK-LABEL: 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]]
320 ; CHECK: vcmpgtsw [[RET:[0-9]+]], 2, 3
321 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
331322
332323 define <4 x i32> @v4ui32_cmp_le(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
333324 entry:
336327 ret <4 x i32> %sext
337328 }
338329 ; CHECK-LABEL: 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]]
330 ; CHECK: vcmpgtuw [[RET:[0-9]+]], 2, 3
331 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
342332
343333 define <4 x i32> @v4si32_cmp_lt(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
344334 entry:
383373 ret <4 x i32> %sext
384374 }
385375 ; CHECK-LABEL: 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]]
376 ; CHECK: vcmpgtsw [[RET:[0-9]+]], 3, 2
377 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
389378
390379 define <4 x i32> @v4ui32_cmp_ge(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
391380 entry:
394383 ret <4 x i32> %sext
395384 }
396385 ; CHECK-LABEL: 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]]
386 ; CHECK: vcmpgtuw [[RET:[0-9]+]], 3, 2
387 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
400388
401389
402390 define <8 x i32> @v8si32_cmp(<8 x i32> %x, <8 x i32> %y) nounwind readnone {
479467 ret <4 x float> %0
480468 }
481469 ; CHECK-LABEL: 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]]
470 ; CHECK: vcmpgefp 2, 3, 2
485471
486472 define <4 x float> @v4f32_cmp_lt(<4 x float> %x, <4 x float> %y) nounwind readnone {
487473 entry:
512498 }
513499 ; CHECK-LABEL: v4f32_cmp_gt:
514500 ; CHECK: vcmpgtfp 2, 2, 3
501
502 define <4 x float> @v4f32_cmp_ule(<4 x float> %x, <4 x float> %y) nounwind readnone {
503 entry:
504 %cmp = fcmp ule <4 x float> %x, %y
505 %sext = sext <4 x i1> %cmp to <4 x i32>
506 %0 = bitcast <4 x i32> %sext to <4 x float>
507 ret <4 x float> %0
508 }
509 ; CHECK-LABEL: v4f32_cmp_ule:
510 ; CHECK: vcmpgtfp [[RET:[0-9]+]], 2, 3
511 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
512
513 define <4 x float> @v4f32_cmp_ult(<4 x float> %x, <4 x float> %y) nounwind readnone {
514 entry:
515 %cmp = fcmp ult <4 x float> %x, %y
516 %sext = sext <4 x i1> %cmp to <4 x i32>
517 %0 = bitcast <4 x i32> %sext to <4 x float>
518 ret <4 x float> %0
519 }
520 ; CHECK-LABEL: v4f32_cmp_ult:
521 ; CHECK: vcmpgefp [[RET:[0-9]+]], 2, 3
522 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
523
524 define <4 x float> @v4f32_cmp_uge(<4 x float> %x, <4 x float> %y) nounwind readnone {
525 entry:
526 %cmp = fcmp uge <4 x float> %x, %y
527 %sext = sext <4 x i1> %cmp to <4 x i32>
528 %0 = bitcast <4 x i32> %sext to <4 x float>
529 ret <4 x float> %0
530 }
531 ; CHECK-LABEL: v4f32_cmp_uge:
532 ; CHECK: vcmpgtfp [[RET:[0-9]+]], 3, 2
533 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
534
535 define <4 x float> @v4f32_cmp_ugt(<4 x float> %x, <4 x float> %y) nounwind readnone {
536 entry:
537 %cmp = fcmp ugt <4 x float> %x, %y
538 %sext = sext <4 x i1> %cmp to <4 x i32>
539 %0 = bitcast <4 x i32> %sext to <4 x float>
540 ret <4 x float> %0
541 }
542 ; CHECK-LABEL: v4f32_cmp_ugt:
543 ; CHECK: vcmpgefp [[RET:[0-9]+]], 3, 2
544 ; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
515545
516546
517547 define <8 x float> @v8f32_cmp(<8 x float> %x, <8 x float> %y) nounwind readnone {