diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3703,7 +3703,13 @@ case ISD::UDIV: { Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1); Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1); - Known = KnownBits::udiv(Known, Known2); + Known = KnownBits::udiv(Known, Known2, Op->getFlags().hasExact()); + break; + } + case ISD::SDIV: { + Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1); + Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1); + Known = KnownBits::sdiv(Known, Known2, Op->getFlags().hasExact()); break; } case ISD::SREM: { diff --git a/llvm/test/CodeGen/X86/knownbits-div.ll b/llvm/test/CodeGen/X86/knownbits-div.ll --- a/llvm/test/CodeGen/X86/knownbits-div.ll +++ b/llvm/test/CodeGen/X86/knownbits-div.ll @@ -4,11 +4,7 @@ define i8 @sdiv_neg_neg_high_bits(i8 %x, i8 %y) { ; CHECK-LABEL: sdiv_neg_neg_high_bits: ; CHECK: # %bb.0: -; CHECK-NEXT: orb $-128, %dil -; CHECK-NEXT: orb $-125, %sil -; CHECK-NEXT: movsbl %dil, %eax -; CHECK-NEXT: idivb %sil -; CHECK-NEXT: andb $-128, %al +; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: retq %num = or i8 %x, 128 %denum = or i8 %y, 131 @@ -20,11 +16,7 @@ define i8 @sdiv_exact_odd_odd(i8 %x, i8 %y) { ; CHECK-LABEL: sdiv_exact_odd_odd: ; CHECK: # %bb.0: -; CHECK-NEXT: orb $1, %dil -; CHECK-NEXT: orb $1, %sil -; CHECK-NEXT: movsbl %dil, %eax -; CHECK-NEXT: idivb %sil -; CHECK-NEXT: andb $1, %al +; CHECK-NEXT: movb $1, %al ; CHECK-NEXT: retq %num = or i8 %x, 1 %denum = or i8 %y, 1 @@ -52,11 +44,7 @@ define i8 @udiv_exact_even_odd(i8 %x, i8 %y) { ; CHECK-LABEL: udiv_exact_even_odd: ; CHECK: # %bb.0: -; CHECK-NEXT: andb $-2, %dil -; CHECK-NEXT: orb $1, %sil -; CHECK-NEXT: movzbl %dil, %eax -; CHECK-NEXT: divb %sil -; CHECK-NEXT: andb $1, %al +; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: retq %num = and i8 %x, -2 %denum = or i8 %y, 1