diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 48c918051bb1..1518efd12567 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -8084,13 +8084,17 @@ SDValue DAGCombiner::visitMSTORE(SDNode *N) { } SDValue DAGCombiner::visitMGATHER(SDNode *N) { - if (Level >= AfterLegalizeTypes) - return SDValue(); - MaskedGatherSDNode *MGT = cast(N); SDValue Mask = MGT->getMask(); SDLoc DL(N); + // Zap gathers with a zero mask. + if (ISD::isBuildVectorAllZeros(Mask.getNode())) + return CombineTo(N, MGT->getPassThru(), MGT->getChain()); + + if (Level >= AfterLegalizeTypes) + return SDValue(); + // If the MGATHER result 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 diff --git a/llvm/test/CodeGen/X86/avx2-masked-gather.ll b/llvm/test/CodeGen/X86/avx2-masked-gather.ll index 3a831a88aa67..c119e1282886 100644 --- a/llvm/test/CodeGen/X86/avx2-masked-gather.ll +++ b/llvm/test/CodeGen/X86/avx2-masked-gather.ll @@ -769,3 +769,24 @@ entry: ret <2 x double> %res } + +define <2 x double> @masked_gather_zeromask(<2 x double*>* %ptr, <2 x double> %dummy, <2 x double> %passthru) { +; X86-LABEL: masked_gather_zeromask: +; X86: # %bb.0: # %entry +; X86-NEXT: vmovaps %xmm1, %xmm0 +; X86-NEXT: retl +; +; X64-LABEL: masked_gather_zeromask: +; X64: # %bb.0: # %entry +; X64-NEXT: vmovaps %xmm1, %xmm0 +; X64-NEXT: retq +; +; NOGATHER-LABEL: masked_gather_zeromask: +; NOGATHER: # %bb.0: # %entry +; NOGATHER-NEXT: vmovaps %xmm1, %xmm0 +; NOGATHER-NEXT: retq +entry: + %ld = load <2 x double*>, <2 x double*>* %ptr + %res = call <2 x double> @llvm.masked.gather.v2double(<2 x double*> %ld, i32 0, <2 x i1> zeroinitializer, <2 x double> %passthru) + ret <2 x double> %res +}