diff options
-rw-r--r-- | include/llvm/CodeGen/ISDOpcodes.h | 2 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 35 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 37 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrFragmentsSIMD.td | 72 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrSSE.td | 349 |
5 files changed, 494 insertions, 1 deletions
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 578e074..2e23f4e 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -603,7 +603,7 @@ namespace ISD { /// which do not reference a specific memory location should be less than /// this value. Those that do must not be less than this value, and can /// be used with SelectionDAG::getMemIntrinsicNode. - static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+100; + static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+150; //===--------------------------------------------------------------------===// /// MemIndexedMode enum - This enum defines the load / store indexed diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 2f0710f..bff1ce5 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -8093,6 +8093,41 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { case X86ISD::MUL_IMM: return "X86ISD::MUL_IMM"; case X86ISD::PTEST: return "X86ISD::PTEST"; case X86ISD::TESTP: return "X86ISD::TESTP"; + case X86ISD::PALIGN: return "X86ISD::PALIGN"; + case X86ISD::PSHUFD: return "X86ISD::PSHUFD"; + case X86ISD::PSHUFHW: return "X86ISD::PSHUFHW"; + case X86ISD::PSHUFHW_LD: return "X86ISD::PSHUFHW_LD"; + case X86ISD::PSHUFLW: return "X86ISD::PSHUFLW"; + case X86ISD::PSHUFLW_LD: return "X86ISD::PSHUFLW_LD"; + case X86ISD::SHUFPS: return "X86ISD::SHUFPS"; + case X86ISD::SHUFPD: return "X86ISD::SHUFPD"; + case X86ISD::MOVLHPS: return "X86ISD::MOVLHPS"; + case X86ISD::MOVHLPS: return "X86ISD::MOVHLPS"; + case X86ISD::MOVLHPD: return "X86ISD::MOVLHPD"; + case X86ISD::MOVHLPD: return "X86ISD::MOVHLPD"; + case X86ISD::MOVHPS: return "X86ISD::MOVHPS"; + case X86ISD::MOVLPS: return "X86ISD::MOVLPS"; + case X86ISD::MOVHPD: return "X86ISD::MOVHPD"; + case X86ISD::MOVLPD: return "X86ISD::MOVLPD"; + case X86ISD::MOVDDUP: return "X86ISD::MOVDDUP"; + case X86ISD::MOVSHDUP: return "X86ISD::MOVSHDUP"; + case X86ISD::MOVSLDUP: return "X86ISD::MOVSLDUP"; + case X86ISD::MOVSHDUP_LD: return "X86ISD::MOVSHDUP_LD"; + case X86ISD::MOVSLDUP_LD: return "X86ISD::MOVSLDUP_LD"; + case X86ISD::MOVSD: return "X86ISD::MOVSD"; + case X86ISD::MOVSS: return "X86ISD::MOVSS"; + case X86ISD::UNPCKLPS: return "X86ISD::UNPCKLPS"; + case X86ISD::UNPCKLPD: return "X86ISD::UNPCKLPD"; + case X86ISD::UNPCKHPS: return "X86ISD::UNPCKHPS"; + case X86ISD::UNPCKHPD: return "X86ISD::UNPCKHPD"; + case X86ISD::PUNPCKLBW: return "X86ISD::PUNPCKLBW"; + case X86ISD::PUNPCKLWD: return "X86ISD::PUNPCKLWD"; + case X86ISD::PUNPCKLDQ: return "X86ISD::PUNPCKLDQ"; + case X86ISD::PUNPCKLQDQ: return "X86ISD::PUNPCKLQDQ"; + case X86ISD::PUNPCKHBW: return "X86ISD::PUNPCKHBW"; + case X86ISD::PUNPCKHWD: return "X86ISD::PUNPCKHWD"; + case X86ISD::PUNPCKHDQ: return "X86ISD::PUNPCKHDQ"; + case X86ISD::PUNPCKHQDQ: return "X86ISD::PUNPCKHQDQ"; case X86ISD::VASTART_SAVE_XMM_REGS: return "X86ISD::VASTART_SAVE_XMM_REGS"; case X86ISD::MINGW_ALLOCA: return "X86ISD::MINGW_ALLOCA"; } diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 61e304d..7791f9a 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -251,6 +251,43 @@ namespace llvm { // TESTP - Vector packed fp sign bitwise comparisons TESTP, + // Several flavors of instructions with vector shuffle behaviors. + PALIGN, + PSHUFD, + PSHUFHW, + PSHUFLW, + PSHUFHW_LD, + PSHUFLW_LD, + SHUFPD, + SHUFPS, + MOVDDUP, + MOVSHDUP, + MOVSLDUP, + MOVSHDUP_LD, + MOVSLDUP_LD, + MOVLHPS, + MOVHLPS, + MOVLHPD, + MOVHLPD, + MOVHPS, + MOVHPD, + MOVLPS, + MOVLPD, + MOVSD, + MOVSS, + UNPCKLPS, + UNPCKLPD, + UNPCKHPS, + UNPCKHPD, + PUNPCKLBW, + PUNPCKLWD, + PUNPCKLDQ, + PUNPCKLQDQ, + PUNPCKHBW, + PUNPCKHWD, + PUNPCKHDQ, + PUNPCKHQDQ, + // VASTART_SAVE_XMM_REGS - Save xmm argument registers to the stack, // according to %al. An operator is needed so that this can be expanded // with control flow. diff --git a/lib/Target/X86/X86InstrFragmentsSIMD.td b/lib/Target/X86/X86InstrFragmentsSIMD.td index 63fef61..7ddf689 100644 --- a/lib/Target/X86/X86InstrFragmentsSIMD.td +++ b/lib/Target/X86/X86InstrFragmentsSIMD.td @@ -122,6 +122,78 @@ def SDTX86CmpPTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, def X86ptest : SDNode<"X86ISD::PTEST", SDTX86CmpPTest>; def X86testp : SDNode<"X86ISD::TESTP", SDTX86CmpPTest>; +// Specific shuffle nodes - At some point ISD::VECTOR_SHUFFLE will always get +// translated into one of the target nodes below during lowering. +// Note: this is a work in progress... +def SDTShuff1Op : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisSameAs<0,1>]>; +def SDTShuff2Op : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0,1>, + SDTCisSameAs<0,2>]>; + +def SDTShuff2OpI : SDTypeProfile<1, 2, [SDTCisVec<0>, + SDTCisSameAs<0,1>, SDTCisInt<2>]>; +def SDTShuff3OpI : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0,1>, + SDTCisSameAs<0,2>, SDTCisInt<3>]>; + +def SDTShuff1OpLd : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisPtrTy<1>]>; +def SDTShuff2OpLd : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0,1>, + SDTCisPtrTy<2>]>; + +def SDTShuff2OpLdI : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisPtrTy<1>, + SDTCisInt<2>]>; + +def X86PAlign : SDNode<"X86ISD::PALIGN", SDTShuff3OpI>; + +def X86PShufd : SDNode<"X86ISD::PSHUFD", SDTShuff2OpI>; +def X86PShufhw : SDNode<"X86ISD::PSHUFHW", SDTShuff2OpI>; +def X86PShuflw : SDNode<"X86ISD::PSHUFLW", SDTShuff2OpI>; + +def X86PShufhwLd : SDNode<"X86ISD::PSHUFHW_LD", SDTShuff2OpLdI>; +def X86PShuflwLd : SDNode<"X86ISD::PSHUFLW_LD", SDTShuff2OpLdI>; + +def X86Shufpd : SDNode<"X86ISD::SHUFPD", SDTShuff3OpI>; +def X86Shufps : SDNode<"X86ISD::SHUFPS", SDTShuff3OpI>; + +def X86Movddup : SDNode<"X86ISD::MOVDDUP", SDTShuff1Op>; +def X86Movshdup : SDNode<"X86ISD::MOVSHDUP", SDTShuff1Op>; +def X86Movsldup : SDNode<"X86ISD::MOVSLDUP", SDTShuff1Op>; + +def X86MovshdupLd : SDNode<"X86ISD::MOVSHDUP_LD", SDTShuff1OpLd, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; +def X86MovsldupLd : SDNode<"X86ISD::MOVSLDUP_LD", SDTShuff1OpLd, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; + +def X86Movsd : SDNode<"X86ISD::MOVSD", SDTShuff2Op>; +def X86Movss : SDNode<"X86ISD::MOVSS", SDTShuff2Op>; + +def X86Movlhps : SDNode<"X86ISD::MOVLHPS", SDTShuff2Op>; +def X86Movhlps : SDNode<"X86ISD::MOVHLPS", SDTShuff2Op>; +def X86Movlhpd : SDNode<"X86ISD::MOVLHPD", SDTShuff2Op>; +def X86Movhlpd : SDNode<"X86ISD::MOVHLPD", SDTShuff2Op>; + +def X86MovhpsLd : SDNode<"X86ISD::MOVHPS", SDTShuff2OpLd, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; +def X86MovhpdLd : SDNode<"X86ISD::MOVHPD", SDTShuff2OpLd, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; +def X86MovlpsLd : SDNode<"X86ISD::MOVLPS", SDTShuff2OpLd, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; +def X86MovlpdLd : SDNode<"X86ISD::MOVLPD", SDTShuff2OpLd, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; + +def X86Unpcklps : SDNode<"X86ISD::UNPCKLPS", SDTShuff2Op>; +def X86Unpcklpd : SDNode<"X86ISD::UNPCKLPD", SDTShuff2Op>; +def X86Unpckhps : SDNode<"X86ISD::UNPCKHPS", SDTShuff2Op>; +def X86Unpckhpd : SDNode<"X86ISD::UNPCKHPD", SDTShuff2Op>; + +def X86Punpcklbw : SDNode<"X86ISD::PUNPCKLBW", SDTShuff2Op>; +def X86Punpcklwd : SDNode<"X86ISD::PUNPCKLWD", SDTShuff2Op>; +def X86Punpckldq : SDNode<"X86ISD::PUNPCKLDQ", SDTShuff2Op>; +def X86Punpcklqdq : SDNode<"X86ISD::PUNPCKLQDQ", SDTShuff2Op>; + +def X86Punpckhbw : SDNode<"X86ISD::PUNPCKHBW", SDTShuff2Op>; +def X86Punpckhwd : SDNode<"X86ISD::PUNPCKHWD", SDTShuff2Op>; +def X86Punpckhdq : SDNode<"X86ISD::PUNPCKHDQ", SDTShuff2Op>; +def X86Punpckhqdq : SDNode<"X86ISD::PUNPCKHQDQ", SDTShuff2Op>; + //===----------------------------------------------------------------------===// // SSE Complex Patterns //===----------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index 5aee9dd..5949a38 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -5585,3 +5585,352 @@ def : Pat<(int_x86_avx_vperm2f128_si_256 VR256:$src1, (memopv8i32 addr:$src2), imm:$src3), (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>; +//===----------------------------------------------------------------------===// +// SSE Shuffle pattern fragments +//===----------------------------------------------------------------------===// + +// This is part of a "work in progress" refactoring. The idea is that all +// vector shuffles are going to be translated into target specific nodes and +// directly matched by the patterns below (which can be changed along the way) +// The AVX version of some but not all of them are described here, and more +// should come in a near future. + +// Shuffle with PSHUFD instruction folding loads. The first two patterns match +// SSE2 loads, which are always promoted to v2i64. The last one should match +// the SSE1 case, where the only legal load is v4f32, but there is no PSHUFD +// in SSE2, how does it ever worked? Anyway, the pattern will remain here until +// we investigate further. +def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)), + (i8 imm:$imm))), + (VPSHUFDmi addr:$src1, imm:$imm)>, Requires<[HasAVX]>; +def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)), + (i8 imm:$imm))), + (PSHUFDmi addr:$src1, imm:$imm)>; +def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv4f32 addr:$src1)), + (i8 imm:$imm))), + (PSHUFDmi addr:$src1, imm:$imm)>; // FIXME: has this ever worked? + +// Shuffle with PSHUFD instruction. +def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))), + (VPSHUFDri VR128:$src1, imm:$imm)>, Requires<[HasAVX]>; +def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))), + (PSHUFDri VR128:$src1, imm:$imm)>; + +def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))), + (VPSHUFDri VR128:$src1, imm:$imm)>, Requires<[HasAVX]>; +def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))), + (PSHUFDri VR128:$src1, imm:$imm)>; + +// Shuffle with SHUFPD instruction. +def : Pat<(v2f64 (X86Shufps VR128:$src1, + (memopv2f64 addr:$src2), (i8 imm:$imm))), + (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>, Requires<[HasAVX]>; +def : Pat<(v2f64 (X86Shufps VR128:$src1, + (memopv2f64 addr:$src2), (i8 imm:$imm))), + (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>; + +def : Pat<(v2i64 (X86Shufpd VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>, Requires<[HasAVX]>; +def : Pat<(v2i64 (X86Shufpd VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>; + +def : Pat<(v2f64 (X86Shufpd VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>, Requires<[HasAVX]>; +def : Pat<(v2f64 (X86Shufpd VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>; + +// Shuffle with SHUFPS instruction. +def : Pat<(v4f32 (X86Shufps VR128:$src1, + (memopv4f32 addr:$src2), (i8 imm:$imm))), + (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>, Requires<[HasAVX]>; +def : Pat<(v4f32 (X86Shufps VR128:$src1, + (memopv4f32 addr:$src2), (i8 imm:$imm))), + (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>; + +def : Pat<(v4f32 (X86Shufps VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>, Requires<[HasAVX]>; +def : Pat<(v4f32 (X86Shufps VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>; + +def : Pat<(v4i32 (X86Shufps VR128:$src1, + (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))), + (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>, Requires<[HasAVX]>; +def : Pat<(v4i32 (X86Shufps VR128:$src1, + (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))), + (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>; + +def : Pat<(v4i32 (X86Shufps VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>, Requires<[HasAVX]>; +def : Pat<(v4i32 (X86Shufps VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>; + +// Shuffle with MOVLHPS instruction +def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)), + (VMOVLHPSrr (v4f32 VR128:$src1), VR128:$src2)>, Requires<[HasAVX]>; +def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)), + (MOVLHPSrr (v4f32 VR128:$src1), VR128:$src2)>; + +def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)), + (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>, Requires<[HasAVX]>; +def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)), + (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>; + +def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)), + (VMOVLHPSrr VR128:$src1, VR128:$src2)>, Requires<[HasAVX]>; +def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)), + (MOVLHPSrr VR128:$src1, VR128:$src2)>; + +// Shuffle with MOVHLPS instruction +def : Pat<(v4f32 (X86Movhlps VR128:$src1, VR128:$src2)), + (MOVHLPSrr VR128:$src1, VR128:$src2)>; +def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)), + (MOVHLPSrr VR128:$src1, VR128:$src2)>; + +// Shuffle with MOVDDUP instruction +def : Pat<(X86Movddup (memopv2f64 addr:$src)), + (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>; +def : Pat<(X86Movddup (memopv2f64 addr:$src)), + (MOVDDUPrm addr:$src)>; + +def : Pat<(X86Movddup (bc_v4f32 (memopv2f64 addr:$src))), + (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>; +def : Pat<(X86Movddup (bc_v4f32 (memopv2f64 addr:$src))), + (MOVDDUPrm addr:$src)>; + +def : Pat<(X86Movddup (memopv2i64 addr:$src)), + (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>; +def : Pat<(X86Movddup (memopv2i64 addr:$src)), + (MOVDDUPrm addr:$src)>; + +def : Pat<(X86Movddup (bc_v4i32 (memopv2i64 addr:$src))), + (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>; +def : Pat<(X86Movddup (bc_v4i32 (memopv2i64 addr:$src))), + (MOVDDUPrm addr:$src)>; + +def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))), + (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>; +def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))), + (MOVDDUPrm addr:$src)>; + +def : Pat<(X86Movddup (bc_v2f64 + (v2i64 (scalar_to_vector (loadi64 addr:$src))))), + (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>; +def : Pat<(X86Movddup (bc_v2f64 + (v2i64 (scalar_to_vector (loadi64 addr:$src))))), + (MOVDDUPrm addr:$src)>; + +// Shuffle with UNPCKLPS +def : Pat<(v4f32 (X86Unpcklps VR128:$src1, (memopv4f32 addr:$src2))), + (VUNPCKLPSrm VR128:$src1, addr:$src2)>, Requires<[HasAVX]>; +def : Pat<(v4f32 (X86Unpcklps VR128:$src1, (memopv4f32 addr:$src2))), + (UNPCKLPSrm VR128:$src1, addr:$src2)>; + +def : Pat<(v4f32 (X86Unpcklps VR128:$src1, VR128:$src2)), + (VUNPCKLPSrr VR128:$src1, VR128:$src2)>, Requires<[HasAVX]>; +def : Pat<(v4f32 (X86Unpcklps VR128:$src1, VR128:$src2)), + (UNPCKLPSrr VR128:$src1, VR128:$src2)>; + +// Shuffle with UNPCKHPS +def : Pat<(v4f32 (X86Unpckhps VR128:$src1, (memopv4f32 addr:$src2))), + (VUNPCKHPSrm VR128:$src1, addr:$src2)>, Requires<[HasAVX]>; +def : Pat<(v4f32 (X86Unpckhps VR128:$src1, (memopv4f32 addr:$src2))), + (UNPCKHPSrm VR128:$src1, addr:$src2)>; + +def : Pat<(v4f32 (X86Unpckhps VR128:$src1, VR128:$src2)), + (VUNPCKHPSrr VR128:$src1, VR128:$src2)>, Requires<[HasAVX]>; +def : Pat<(v4f32 (X86Unpckhps VR128:$src1, VR128:$src2)), + (UNPCKHPSrr VR128:$src1, VR128:$src2)>; + +// Shuffle with UNPCKLPD +def : Pat<(v2f64 (X86Unpcklpd VR128:$src1, (memopv2f64 addr:$src2))), + (VUNPCKLPSrm VR128:$src1, addr:$src2)>, Requires<[HasAVX]>; +def : Pat<(v2f64 (X86Unpcklpd VR128:$src1, (memopv2f64 addr:$src2))), + (UNPCKLPSrm VR128:$src1, addr:$src2)>; + +def : Pat<(v2f64 (X86Unpcklpd VR128:$src1, VR128:$src2)), + (VUNPCKLPDrr VR128:$src1, VR128:$src2)>, Requires<[HasAVX]>; +def : Pat<(v2f64 (X86Unpcklpd VR128:$src1, VR128:$src2)), + (UNPCKLPDrr VR128:$src1, VR128:$src2)>; + +// Shuffle with UNPCKHPD +def : Pat<(v2f64 (X86Unpckhpd VR128:$src1, (memopv2f64 addr:$src2))), + (VUNPCKLPSrm VR128:$src1, addr:$src2)>, Requires<[HasAVX]>; +def : Pat<(v2f64 (X86Unpckhpd VR128:$src1, (memopv2f64 addr:$src2))), + (UNPCKLPSrm VR128:$src1, addr:$src2)>; + +def : Pat<(v2f64 (X86Unpckhpd VR128:$src1, VR128:$src2)), + (VUNPCKHPDrr VR128:$src1, VR128:$src2)>, Requires<[HasAVX]>; +def : Pat<(v2f64 (X86Unpckhpd VR128:$src1, VR128:$src2)), + (UNPCKHPDrr VR128:$src1, VR128:$src2)>; + +// Shuffle with PUNPCKLBW +def : Pat<(v16i8 (X86Punpcklbw VR128:$src1, + (bc_v16i8 (memopv2i64 addr:$src2)))), + (PUNPCKLBWrm VR128:$src1, addr:$src2)>; +def : Pat<(v16i8 (X86Punpcklbw VR128:$src1, VR128:$src2)), + (PUNPCKLBWrr VR128:$src1, VR128:$src2)>; + +// Shuffle with PUNPCKLWD +def : Pat<(v8i16 (X86Punpcklwd VR128:$src1, + (bc_v8i16 (memopv2i64 addr:$src2)))), + (PUNPCKLWDrm VR128:$src1, addr:$src2)>; +def : Pat<(v8i16 (X86Punpcklwd VR128:$src1, VR128:$src2)), + (PUNPCKLWDrr VR128:$src1, VR128:$src2)>; + +// Shuffle with PUNPCKLDQ +def : Pat<(v4i32 (X86Punpckldq VR128:$src1, + (bc_v4i32 (memopv2i64 addr:$src2)))), + (PUNPCKLDQrm VR128:$src1, addr:$src2)>; +def : Pat<(v4i32 (X86Punpckldq VR128:$src1, VR128:$src2)), + (PUNPCKLDQrr VR128:$src1, VR128:$src2)>; + +// Shuffle with PUNPCKLQDQ +def : Pat<(v2i64 (X86Punpcklqdq VR128:$src1, (memopv2i64 addr:$src2))), + (PUNPCKLQDQrm VR128:$src1, addr:$src2)>; +def : Pat<(v2i64 (X86Punpcklqdq VR128:$src1, VR128:$src2)), + (PUNPCKLQDQrr VR128:$src1, VR128:$src2)>; + +// Shuffle with PUNPCKHBW +def : Pat<(v16i8 (X86Punpckhbw VR128:$src1, + (bc_v16i8 (memopv2i64 addr:$src2)))), + (PUNPCKHBWrm VR128:$src1, addr:$src2)>; +def : Pat<(v16i8 (X86Punpckhbw VR128:$src1, VR128:$src2)), + (PUNPCKHBWrr VR128:$src1, VR128:$src2)>; + +// Shuffle with PUNPCKHWD +def : Pat<(v8i16 (X86Punpckhwd VR128:$src1, + (bc_v8i16 (memopv2i64 addr:$src2)))), + (PUNPCKHWDrm VR128:$src1, addr:$src2)>; +def : Pat<(v8i16 (X86Punpckhwd VR128:$src1, VR128:$src2)), + (PUNPCKHWDrr VR128:$src1, VR128:$src2)>; + +// Shuffle with PUNPCKHDQ +def : Pat<(v4i32 (X86Punpckhdq VR128:$src1, + (bc_v4i32 (memopv2i64 addr:$src2)))), + (PUNPCKHDQrm VR128:$src1, addr:$src2)>; +def : Pat<(v4i32 (X86Punpckhdq VR128:$src1, VR128:$src2)), + (PUNPCKHDQrr VR128:$src1, VR128:$src2)>; + +// Shuffle with PUNPCKHQDQ +def : Pat<(v2i64 (X86Punpckhqdq VR128:$src1, (memopv2i64 addr:$src2))), + (PUNPCKHQDQrm VR128:$src1, addr:$src2)>; +def : Pat<(v2i64 (X86Punpckhqdq VR128:$src1, VR128:$src2)), + (PUNPCKHQDQrr VR128:$src1, VR128:$src2)>; + +// Shuffle with MOVHPS +def : Pat<(v4f32 (X86MovhpsLd VR128:$src1, addr:$src2)), + (MOVHPSrm VR128:$src1, addr:$src2)>; +def : Pat<(v4i32 (X86MovhpsLd VR128:$src1, addr:$src2)), + (MOVHPSrm VR128:$src1, addr:$src2)>; + +// Shuffle with MOVHPD +def : Pat<(v2f64 (X86MovhpdLd VR128:$src1, addr:$src2)), + (MOVHPDrm VR128:$src1, addr:$src2)>; + +// Shuffle with MOVLPS +def : Pat<(v4f32 (X86MovlpsLd VR128:$src1, addr:$src2)), + (MOVLPSrm VR128:$src1, addr:$src2)>; +def : Pat<(v4i32 (X86MovlpsLd VR128:$src1, addr:$src2)), + (MOVLPSrm VR128:$src1, addr:$src2)>; + +// Shuffle with MOVLPD +def : Pat<(v2f64 (X86MovlpdLd VR128:$src1, addr:$src2)), + (MOVLPDrm VR128:$src1, addr:$src2)>; +def : Pat<(v2i64 (X86MovlpdLd VR128:$src1, addr:$src2)), + (MOVLPDrm VR128:$src1, addr:$src2)>; + +// Shuffle with MOVSS +def : Pat<(v4f32 (X86Movss VR128:$src1, (scalar_to_vector FR32:$src2))), + (MOVSSrr VR128:$src1, FR32:$src2)>; +def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)), + (MOVSSrr (v4i32 VR128:$src1), + (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>; +def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)), + (MOVSSrr (v4f32 VR128:$src1), + (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>; + +// Shuffle with MOVSD +def : Pat<(v2f64 (X86Movsd VR128:$src1, (scalar_to_vector FR64:$src2))), + (MOVSDrr VR128:$src1, FR64:$src2)>; +def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)), + (MOVSDrr (v2i64 VR128:$src1), + (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>; +def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)), + (MOVSDrr (v2f64 VR128:$src1), + (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>; +def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)), + (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>; +def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)), + (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>; + +// Shuffle with MOVSHDUP +def : Pat<(v4i32 (X86Movshdup VR128:$src)), + (MOVSHDUPrr VR128:$src)>; +def : Pat<(v4i32 (X86MovshdupLd addr:$src)), + (MOVSHDUPrm addr:$src)>; + +def : Pat<(v4f32 (X86Movshdup VR128:$src)), + (MOVSHDUPrr VR128:$src)>; +def : Pat<(v4f32 (X86MovshdupLd addr:$src)), + (MOVSHDUPrm addr:$src)>; + +// Shuffle with MOVSLDUP +def : Pat<(v4i32 (X86Movsldup VR128:$src)), + (MOVSLDUPrr VR128:$src)>; +def : Pat<(v4i32 (X86MovsldupLd addr:$src)), + (MOVSLDUPrm addr:$src)>; + +def : Pat<(v4f32 (X86Movsldup VR128:$src)), + (MOVSLDUPrr VR128:$src)>; +def : Pat<(v4f32 (X86MovsldupLd addr:$src)), + (MOVSLDUPrm addr:$src)>; + +// Shuffle with PSHUFHW +def : Pat<(v8i16 (X86PShufhwLd addr:$src, (i8 imm:$imm))), + (PSHUFHWmi addr:$src, imm:$imm)>; +def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))), + (PSHUFHWri VR128:$src, imm:$imm)>; + +// Shuffle with PSHUFLW +def : Pat<(v8i16 (X86PShuflwLd addr:$src, (i8 imm:$imm))), + (PSHUFLWmi addr:$src, imm:$imm)>; +def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))), + (PSHUFLWri VR128:$src, imm:$imm)>; + +// Shuffle with PALIGN +def : Pat<(v1i64 (X86PAlign VR64:$src1, VR64:$src2, (i8 imm:$imm))), + (PALIGNR64rr VR64:$src2, VR64:$src1, imm:$imm)>; +def : Pat<(v2i32 (X86PAlign VR64:$src1, VR64:$src2, (i8 imm:$imm))), + (PALIGNR64rr VR64:$src2, VR64:$src1, imm:$imm)>; +def : Pat<(v4i16 (X86PAlign VR64:$src1, VR64:$src2, (i8 imm:$imm))), + (PALIGNR64rr VR64:$src2, VR64:$src1, imm:$imm)>; +def : Pat<(v8i8 (X86PAlign VR64:$src1, VR64:$src2, (i8 imm:$imm))), + (PALIGNR64rr VR64:$src2, VR64:$src1, imm:$imm)>; + +def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>; +def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>; +def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>; +def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))), + (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>; + +// Extra patterns to match stores +def : Pat<(store (f64 (vector_extract + (v2f64 (X86Unpckhps VR128:$src, (undef))), (iPTR 0))),addr:$dst), + (MOVHPSmr addr:$dst, VR128:$src)>; +def : Pat<(store (f64 (vector_extract + (v2f64 (X86Unpckhpd VR128:$src, (undef))), (iPTR 0))),addr:$dst), + (MOVHPDmr addr:$dst, VR128:$src)>; + +def : Pat<(store (v2f64 (X86MovlpdLd VR128:$src1, addr:$src2)),addr:$src2), + (MOVLPDmr addr:$src2, VR128:$src1)>; +def : Pat<(store (v2i64 (X86MovlpdLd VR128:$src1, addr:$src2)),addr:$src2), + (MOVLPDmr addr:$src2, VR128:$src1)>; + +def : Pat<(store (v4f32 (X86MovlpsLd VR128:$src1, addr:$src2)),addr:$src2), + (MOVLPSmr addr:$src2, VR128:$src1)>; +def : Pat<(store (v4i32 (X86MovlpsLd VR128:$src1, addr:$src2)),addr:$src2), + (MOVLPSmr addr:$src2, VR128:$src1)>; + |