diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 240be748a89ec8..044e21dab43915 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -46438,6 +46438,49 @@ static SDValue combineBitOpWithMOVMSK(SDNode *N, SelectionDAG &DAG) { return DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, Result); } +// Attempt to fold BITOP(SHIFT(X,Z),SHIFT(Y,Z)) -> SHIFT(BITOP(X,Y),Z). +// NOTE: This is a very limited case of what SimplifyUsingDistributiveLaws +// handles in InstCombine. +static SDValue combineBitOpWithShift(SDNode *N, SelectionDAG &DAG) { + unsigned Opc = N->getOpcode(); + assert((Opc == ISD::OR || Opc == ISD::AND || Opc == ISD::XOR) && + "Unexpected bit opcode"); + + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + EVT VT = N->getValueType(0); + + // Both operands must be single use. + if (!N0.hasOneUse() || !N1.hasOneUse()) + return SDValue(); + + // Search for matching shifts. + SDValue BC0 = peekThroughOneUseBitcasts(N0); + SDValue BC1 = peekThroughOneUseBitcasts(N1); + + unsigned BCOpc = BC0.getOpcode(); + EVT BCVT = BC0.getValueType(); + if (BCOpc != BC1->getOpcode() || BCVT != BC1.getValueType()) + return SDValue(); + + switch (BCOpc) { + case X86ISD::VSHLI: + case X86ISD::VSRLI: + case X86ISD::VSRAI: { + if (BC0.getOperand(1) != BC1.getOperand(1)) + return SDValue(); + + SDLoc DL(N); + SDValue BitOp = + DAG.getNode(Opc, DL, BCVT, BC0.getOperand(0), BC1.getOperand(0)); + SDValue Shift = DAG.getNode(BCOpc, DL, BCVT, BitOp, BC0.getOperand(1)); + return DAG.getBitcast(VT, Shift); + } + } + + return SDValue(); +} + /// If this is a zero/all-bits result that is bitwise-anded with a low bits /// mask. (Mask == 1 for the x86 lowering of a SETCC + ZEXT), replace the 'and' /// with a shift-right to eliminate loading the vector constant mask value. @@ -46741,6 +46784,9 @@ static SDValue combineAnd(SDNode *N, SelectionDAG &DAG, if (SDValue R = combineBitOpWithMOVMSK(N, DAG)) return R; + if (SDValue R = combineBitOpWithShift(N, DAG)) + return R; + if (SDValue FPLogic = convertIntLogicToFPLogic(N, DAG, DCI, Subtarget)) return FPLogic; @@ -47188,6 +47234,9 @@ static SDValue combineOr(SDNode *N, SelectionDAG &DAG, if (SDValue R = combineBitOpWithMOVMSK(N, DAG)) return R; + if (SDValue R = combineBitOpWithShift(N, DAG)) + return R; + if (SDValue FPLogic = convertIntLogicToFPLogic(N, DAG, DCI, Subtarget)) return FPLogic; @@ -49660,6 +49709,9 @@ static SDValue combineXor(SDNode *N, SelectionDAG &DAG, if (SDValue R = combineBitOpWithMOVMSK(N, DAG)) return R; + if (SDValue R = combineBitOpWithShift(N, DAG)) + return R; + if (SDValue FPLogic = convertIntLogicToFPLogic(N, DAG, DCI, Subtarget)) return FPLogic; diff --git a/llvm/test/CodeGen/X86/movmsk-cmp.ll b/llvm/test/CodeGen/X86/movmsk-cmp.ll index 68adeda025d7c6..cb4af67fe02416 100644 --- a/llvm/test/CodeGen/X86/movmsk-cmp.ll +++ b/llvm/test/CodeGen/X86/movmsk-cmp.ll @@ -1227,20 +1227,18 @@ define i1 @allzeros_v16i8_and1(<16 x i8> %arg) { define i1 @allones_v32i8_and1(<32 x i8> %arg) { ; SSE-LABEL: allones_v32i8_and1: ; SSE: # %bb.0: +; SSE-NEXT: pand %xmm1, %xmm0 ; SSE-NEXT: psllw $7, %xmm0 -; SSE-NEXT: psllw $7, %xmm1 -; SSE-NEXT: pand %xmm0, %xmm1 -; SSE-NEXT: pmovmskb %xmm1, %eax +; SSE-NEXT: pmovmskb %xmm0, %eax ; SSE-NEXT: cmpw $-1, %ax ; SSE-NEXT: sete %al ; SSE-NEXT: retq ; ; AVX1-LABEL: allones_v32i8_and1: ; AVX1: # %bb.0: -; AVX1-NEXT: vpsllw $7, %xmm0, %xmm1 -; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 +; AVX1-NEXT: vpand %xmm0, %xmm1, %xmm0 ; AVX1-NEXT: vpsllw $7, %xmm0, %xmm0 -; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 ; AVX1-NEXT: vpmovmskb %xmm0, %eax ; AVX1-NEXT: cmpw $-1, %ax ; AVX1-NEXT: sete %al @@ -1292,9 +1290,8 @@ define i1 @allzeros_v32i8_and1(<32 x i8> %arg) { ; AVX1-LABEL: allzeros_v32i8_and1: ; AVX1: # %bb.0: ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 -; AVX1-NEXT: vpsllw $7, %xmm1, %xmm1 -; AVX1-NEXT: vpsllw $7, %xmm0, %xmm0 ; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsllw $7, %xmm0, %xmm0 ; AVX1-NEXT: vpmovmskb %xmm0, %eax ; AVX1-NEXT: testl %eax, %eax ; AVX1-NEXT: sete %al @@ -1336,14 +1333,11 @@ define i1 @allzeros_v32i8_and1(<32 x i8> %arg) { define i1 @allones_v64i8_and1(<64 x i8> %arg) { ; SSE-LABEL: allones_v64i8_and1: ; SSE: # %bb.0: -; SSE-NEXT: psllw $7, %xmm1 -; SSE-NEXT: psllw $7, %xmm3 +; SSE-NEXT: pand %xmm2, %xmm0 +; SSE-NEXT: pand %xmm1, %xmm0 +; SSE-NEXT: pand %xmm3, %xmm0 ; SSE-NEXT: psllw $7, %xmm0 -; SSE-NEXT: psllw $7, %xmm2 -; SSE-NEXT: pand %xmm0, %xmm2 -; SSE-NEXT: pand %xmm1, %xmm2 -; SSE-NEXT: pand %xmm3, %xmm2 -; SSE-NEXT: pmovmskb %xmm2, %eax +; SSE-NEXT: pmovmskb %xmm0, %eax ; SSE-NEXT: cmpw $-1, %ax ; SSE-NEXT: sete %al ; SSE-NEXT: retq @@ -1351,14 +1345,11 @@ define i1 @allones_v64i8_and1(<64 x i8> %arg) { ; AVX1-LABEL: allones_v64i8_and1: ; AVX1: # %bb.0: ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 -; AVX1-NEXT: vpsllw $7, %xmm2, %xmm2 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm3 -; AVX1-NEXT: vpsllw $7, %xmm3, %xmm3 -; AVX1-NEXT: vpsllw $7, %xmm0, %xmm0 -; AVX1-NEXT: vpsllw $7, %xmm1, %xmm1 ; AVX1-NEXT: vpand %xmm0, %xmm1, %xmm0 ; AVX1-NEXT: vpand %xmm0, %xmm2, %xmm0 ; AVX1-NEXT: vpand %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsllw $7, %xmm0, %xmm0 ; AVX1-NEXT: vpmovmskb %xmm0, %eax ; AVX1-NEXT: cmpw $-1, %ax ; AVX1-NEXT: sete %al @@ -1367,9 +1358,8 @@ define i1 @allones_v64i8_and1(<64 x i8> %arg) { ; ; AVX2-LABEL: allones_v64i8_and1: ; AVX2: # %bb.0: -; AVX2-NEXT: vpsllw $7, %ymm0, %ymm0 -; AVX2-NEXT: vpsllw $7, %ymm1, %ymm1 ; AVX2-NEXT: vpand %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsllw $7, %ymm0, %ymm0 ; AVX2-NEXT: vpmovmskb %ymm0, %eax ; AVX2-NEXT: cmpl $-1, %eax ; AVX2-NEXT: sete %al @@ -1378,10 +1368,9 @@ define i1 @allones_v64i8_and1(<64 x i8> %arg) { ; ; KNL-LABEL: allones_v64i8_and1: ; KNL: # %bb.0: -; KNL-NEXT: vpsllw $7, %ymm0, %ymm1 -; KNL-NEXT: vextracti64x4 $1, %zmm0, %ymm0 +; KNL-NEXT: vextracti64x4 $1, %zmm0, %ymm1 +; KNL-NEXT: vpand %ymm0, %ymm1, %ymm0 ; KNL-NEXT: vpsllw $7, %ymm0, %ymm0 -; KNL-NEXT: vpand %ymm1, %ymm0, %ymm0 ; KNL-NEXT: vpmovmskb %ymm0, %eax ; KNL-NEXT: cmpl $-1, %eax ; KNL-NEXT: sete %al @@ -1416,15 +1405,12 @@ define i1 @allzeros_v64i8_and1(<64 x i8> %arg) { ; ; AVX1-LABEL: allzeros_v64i8_and1: ; AVX1: # %bb.0: -; AVX1-NEXT: vpsllw $7, %xmm1, %xmm2 -; AVX1-NEXT: vpsllw $7, %xmm0, %xmm3 -; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 -; AVX1-NEXT: vpsllw $7, %xmm1, %xmm1 -; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 -; AVX1-NEXT: vpsllw $7, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 +; AVX1-NEXT: vpor %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vpor %xmm2, %xmm1, %xmm1 ; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 -; AVX1-NEXT: vpor %xmm0, %xmm2, %xmm0 -; AVX1-NEXT: vpor %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsllw $7, %xmm0, %xmm0 ; AVX1-NEXT: vpmovmskb %xmm0, %eax ; AVX1-NEXT: testl %eax, %eax ; AVX1-NEXT: sete %al @@ -1444,9 +1430,8 @@ define i1 @allzeros_v64i8_and1(<64 x i8> %arg) { ; KNL-LABEL: allzeros_v64i8_and1: ; KNL: # %bb.0: ; KNL-NEXT: vextracti64x4 $1, %zmm0, %ymm1 -; KNL-NEXT: vpsllw $7, %ymm1, %ymm1 -; KNL-NEXT: vpsllw $7, %ymm0, %ymm0 ; KNL-NEXT: vpor %ymm1, %ymm0, %ymm0 +; KNL-NEXT: vpsllw $7, %ymm0, %ymm0 ; KNL-NEXT: vpmovmskb %ymm0, %eax ; KNL-NEXT: testl %eax, %eax ; KNL-NEXT: sete %al @@ -1734,11 +1719,9 @@ define i1 @allzeros_v32i16_and1(<32 x i16> %arg) { ; KNL-LABEL: allzeros_v32i16_and1: ; KNL: # %bb.0: ; KNL-NEXT: vextracti64x4 $1, %zmm0, %ymm1 -; KNL-NEXT: vpsllw $15, %ymm1, %ymm1 -; KNL-NEXT: vpsraw $15, %ymm1, %ymm1 +; KNL-NEXT: vpor %ymm1, %ymm0, %ymm0 ; KNL-NEXT: vpsllw $15, %ymm0, %ymm0 ; KNL-NEXT: vpsraw $15, %ymm0, %ymm0 -; KNL-NEXT: vpor %ymm1, %ymm0, %ymm0 ; KNL-NEXT: vpmovsxwd %ymm0, %zmm0 ; KNL-NEXT: vptestmd %zmm0, %zmm0, %k0 ; KNL-NEXT: kortestw %k0, %k0 @@ -2545,20 +2528,18 @@ define i1 @allzeros_v16i8_and4(<16 x i8> %arg) { define i1 @allones_v32i8_and4(<32 x i8> %arg) { ; SSE-LABEL: allones_v32i8_and4: ; SSE: # %bb.0: +; SSE-NEXT: pand %xmm1, %xmm0 ; SSE-NEXT: psllw $5, %xmm0 -; SSE-NEXT: psllw $5, %xmm1 -; SSE-NEXT: pand %xmm0, %xmm1 -; SSE-NEXT: pmovmskb %xmm1, %eax +; SSE-NEXT: pmovmskb %xmm0, %eax ; SSE-NEXT: cmpw $-1, %ax ; SSE-NEXT: sete %al ; SSE-NEXT: retq ; ; AVX1-LABEL: allones_v32i8_and4: ; AVX1: # %bb.0: -; AVX1-NEXT: vpsllw $5, %xmm0, %xmm1 -; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 +; AVX1-NEXT: vpand %xmm0, %xmm1, %xmm0 ; AVX1-NEXT: vpsllw $5, %xmm0, %xmm0 -; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 ; AVX1-NEXT: vpmovmskb %xmm0, %eax ; AVX1-NEXT: cmpw $-1, %ax ; AVX1-NEXT: sete %al @@ -2610,9 +2591,8 @@ define i1 @allzeros_v32i8_and4(<32 x i8> %arg) { ; AVX1-LABEL: allzeros_v32i8_and4: ; AVX1: # %bb.0: ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 -; AVX1-NEXT: vpsllw $5, %xmm1, %xmm1 -; AVX1-NEXT: vpsllw $5, %xmm0, %xmm0 ; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsllw $5, %xmm0, %xmm0 ; AVX1-NEXT: vpmovmskb %xmm0, %eax ; AVX1-NEXT: testl %eax, %eax ; AVX1-NEXT: sete %al @@ -2654,14 +2634,11 @@ define i1 @allzeros_v32i8_and4(<32 x i8> %arg) { define i1 @allones_v64i8_and4(<64 x i8> %arg) { ; SSE-LABEL: allones_v64i8_and4: ; SSE: # %bb.0: -; SSE-NEXT: psllw $5, %xmm1 -; SSE-NEXT: psllw $5, %xmm3 +; SSE-NEXT: pand %xmm2, %xmm0 +; SSE-NEXT: pand %xmm1, %xmm0 +; SSE-NEXT: pand %xmm3, %xmm0 ; SSE-NEXT: psllw $5, %xmm0 -; SSE-NEXT: psllw $5, %xmm2 -; SSE-NEXT: pand %xmm0, %xmm2 -; SSE-NEXT: pand %xmm1, %xmm2 -; SSE-NEXT: pand %xmm3, %xmm2 -; SSE-NEXT: pmovmskb %xmm2, %eax +; SSE-NEXT: pmovmskb %xmm0, %eax ; SSE-NEXT: cmpw $-1, %ax ; SSE-NEXT: sete %al ; SSE-NEXT: retq @@ -2669,14 +2646,11 @@ define i1 @allones_v64i8_and4(<64 x i8> %arg) { ; AVX1-LABEL: allones_v64i8_and4: ; AVX1: # %bb.0: ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 -; AVX1-NEXT: vpsllw $5, %xmm2, %xmm2 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm3 -; AVX1-NEXT: vpsllw $5, %xmm3, %xmm3 -; AVX1-NEXT: vpsllw $5, %xmm0, %xmm0 -; AVX1-NEXT: vpsllw $5, %xmm1, %xmm1 ; AVX1-NEXT: vpand %xmm0, %xmm1, %xmm0 ; AVX1-NEXT: vpand %xmm0, %xmm2, %xmm0 ; AVX1-NEXT: vpand %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsllw $5, %xmm0, %xmm0 ; AVX1-NEXT: vpmovmskb %xmm0, %eax ; AVX1-NEXT: cmpw $-1, %ax ; AVX1-NEXT: sete %al @@ -2685,9 +2659,8 @@ define i1 @allones_v64i8_and4(<64 x i8> %arg) { ; ; AVX2-LABEL: allones_v64i8_and4: ; AVX2: # %bb.0: -; AVX2-NEXT: vpsllw $5, %ymm0, %ymm0 -; AVX2-NEXT: vpsllw $5, %ymm1, %ymm1 ; AVX2-NEXT: vpand %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsllw $5, %ymm0, %ymm0 ; AVX2-NEXT: vpmovmskb %ymm0, %eax ; AVX2-NEXT: cmpl $-1, %eax ; AVX2-NEXT: sete %al @@ -2696,10 +2669,9 @@ define i1 @allones_v64i8_and4(<64 x i8> %arg) { ; ; KNL-LABEL: allones_v64i8_and4: ; KNL: # %bb.0: -; KNL-NEXT: vpsllw $5, %ymm0, %ymm1 -; KNL-NEXT: vextracti64x4 $1, %zmm0, %ymm0 +; KNL-NEXT: vextracti64x4 $1, %zmm0, %ymm1 +; KNL-NEXT: vpand %ymm0, %ymm1, %ymm0 ; KNL-NEXT: vpsllw $5, %ymm0, %ymm0 -; KNL-NEXT: vpand %ymm1, %ymm0, %ymm0 ; KNL-NEXT: vpmovmskb %ymm0, %eax ; KNL-NEXT: cmpl $-1, %eax ; KNL-NEXT: sete %al @@ -2734,15 +2706,12 @@ define i1 @allzeros_v64i8_and4(<64 x i8> %arg) { ; ; AVX1-LABEL: allzeros_v64i8_and4: ; AVX1: # %bb.0: -; AVX1-NEXT: vpsllw $5, %xmm1, %xmm2 -; AVX1-NEXT: vpsllw $5, %xmm0, %xmm3 -; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 -; AVX1-NEXT: vpsllw $5, %xmm1, %xmm1 -; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 -; AVX1-NEXT: vpsllw $5, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 +; AVX1-NEXT: vpor %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vpor %xmm2, %xmm1, %xmm1 ; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 -; AVX1-NEXT: vpor %xmm0, %xmm2, %xmm0 -; AVX1-NEXT: vpor %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsllw $5, %xmm0, %xmm0 ; AVX1-NEXT: vpmovmskb %xmm0, %eax ; AVX1-NEXT: testl %eax, %eax ; AVX1-NEXT: sete %al @@ -2762,9 +2731,8 @@ define i1 @allzeros_v64i8_and4(<64 x i8> %arg) { ; KNL-LABEL: allzeros_v64i8_and4: ; KNL: # %bb.0: ; KNL-NEXT: vextracti64x4 $1, %zmm0, %ymm1 -; KNL-NEXT: vpsllw $5, %ymm1, %ymm1 -; KNL-NEXT: vpsllw $5, %ymm0, %ymm0 ; KNL-NEXT: vpor %ymm1, %ymm0, %ymm0 +; KNL-NEXT: vpsllw $5, %ymm0, %ymm0 ; KNL-NEXT: vpmovmskb %ymm0, %eax ; KNL-NEXT: testl %eax, %eax ; KNL-NEXT: sete %al @@ -3052,11 +3020,9 @@ define i1 @allzeros_v32i16_and4(<32 x i16> %arg) { ; KNL-LABEL: allzeros_v32i16_and4: ; KNL: # %bb.0: ; KNL-NEXT: vextracti64x4 $1, %zmm0, %ymm1 -; KNL-NEXT: vpsllw $13, %ymm1, %ymm1 -; KNL-NEXT: vpsraw $15, %ymm1, %ymm1 +; KNL-NEXT: vpor %ymm1, %ymm0, %ymm0 ; KNL-NEXT: vpsllw $13, %ymm0, %ymm0 ; KNL-NEXT: vpsraw $15, %ymm0, %ymm0 -; KNL-NEXT: vpor %ymm1, %ymm0, %ymm0 ; KNL-NEXT: vpmovsxwd %ymm0, %zmm0 ; KNL-NEXT: vptestmd %zmm0, %zmm0, %k0 ; KNL-NEXT: kortestw %k0, %k0 diff --git a/llvm/test/CodeGen/X86/vector-ext-logic.ll b/llvm/test/CodeGen/X86/vector-ext-logic.ll index a26d7e9486f1cb..cfbc83d5e84e6f 100644 --- a/llvm/test/CodeGen/X86/vector-ext-logic.ll +++ b/llvm/test/CodeGen/X86/vector-ext-logic.ll @@ -198,10 +198,9 @@ define <8 x i16> @sext_and_v8i16(<8 x i8> %x, <8 x i8> %y) { ; SSE2-LABEL: sext_and_v8i16: ; SSE2: # %bb.0: ; SSE2-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7] -; SSE2-NEXT: psraw $8, %xmm2 ; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7] -; SSE2-NEXT: psraw $8, %xmm0 ; SSE2-NEXT: pand %xmm2, %xmm0 +; SSE2-NEXT: psraw $8, %xmm0 ; SSE2-NEXT: retq ; ; AVX2-LABEL: sext_and_v8i16: @@ -220,10 +219,9 @@ define <8 x i16> @sext_or_v8i16(<8 x i8> %x, <8 x i8> %y) { ; SSE2-LABEL: sext_or_v8i16: ; SSE2: # %bb.0: ; SSE2-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7] -; SSE2-NEXT: psraw $8, %xmm2 ; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7] -; SSE2-NEXT: psraw $8, %xmm0 ; SSE2-NEXT: por %xmm2, %xmm0 +; SSE2-NEXT: psraw $8, %xmm0 ; SSE2-NEXT: retq ; ; AVX2-LABEL: sext_or_v8i16: @@ -242,10 +240,9 @@ define <8 x i16> @sext_xor_v8i16(<8 x i8> %x, <8 x i8> %y) { ; SSE2-LABEL: sext_xor_v8i16: ; SSE2: # %bb.0: ; SSE2-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7] -; SSE2-NEXT: psraw $8, %xmm2 ; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7] -; SSE2-NEXT: psraw $8, %xmm0 ; SSE2-NEXT: pxor %xmm2, %xmm0 +; SSE2-NEXT: psraw $8, %xmm0 ; SSE2-NEXT: retq ; ; AVX2-LABEL: sext_xor_v8i16: @@ -338,34 +335,27 @@ define <8 x i32> @bool_zext_xor(<8 x i1> %x, <8 x i1> %y) { define <8 x i32> @bool_sext_and(<8 x i1> %x, <8 x i1> %y) { ; SSE2-LABEL: bool_sext_and: ; SSE2: # %bb.0: -; SSE2-NEXT: movdqa %xmm1, %xmm2 -; SSE2-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0,0,1,1,2,2,3,3] -; SSE2-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4,4,5,5,6,6,7,7] -; SSE2-NEXT: movdqa %xmm0, %xmm3 -; SSE2-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0,0,1,1,2,2,3,3] -; SSE2-NEXT: punpckhwd {{.*#+}} xmm0 = xmm0[4,4,5,5,6,6,7,7] +; SSE2-NEXT: movdqa %xmm1, %xmm3 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4,4,5,5,6,6,7,7] +; SSE2-NEXT: movdqa %xmm0, %xmm2 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm2 = xmm2[4,4,5,5,6,6,7,7] +; SSE2-NEXT: pand %xmm3, %xmm2 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3] +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] +; SSE2-NEXT: pand %xmm1, %xmm0 ; SSE2-NEXT: pslld $31, %xmm0 ; SSE2-NEXT: psrad $31, %xmm0 -; SSE2-NEXT: pslld $31, %xmm3 -; SSE2-NEXT: psrad $31, %xmm3 -; SSE2-NEXT: pslld $31, %xmm1 -; SSE2-NEXT: psrad $31, %xmm1 -; SSE2-NEXT: pand %xmm0, %xmm1 ; SSE2-NEXT: pslld $31, %xmm2 ; SSE2-NEXT: psrad $31, %xmm2 -; SSE2-NEXT: pand %xmm3, %xmm2 -; SSE2-NEXT: movdqa %xmm2, %xmm0 +; SSE2-NEXT: movdqa %xmm2, %xmm1 ; SSE2-NEXT: retq ; ; AVX2-LABEL: bool_sext_and: ; AVX2: # %bb.0: -; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm0 ; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero ; AVX2-NEXT: vpslld $31, %ymm0, %ymm0 ; AVX2-NEXT: vpsrad $31, %ymm0, %ymm0 -; AVX2-NEXT: vpslld $31, %ymm1, %ymm1 -; AVX2-NEXT: vpsrad $31, %ymm1, %ymm1 -; AVX2-NEXT: vpand %ymm1, %ymm0, %ymm0 ; AVX2-NEXT: retq %xs = sext <8 x i1> %x to <8 x i32> %ys = sext <8 x i1> %y to <8 x i32> @@ -376,34 +366,27 @@ define <8 x i32> @bool_sext_and(<8 x i1> %x, <8 x i1> %y) { define <8 x i32> @bool_sext_or(<8 x i1> %x, <8 x i1> %y) { ; SSE2-LABEL: bool_sext_or: ; SSE2: # %bb.0: -; SSE2-NEXT: movdqa %xmm1, %xmm2 -; SSE2-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0,0,1,1,2,2,3,3] -; SSE2-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4,4,5,5,6,6,7,7] -; SSE2-NEXT: movdqa %xmm0, %xmm3 -; SSE2-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0,0,1,1,2,2,3,3] -; SSE2-NEXT: punpckhwd {{.*#+}} xmm0 = xmm0[4,4,5,5,6,6,7,7] +; SSE2-NEXT: movdqa %xmm1, %xmm3 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4,4,5,5,6,6,7,7] +; SSE2-NEXT: movdqa %xmm0, %xmm2 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm2 = xmm2[4,4,5,5,6,6,7,7] +; SSE2-NEXT: por %xmm3, %xmm2 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3] +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] +; SSE2-NEXT: por %xmm1, %xmm0 ; SSE2-NEXT: pslld $31, %xmm0 ; SSE2-NEXT: psrad $31, %xmm0 -; SSE2-NEXT: pslld $31, %xmm3 -; SSE2-NEXT: psrad $31, %xmm3 -; SSE2-NEXT: pslld $31, %xmm1 -; SSE2-NEXT: psrad $31, %xmm1 -; SSE2-NEXT: por %xmm0, %xmm1 ; SSE2-NEXT: pslld $31, %xmm2 ; SSE2-NEXT: psrad $31, %xmm2 -; SSE2-NEXT: por %xmm3, %xmm2 -; SSE2-NEXT: movdqa %xmm2, %xmm0 +; SSE2-NEXT: movdqa %xmm2, %xmm1 ; SSE2-NEXT: retq ; ; AVX2-LABEL: bool_sext_or: ; AVX2: # %bb.0: -; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; AVX2-NEXT: vpor %xmm1, %xmm0, %xmm0 ; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero ; AVX2-NEXT: vpslld $31, %ymm0, %ymm0 ; AVX2-NEXT: vpsrad $31, %ymm0, %ymm0 -; AVX2-NEXT: vpslld $31, %ymm1, %ymm1 -; AVX2-NEXT: vpsrad $31, %ymm1, %ymm1 -; AVX2-NEXT: vpor %ymm1, %ymm0, %ymm0 ; AVX2-NEXT: retq %xs = sext <8 x i1> %x to <8 x i32> %ys = sext <8 x i1> %y to <8 x i32> @@ -414,34 +397,27 @@ define <8 x i32> @bool_sext_or(<8 x i1> %x, <8 x i1> %y) { define <8 x i32> @bool_sext_xor(<8 x i1> %x, <8 x i1> %y) { ; SSE2-LABEL: bool_sext_xor: ; SSE2: # %bb.0: -; SSE2-NEXT: movdqa %xmm1, %xmm2 -; SSE2-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0,0,1,1,2,2,3,3] -; SSE2-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4,4,5,5,6,6,7,7] -; SSE2-NEXT: movdqa %xmm0, %xmm3 -; SSE2-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0,0,1,1,2,2,3,3] -; SSE2-NEXT: punpckhwd {{.*#+}} xmm0 = xmm0[4,4,5,5,6,6,7,7] +; SSE2-NEXT: movdqa %xmm1, %xmm3 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4,4,5,5,6,6,7,7] +; SSE2-NEXT: movdqa %xmm0, %xmm2 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm2 = xmm2[4,4,5,5,6,6,7,7] +; SSE2-NEXT: pxor %xmm3, %xmm2 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3] +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] +; SSE2-NEXT: pxor %xmm1, %xmm0 ; SSE2-NEXT: pslld $31, %xmm0 ; SSE2-NEXT: psrad $31, %xmm0 -; SSE2-NEXT: pslld $31, %xmm3 -; SSE2-NEXT: psrad $31, %xmm3 -; SSE2-NEXT: pslld $31, %xmm1 -; SSE2-NEXT: psrad $31, %xmm1 -; SSE2-NEXT: pxor %xmm0, %xmm1 ; SSE2-NEXT: pslld $31, %xmm2 ; SSE2-NEXT: psrad $31, %xmm2 -; SSE2-NEXT: pxor %xmm3, %xmm2 -; SSE2-NEXT: movdqa %xmm2, %xmm0 +; SSE2-NEXT: movdqa %xmm2, %xmm1 ; SSE2-NEXT: retq ; ; AVX2-LABEL: bool_sext_xor: ; AVX2: # %bb.0: -; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 ; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero ; AVX2-NEXT: vpslld $31, %ymm0, %ymm0 ; AVX2-NEXT: vpsrad $31, %ymm0, %ymm0 -; AVX2-NEXT: vpslld $31, %ymm1, %ymm1 -; AVX2-NEXT: vpsrad $31, %ymm1, %ymm1 -; AVX2-NEXT: vpxor %ymm1, %ymm0, %ymm0 ; AVX2-NEXT: retq %xs = sext <8 x i1> %x to <8 x i32> %ys = sext <8 x i1> %y to <8 x i32>