diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index ad4c95287761..fb1d30b28e12 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -32142,8 +32142,7 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG, cast(AndNode.getOperand(1))->getAPIntValue() == 1) { // LHS and RHS swapped due to // setcc outputting 1 when AND resulted in 0 and vice versa. - if (AndNode.getValueType() != MVT::i8) - AndNode = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, AndNode); + AndNode = DAG.getZExtOrTrunc(AndNode, DL, MVT::i8); return DAG.getNode(ISD::SELECT, DL, VT, AndNode, RHS, LHS); } } diff --git a/llvm/test/CodeGen/X86/combine-select.ll b/llvm/test/CodeGen/X86/combine-select.ll index 58be308f505b..7cbb9831ba9a 100644 --- a/llvm/test/CodeGen/X86/combine-select.ll +++ b/llvm/test/CodeGen/X86/combine-select.ll @@ -105,3 +105,23 @@ entry: %6 = insertelement <4 x float> %a, float %5, i32 0 ret <4 x float> %6 } + +; Make sure we don't crash trying to truncate the and instruction i4->i8. We need to extend instead. +define <4 x float> @select_mask_add_ss_small_mask_type(<4 x float> %w, i4 %u, <4 x float> %a, <4 x float> %b) { +; CHECK-LABEL: select_mask_add_ss_small_mask_type: +; CHECK: ## %bb.0: ## %entry +; CHECK-NEXT: kmovw %edi, %k1 +; CHECK-NEXT: vaddss %xmm2, %xmm1, %xmm0 {%k1} +; CHECK-NEXT: retq +entry: + %0 = extractelement <4 x float> %b, i32 0 + %1 = extractelement <4 x float> %a, i32 0 + %2 = fadd float %1, %0 + %3 = and i4 %u, 1 + %4 = icmp eq i4 %3, 0 + %5 = extractelement <4 x float> %w, i32 0 + %6 = select i1 %4, float %5, float %2 + %7 = insertelement <4 x float> %a, float %6, i32 0 + ret <4 x float> %7 +} +