Similar to what was done for masked load and gather.
llvm-svn: 362342
}
SDValue DAGCombiner::visitMSCATTER(SDNode *N) {
- if (Level >= AfterLegalizeTypes)
- return SDValue();
-
MaskedScatterSDNode *MSC = cast<MaskedScatterSDNode>(N);
SDValue Mask = MSC->getMask();
- SDValue Data = MSC->getValue();
+ SDValue Data = MSC->getValue();
+ SDValue Chain = MSC->getChain();
SDLoc DL(N);
+ // Zap scatters with a zero mask.
+ if (ISD::isBuildVectorAllZeros(Mask.getNode()))
+ return Chain;
+
+ if (Level >= AfterLegalizeTypes)
+ return SDValue();
+
// If the MSCATTER data type requires splitting and the mask is provided by a
// SETCC, then split both nodes and its operands before legalization. This
// prevents the type legalizer from unrolling SETCC into scalar comparisons
EVT LoVT, HiVT;
std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MSC->getValueType(0));
- SDValue Chain = MSC->getChain();
-
EVT MemoryVT = MSC->getMemoryVT();
unsigned Alignment = MSC->getOriginalAlignment();
}
SDValue DAGCombiner::visitMSTORE(SDNode *N) {
- if (Level >= AfterLegalizeTypes)
- return SDValue();
-
MaskedStoreSDNode *MST = cast<MaskedStoreSDNode>(N);
SDValue Mask = MST->getMask();
- SDValue Data = MST->getValue();
+ SDValue Data = MST->getValue();
+ SDValue Chain = MST->getChain();
EVT VT = Data.getValueType();
SDLoc DL(N);
+ // Zap masked stores with a zero mask.
+ if (ISD::isBuildVectorAllZeros(Mask.getNode()))
+ return Chain;
+
+ if (Level >= AfterLegalizeTypes)
+ return SDValue();
+
// If the MSTORE data type requires splitting and the mask is provided by a
// SETCC, then split both nodes and its operands before legalization. This
// prevents the type legalizer from unrolling SETCC into scalar comparisons
SDValue MaskLo, MaskHi, Lo, Hi;
std::tie(MaskLo, MaskHi) = SplitVSETCC(Mask.getNode(), DAG);
- SDValue Chain = MST->getChain();
SDValue Ptr = MST->getBasePtr();
EVT MemoryVT = MST->getMemoryVT();
}
define void @zero_mask(<2 x double>%a1, <2 x double*> %ptr) {
-; KNL_64-LABEL: zero_mask:
-; KNL_64: # %bb.0:
-; KNL_64-NEXT: # kill: def $xmm1 killed $xmm1 def $zmm1
-; KNL_64-NEXT: # kill: def $xmm0 killed $xmm0 def $zmm0
-; KNL_64-NEXT: kxorw %k0, %k0, %k1
-; KNL_64-NEXT: vscatterqpd %zmm0, (,%zmm1) {%k1}
-; KNL_64-NEXT: vzeroupper
-; KNL_64-NEXT: retq
-;
-; KNL_32-LABEL: zero_mask:
-; KNL_32: # %bb.0:
-; KNL_32-NEXT: # kill: def $xmm0 killed $xmm0 def $zmm0
-; KNL_32-NEXT: vpsllq $32, %xmm1, %xmm1
-; KNL_32-NEXT: vpsraq $32, %zmm1, %zmm1
-; KNL_32-NEXT: kxorw %k0, %k0, %k1
-; KNL_32-NEXT: vscatterqpd %zmm0, (,%zmm1) {%k1}
-; KNL_32-NEXT: vzeroupper
-; KNL_32-NEXT: retl
-;
-; SKX-LABEL: zero_mask:
-; SKX: # %bb.0:
-; SKX-NEXT: kxorw %k0, %k0, %k1
-; SKX-NEXT: vscatterqpd %xmm0, (,%xmm1) {%k1}
-; SKX-NEXT: retq
-;
-; SKX_32-LABEL: zero_mask:
-; SKX_32: # %bb.0:
-; SKX_32-NEXT: vpsllq $32, %xmm1, %xmm1
-; SKX_32-NEXT: vpsraq $32, %xmm1, %xmm1
-; SKX_32-NEXT: kxorw %k0, %k0, %k1
-; SKX_32-NEXT: vscatterqpd %xmm0, (,%xmm1) {%k1}
-; SKX_32-NEXT: retl
+; ALL-LABEL: zero_mask:
+; ALL: # %bb.0:
+; ALL-NEXT: ret{{[l|q]}}
call void @llvm.masked.scatter.v2f64.v2p0f64(<2 x double> %a1, <2 x double*> %ptr, i32 4, <2 x i1> zeroinitializer)
ret void
}
; SSE: ## %bb.0:
; SSE-NEXT: retq
;
-; AVX1OR2-LABEL: zero_mask:
-; AVX1OR2: ## %bb.0:
-; AVX1OR2-NEXT: vxorpd %xmm1, %xmm1, %xmm1
-; AVX1OR2-NEXT: vmaskmovpd %xmm0, %xmm1, (%rdi)
-; AVX1OR2-NEXT: retq
-;
-; AVX512F-LABEL: zero_mask:
-; AVX512F: ## %bb.0:
-; AVX512F-NEXT: ## kill: def $xmm0 killed $xmm0 def $zmm0
-; AVX512F-NEXT: kxorw %k0, %k0, %k1
-; AVX512F-NEXT: vmovupd %zmm0, (%rdi) {%k1}
-; AVX512F-NEXT: vzeroupper
-; AVX512F-NEXT: retq
-;
-; AVX512VL-LABEL: zero_mask:
-; AVX512VL: ## %bb.0:
-; AVX512VL-NEXT: kxorw %k0, %k0, %k1
-; AVX512VL-NEXT: vmovupd %xmm0, (%rdi) {%k1}
-; AVX512VL-NEXT: retq
+; AVX-LABEL: zero_mask:
+; AVX: ## %bb.0:
+; AVX-NEXT: retq
call void @llvm.masked.store.v2f64.p0v2f64(<2 x double> %val, <2 x double>* %addr, i32 4, <2 x i1> zeroinitializer)
ret void
}