Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3128,11 +3128,11 @@ // X / 1 -> X // X % 1 -> 0 - if (N1C && N1C->isOne()) - return IsDiv ? N0 : DAG.getConstant(0, DL, VT); // If this is a boolean op (single-bit element type), we can't have // division-by-zero or remainder-by-zero, so assume the divisor is 1. // Similarly, if we're zero-extending a boolean divisor, then assume it's a 1. + if ((N1C && N1C->isOne()) || (VT.getScalarType() == MVT::i1)) + return IsDiv ? N0 : DAG.getConstant(0, DL, VT); return SDValue(); } Index: test/CodeGen/X86/combine-sdiv.ll =================================================================== --- test/CodeGen/X86/combine-sdiv.ll +++ test/CodeGen/X86/combine-sdiv.ll @@ -3284,3 +3284,21 @@ %1 = sdiv <16 x i8> %x, ret <16 x i8> %1 } + +define i1 @bool_sdiv(i1 %x, i1 %y) { +; CHECK-LABEL: bool_sdiv: +; CHECK: # %bb.0: +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NEXT: retq + %r = sdiv i1 %x, %y + ret i1 %r +} + +define <4 x i1> @boolvec_sdiv(<4 x i1> %x, <4 x i1> %y) { +; CHECK-LABEL: boolvec_sdiv: +; CHECK: # %bb.0: +; CHECK-NEXT: retq + %r = sdiv <4 x i1> %x, %y + ret <4 x i1> %r +} Index: test/CodeGen/X86/combine-srem.ll =================================================================== --- test/CodeGen/X86/combine-srem.ll +++ test/CodeGen/X86/combine-srem.ll @@ -458,3 +458,25 @@ %B6 = and i32 %B16, %B10 ret i32 %B6 } + +define i1 @bool_srem(i1 %x, i1 %y) { +; CHECK-LABEL: bool_srem: +; CHECK: # %bb.0: +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq + %r = srem i1 %x, %y + ret i1 %r +} +define <4 x i1> @boolvec_srem(<4 x i1> %x, <4 x i1> %y) { +; SSE-LABEL: boolvec_srem: +; SSE: # %bb.0: +; SSE-NEXT: xorps %xmm0, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: boolvec_srem: +; AVX: # %bb.0: +; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 +; AVX-NEXT: retq + %r = srem <4 x i1> %x, %y + ret <4 x i1> %r +} Index: test/CodeGen/X86/combine-udiv.ll =================================================================== --- test/CodeGen/X86/combine-udiv.ll +++ test/CodeGen/X86/combine-udiv.ll @@ -907,3 +907,21 @@ %1 = udiv <8 x i16> %a0, ret <8 x i16> %1 } + +define i1 @bool_udiv(i1 %x, i1 %y) { +; CHECK-LABEL: bool_udiv: +; CHECK: # %bb.0: +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NEXT: retq + %r = udiv i1 %x, %y + ret i1 %r +} + +define <4 x i1> @boolvec_udiv(<4 x i1> %x, <4 x i1> %y) { +; CHECK-LABEL: boolvec_udiv: +; CHECK: # %bb.0: +; CHECK-NEXT: retq + %r = udiv <4 x i1> %x, %y + ret <4 x i1> %r +} Index: test/CodeGen/X86/combine-urem.ll =================================================================== --- test/CodeGen/X86/combine-urem.ll +++ test/CodeGen/X86/combine-urem.ll @@ -379,3 +379,26 @@ %2 = urem <4 x i32> %x, %1 ret <4 x i32> %2 } + +define i1 @bool_srem(i1 %x, i1 %y) { +; CHECK-LABEL: bool_srem: +; CHECK: # %bb.0: +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq + %r = srem i1 %x, %y + ret i1 %r +} + +define <4 x i1> @boolvec_urem(<4 x i1> %x, <4 x i1> %y) { +; SSE-LABEL: boolvec_urem: +; SSE: # %bb.0: +; SSE-NEXT: xorps %xmm0, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: boolvec_urem: +; AVX: # %bb.0: +; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 +; AVX-NEXT: retq + %r = urem <4 x i1> %x, %y + ret <4 x i1> %r +}