Index: lib/Transforms/Utils/IntegerDivision.cpp =================================================================== --- lib/Transforms/Utils/IntegerDivision.cpp +++ lib/Transforms/Utils/IntegerDivision.cpp @@ -182,6 +182,8 @@ Function *F = IBB->getParent(); Function *CTLZ = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz, DivTy); + Function *CTTZ = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz, + DivTy); // Our CFG is going to look like: // +---------------------+ @@ -234,7 +236,7 @@ // Same instructions are generated for both i32 (msb 31) and i64 (msb 63). // First off, check for special cases: dividend or divisor is zero, divisor - // is greater than dividend, and divisor is 1. + // is greater than dividend, and divisor is a power of 2. // ; special-cases: // ; %ret0_1 = icmp eq i32 %divisor, 0 // ; %ret0_2 = icmp eq i32 %dividend, 0 @@ -244,8 +246,11 @@ // ; %sr = sub nsw i32 %tmp0, %tmp1 // ; %ret0_4 = icmp ugt i32 %sr, 31 // ; %ret0 = or i1 %ret0_3, %ret0_4 - // ; %retDividend = icmp eq i32 %sr, 31 - // ; %retVal = select i1 %ret0, i32 0, i32 %dividend + // ; %tmp14 = tail call i32 @llvm.cttz.i32(i32 %divisor, i1 true) + // ; %tmp15 = add i32 %tmp0, %tmp14 + // ; %retDividend = icmp eq i32 %tmp15, 31 + // ; %dividend_1 = lshr i32 %dividend, %tmp14 + // ; %retVal = select i1 %ret0, i32 0, i32 %dividend_1 // ; %earlyRet = or i1 %ret0, %retDividend // ; br i1 %earlyRet, label %end, label %bb1 Builder.SetInsertPoint(SpecialCases); @@ -257,8 +262,11 @@ Value *SR = Builder.CreateSub(Tmp0, Tmp1); Value *Ret0_4 = Builder.CreateICmpUGT(SR, MSB); Value *Ret0 = Builder.CreateOr(Ret0_3, Ret0_4); - Value *RetDividend = Builder.CreateICmpEQ(SR, MSB); - Value *RetVal = Builder.CreateSelect(Ret0, Zero, Dividend); + Value *Tmp14 = Builder.CreateCall(CTTZ, {Divisor, True}); + Value *Tmp15 = Builder.CreateAdd(Tmp0, Tmp14); + Value *RetDividend = Builder.CreateICmpEQ(Tmp15, MSB); + Value *Dividend_1 = Builder.CreateLShr(Dividend, Tmp14); + Value *RetVal = Builder.CreateSelect(Ret0, Zero, Dividend_1); Value *EarlyRet = Builder.CreateOr(Ret0, RetDividend); Builder.CreateCondBr(EarlyRet, End, BB1);