llvm.org GIT mirror llvm / a463daf
[DAGCombiner] Recognise vector rotations with non-splat constants Fixes PR33691. Differential revision: https://reviews.llvm.org/D35381 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308150 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Zhogin 3 years ago
5 changed file(s) with 61 addition(s) and 119 deletion(s). Raw diff Collapse all Expand all
45844584 return nullptr;
45854585 }
45864586
4587 // if Left + Right == Sum (constant or constant splat vector)
4588 static bool sumMatchConstant(SDValue Left, SDValue Right, unsigned Sum,
4589 SelectionDAG &DAG, const SDLoc &DL) {
4590 EVT ShiftVT = Left.getValueType();
4591 if (ShiftVT != Right.getValueType()) return false;
4592
4593 SDValue ShiftSum = DAG.FoldConstantArithmetic(ISD::ADD, DL, ShiftVT,
4594 Left.getNode(), Right.getNode());
4595 if (!ShiftSum) return false;
4596
4597 ConstantSDNode *CSum = isConstOrConstSplat(ShiftSum);
4598 return CSum && CSum->getZExtValue() == Sum;
4599 }
4600
45874601 // MatchRotate - Handle an 'or' of two operands. If this is one of the many
45884602 // idioms for rotate, and if the target supports rotation instructions, generate
45894603 // a rot[lr].
46294643
46304644 // fold (or (shl x, C1), (srl x, C2)) -> (rotl x, C1)
46314645 // fold (or (shl x, C1), (srl x, C2)) -> (rotr x, C2)
4632 if (isConstOrConstSplat(LHSShiftAmt) && isConstOrConstSplat(RHSShiftAmt)) {
4633 uint64_t LShVal = isConstOrConstSplat(LHSShiftAmt)->getZExtValue();
4634 uint64_t RShVal = isConstOrConstSplat(RHSShiftAmt)->getZExtValue();
4635 if ((LShVal + RShVal) != EltSizeInBits)
4636 return nullptr;
4637
4646 if (sumMatchConstant(LHSShiftAmt, RHSShiftAmt, EltSizeInBits, DAG, DL)) {
46384647 SDValue Rot = DAG.getNode(HasROTL ? ISD::ROTL : ISD::ROTR, DL, VT,
46394648 LHSShiftArg, HasROTL ? LHSShiftAmt : RHSShiftAmt);
46404649
46414650 // If there is an AND of either shifted operand, apply it to the result.
46424651 if (LHSMask.getNode() || RHSMask.getNode()) {
4643 SDValue Mask = DAG.getAllOnesConstant(DL, VT);
4652 SDValue AllOnes = DAG.getAllOnesConstant(DL, VT);
4653 SDValue Mask = AllOnes;
46444654
46454655 if (LHSMask.getNode()) {
4646 APInt RHSBits = APInt::getLowBitsSet(EltSizeInBits, LShVal);
4656 SDValue RHSBits = DAG.getNode(ISD::SRL, DL, VT, AllOnes, RHSShiftAmt);
46474657 Mask = DAG.getNode(ISD::AND, DL, VT, Mask,
4648 DAG.getNode(ISD::OR, DL, VT, LHSMask,
4649 DAG.getConstant(RHSBits, DL, VT)));
4658 DAG.getNode(ISD::OR, DL, VT, LHSMask, RHSBits));
46504659 }
46514660 if (RHSMask.getNode()) {
4652 APInt LHSBits = APInt::getHighBitsSet(EltSizeInBits, RShVal);
4661 SDValue LHSBits = DAG.getNode(ISD::SHL, DL, VT, AllOnes, LHSShiftAmt);
46534662 Mask = DAG.getNode(ISD::AND, DL, VT, Mask,
4654 DAG.getNode(ISD::OR, DL, VT, RHSMask,
4655 DAG.getConstant(LHSBits, DL, VT)));
4663 DAG.getNode(ISD::OR, DL, VT, RHSMask, LHSBits));
46564664 }
46574665
46584666 Rot = DAG.getNode(ISD::AND, DL, VT, Rot, Mask);
55 define <4 x i32> @combine_vec_rot_rot(<4 x i32> %x) {
66 ; XOP-LABEL: combine_vec_rot_rot:
77 ; XOP: # BB#0:
8 ; XOP-NEXT: vpshld {{.*}}(%rip), %xmm0, %xmm1
9 ; XOP-NEXT: vpshld {{.*}}(%rip), %xmm0, %xmm0
10 ; XOP-NEXT: vpor %xmm0, %xmm1, %xmm0
11 ; XOP-NEXT: vpshld {{.*}}(%rip), %xmm0, %xmm1
12 ; XOP-NEXT: vpshld {{.*}}(%rip), %xmm0, %xmm0
13 ; XOP-NEXT: vpor %xmm0, %xmm1, %xmm0
8 ; XOP-NEXT: vprotd {{.*}}(%rip), %xmm0, %xmm0
149 ; XOP-NEXT: retq
1510 ;
1611 ; AVX512-LABEL: combine_vec_rot_rot:
1414 define <4 x i32> @rot_v4i32_non_splat(<4 x i32> %x) {
1515 ; CHECK-LABEL: rot_v4i32_non_splat:
1616 ; CHECK: # BB#0:
17 ; CHECK-NEXT: vpsrlvd {{.*}}(%rip), %xmm0, %xmm1
18 ; CHECK-NEXT: vpsllvd {{.*}}(%rip), %xmm0, %xmm0
19 ; CHECK-NEXT: vpor %xmm0, %xmm1, %xmm0
17 ; CHECK-NEXT: vprotd {{.*}}(%rip), %xmm0, %xmm0
2018 ; CHECK-NEXT: retq
2119 %1 = lshr <4 x i32> %x,
2220 %2 = shl <4 x i32> %x,
4240 define <4 x i32> @rot_v4i32_non_splat_2masks(<4 x i32> %x) {
4341 ; CHECK-LABEL: rot_v4i32_non_splat_2masks:
4442 ; CHECK: # BB#0:
45 ; CHECK-NEXT: vpsrlvd {{.*}}(%rip), %xmm0, %xmm1
46 ; CHECK-NEXT: vpxor %xmm2, %xmm2, %xmm2
47 ; CHECK-NEXT: vpblendw {{.*#+}} xmm1 = xmm2[0],xmm1[1],xmm2[2],xmm1[3],xmm2[4],xmm1[5],xmm2[6],xmm1[7]
48 ; CHECK-NEXT: vpsllvd {{.*}}(%rip), %xmm0, %xmm0
49 ; CHECK-NEXT: vpblendw {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[3],xmm2[4,5,6],xmm0[7]
50 ; CHECK-NEXT: vpor %xmm0, %xmm1, %xmm0
43 ; CHECK-NEXT: vprotd {{.*}}(%rip), %xmm0, %xmm0
44 ; CHECK-NEXT: vpand {{.*}}(%rip), %xmm0, %xmm0
5145 ; CHECK-NEXT: retq
5246 %1 = lshr <4 x i32> %x,
5347 %2 = and <4 x i32> %1,
850850 ; AVX512-NEXT: vpor %xmm0, %xmm1, %xmm0
851851 ; AVX512-NEXT: retq
852852 ;
853 ; XOPAVX1-LABEL: constant_rotate_v2i64:
854 ; XOPAVX1: # BB#0:
855 ; XOPAVX1-NEXT: vpshlq {{.*}}(%rip), %xmm0, %xmm1
856 ; XOPAVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2
857 ; XOPAVX1-NEXT: vpsubq {{.*}}(%rip), %xmm2, %xmm2
858 ; XOPAVX1-NEXT: vpshlq %xmm2, %xmm0, %xmm0
859 ; XOPAVX1-NEXT: vpor %xmm0, %xmm1, %xmm0
860 ; XOPAVX1-NEXT: retq
861 ;
862 ; XOPAVX2-LABEL: constant_rotate_v2i64:
863 ; XOPAVX2: # BB#0:
864 ; XOPAVX2-NEXT: vpsllvq {{.*}}(%rip), %xmm0, %xmm1
865 ; XOPAVX2-NEXT: vpsrlvq {{.*}}(%rip), %xmm0, %xmm0
866 ; XOPAVX2-NEXT: vpor %xmm0, %xmm1, %xmm0
867 ; XOPAVX2-NEXT: retq
853 ; XOP-LABEL: constant_rotate_v2i64:
854 ; XOP: # BB#0:
855 ; XOP-NEXT: vprotq {{.*}}(%rip), %xmm0, %xmm0
856 ; XOP-NEXT: retq
868857 ;
869858 ; X32-SSE-LABEL: constant_rotate_v2i64:
870859 ; X32-SSE: # BB#0:
957946 ; AVX512-NEXT: vpor %xmm0, %xmm1, %xmm0
958947 ; AVX512-NEXT: retq
959948 ;
960 ; XOPAVX1-LABEL: constant_rotate_v4i32:
961 ; XOPAVX1: # BB#0:
962 ; XOPAVX1-NEXT: vpshld {{.*}}(%rip), %xmm0, %xmm1
963 ; XOPAVX1-NEXT: vpshld {{.*}}(%rip), %xmm0, %xmm0
964 ; XOPAVX1-NEXT: vpor %xmm0, %xmm1, %xmm0
965 ; XOPAVX1-NEXT: retq
966 ;
967 ; XOPAVX2-LABEL: constant_rotate_v4i32:
968 ; XOPAVX2: # BB#0:
969 ; XOPAVX2-NEXT: vpsllvd {{.*}}(%rip), %xmm0, %xmm1
970 ; XOPAVX2-NEXT: vpsrlvd {{.*}}(%rip), %xmm0, %xmm0
971 ; XOPAVX2-NEXT: vpor %xmm0, %xmm1, %xmm0
972 ; XOPAVX2-NEXT: retq
949 ; XOP-LABEL: constant_rotate_v4i32:
950 ; XOP: # BB#0:
951 ; XOP-NEXT: vprotd {{.*}}(%rip), %xmm0, %xmm0
952 ; XOP-NEXT: retq
973953 ;
974954 ; X32-SSE-LABEL: constant_rotate_v4i32:
975955 ; X32-SSE: # BB#0:
10991079 ;
11001080 ; XOP-LABEL: constant_rotate_v8i16:
11011081 ; XOP: # BB#0:
1102 ; XOP-NEXT: vpshlw {{.*}}(%rip), %xmm0, %xmm1
1103 ; XOP-NEXT: vpxor %xmm2, %xmm2, %xmm2
1104 ; XOP-NEXT: vpsubw {{.*}}(%rip), %xmm2, %xmm2
1105 ; XOP-NEXT: vpshlw %xmm2, %xmm0, %xmm0
1106 ; XOP-NEXT: vpor %xmm0, %xmm1, %xmm0
1082 ; XOP-NEXT: vprotw {{.*}}(%rip), %xmm0, %xmm0
11071083 ; XOP-NEXT: retq
11081084 ;
11091085 ; X32-SSE-LABEL: constant_rotate_v8i16:
12801256 ;
12811257 ; XOP-LABEL: constant_rotate_v16i8:
12821258 ; XOP: # BB#0:
1283 ; XOP-NEXT: vpshlb {{.*}}(%rip), %xmm0, %xmm1
1284 ; XOP-NEXT: vpxor %xmm2, %xmm2, %xmm2
1285 ; XOP-NEXT: vpsubb {{.*}}(%rip), %xmm2, %xmm2
1286 ; XOP-NEXT: vpshlb %xmm2, %xmm0, %xmm0
1287 ; XOP-NEXT: vpor %xmm0, %xmm1, %xmm0
1259 ; XOP-NEXT: vprotb {{.*}}(%rip), %xmm0, %xmm0
12881260 ; XOP-NEXT: retq
12891261 ;
12901262 ; X32-SSE-LABEL: constant_rotate_v16i8:
557557 ;
558558 ; XOPAVX1-LABEL: constant_rotate_v8i32:
559559 ; XOPAVX1: # BB#0:
560 ; XOPAVX1-NEXT: vpshld {{.*}}(%rip), %xmm0, %xmm1
561 ; XOPAVX1-NEXT: vextractf128 $1, %ymm0, %xmm2
562 ; XOPAVX1-NEXT: vpshld {{.*}}(%rip), %xmm2, %xmm3
563 ; XOPAVX1-NEXT: vinsertf128 $1, %xmm3, %ymm1, %ymm1
564 ; XOPAVX1-NEXT: vpshld {{.*}}(%rip), %xmm0, %xmm0
565 ; XOPAVX1-NEXT: vpshld {{.*}}(%rip), %xmm2, %xmm2
566 ; XOPAVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
567 ; XOPAVX1-NEXT: vorps %ymm0, %ymm1, %ymm0
560 ; XOPAVX1-NEXT: vprotd {{.*}}(%rip), %xmm0, %xmm1
561 ; XOPAVX1-NEXT: vextractf128 $1, %ymm0, %xmm0
562 ; XOPAVX1-NEXT: vprotd {{.*}}(%rip), %xmm0, %xmm0
563 ; XOPAVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0
568564 ; XOPAVX1-NEXT: retq
569565 ;
570566 ; XOPAVX2-LABEL: constant_rotate_v8i32:
571567 ; XOPAVX2: # BB#0:
572 ; XOPAVX2-NEXT: vpsllvd {{.*}}(%rip), %ymm0, %ymm1
573 ; XOPAVX2-NEXT: vpsrlvd {{.*}}(%rip), %ymm0, %ymm0
574 ; XOPAVX2-NEXT: vpor %ymm0, %ymm1, %ymm0
568 ; XOPAVX2-NEXT: vprotd {{.*}}(%rip), %xmm0, %xmm1
569 ; XOPAVX2-NEXT: vextracti128 $1, %ymm0, %xmm0
570 ; XOPAVX2-NEXT: vprotd {{.*}}(%rip), %xmm0, %xmm0
571 ; XOPAVX2-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0
575572 ; XOPAVX2-NEXT: retq
576573 %shl = shl <8 x i32> %a,
577574 %lshr = lshr <8 x i32> %a,
642639 ;
643640 ; XOPAVX1-LABEL: constant_rotate_v16i16:
644641 ; XOPAVX1: # BB#0:
645 ; XOPAVX1-NEXT: vpshlw {{.*}}(%rip), %xmm0, %xmm1
646 ; XOPAVX1-NEXT: vextractf128 $1, %ymm0, %xmm2
647 ; XOPAVX1-NEXT: vpshlw {{.*}}(%rip), %xmm2, %xmm3
648 ; XOPAVX1-NEXT: vinsertf128 $1, %xmm3, %ymm1, %ymm1
649 ; XOPAVX1-NEXT: vpxor %xmm3, %xmm3, %xmm3
650 ; XOPAVX1-NEXT: vpsubw {{.*}}(%rip), %xmm3, %xmm4
651 ; XOPAVX1-NEXT: vpshlw %xmm4, %xmm2, %xmm2
652 ; XOPAVX1-NEXT: vpsubw {{.*}}(%rip), %xmm3, %xmm3
653 ; XOPAVX1-NEXT: vpshlw %xmm3, %xmm0, %xmm0
654 ; XOPAVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
655 ; XOPAVX1-NEXT: vorps %ymm0, %ymm1, %ymm0
642 ; XOPAVX1-NEXT: vprotw {{.*}}(%rip), %xmm0, %xmm1
643 ; XOPAVX1-NEXT: vextractf128 $1, %ymm0, %xmm0
644 ; XOPAVX1-NEXT: vprotw {{.*}}(%rip), %xmm0, %xmm0
645 ; XOPAVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0
656646 ; XOPAVX1-NEXT: retq
657647 ;
658648 ; XOPAVX2-LABEL: constant_rotate_v16i16:
659649 ; XOPAVX2: # BB#0:
660 ; XOPAVX2-NEXT: vpmullw {{.*}}(%rip), %ymm0, %ymm1
661 ; XOPAVX2-NEXT: vpxor %xmm2, %xmm2, %xmm2
662 ; XOPAVX2-NEXT: vpsubw {{.*}}(%rip), %xmm2, %xmm3
663 ; XOPAVX2-NEXT: vextracti128 $1, %ymm0, %xmm4
664 ; XOPAVX2-NEXT: vpshlw %xmm3, %xmm4, %xmm3
665 ; XOPAVX2-NEXT: vpsubw {{.*}}(%rip), %xmm2, %xmm2
666 ; XOPAVX2-NEXT: vpshlw %xmm2, %xmm0, %xmm0
667 ; XOPAVX2-NEXT: vinserti128 $1, %xmm3, %ymm0, %ymm0
668 ; XOPAVX2-NEXT: vpor %ymm0, %ymm1, %ymm0
650 ; XOPAVX2-NEXT: vprotw {{.*}}(%rip), %xmm0, %xmm1
651 ; XOPAVX2-NEXT: vextracti128 $1, %ymm0, %xmm0
652 ; XOPAVX2-NEXT: vprotw {{.*}}(%rip), %xmm0, %xmm0
653 ; XOPAVX2-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0
669654 ; XOPAVX2-NEXT: retq
670655 %shl = shl <16 x i16> %a,
671656 %lshr = lshr <16 x i16> %a,
767752 ;
768753 ; XOPAVX1-LABEL: constant_rotate_v32i8:
769754 ; XOPAVX1: # BB#0:
770 ; XOPAVX1-NEXT: vmovdqa {{.*#+}} xmm1 = [0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1]
771 ; XOPAVX1-NEXT: vextractf128 $1, %ymm0, %xmm2
772 ; XOPAVX1-NEXT: vpshlb %xmm1, %xmm2, %xmm3
773 ; XOPAVX1-NEXT: vpshlb %xmm1, %xmm0, %xmm1
774 ; XOPAVX1-NEXT: vinsertf128 $1, %xmm3, %ymm1, %ymm1
775 ; XOPAVX1-NEXT: vpxor %xmm3, %xmm3, %xmm3
776 ; XOPAVX1-NEXT: vpsubb {{.*}}(%rip), %xmm3, %xmm3
777 ; XOPAVX1-NEXT: vpshlb %xmm3, %xmm2, %xmm2
778 ; XOPAVX1-NEXT: vpshlb %xmm3, %xmm0, %xmm0
779 ; XOPAVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
780 ; XOPAVX1-NEXT: vorps %ymm0, %ymm1, %ymm0
755 ; XOPAVX1-NEXT: vextractf128 $1, %ymm0, %xmm1
756 ; XOPAVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1]
757 ; XOPAVX1-NEXT: vprotb %xmm2, %xmm1, %xmm1
758 ; XOPAVX1-NEXT: vprotb %xmm2, %xmm0, %xmm0
759 ; XOPAVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
781760 ; XOPAVX1-NEXT: retq
782761 ;
783762 ; XOPAVX2-LABEL: constant_rotate_v32i8:
784763 ; XOPAVX2: # BB#0:
785 ; XOPAVX2-NEXT: vmovdqa {{.*#+}} xmm1 = [0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1]
786 ; XOPAVX2-NEXT: vextracti128 $1, %ymm0, %xmm2
787 ; XOPAVX2-NEXT: vpshlb %xmm1, %xmm2, %xmm3
788 ; XOPAVX2-NEXT: vpshlb %xmm1, %xmm0, %xmm1
789 ; XOPAVX2-NEXT: vinserti128 $1, %xmm3, %ymm1, %ymm1
790 ; XOPAVX2-NEXT: vpxor %xmm3, %xmm3, %xmm3
791 ; XOPAVX2-NEXT: vpsubb {{.*}}(%rip), %xmm3, %xmm3
792 ; XOPAVX2-NEXT: vpshlb %xmm3, %xmm2, %xmm2
793 ; XOPAVX2-NEXT: vpshlb %xmm3, %xmm0, %xmm0
794 ; XOPAVX2-NEXT: vinserti128 $1, %xmm2, %ymm0, %ymm0
795 ; XOPAVX2-NEXT: vpor %ymm0, %ymm1, %ymm0
764 ; XOPAVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
765 ; XOPAVX2-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1]
766 ; XOPAVX2-NEXT: vprotb %xmm2, %xmm1, %xmm1
767 ; XOPAVX2-NEXT: vprotb %xmm2, %xmm0, %xmm0
768 ; XOPAVX2-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0
796769 ; XOPAVX2-NEXT: retq
797770 %shl = shl <32 x i8> %a,
798771 %lshr = lshr <32 x i8> %a,