From: Dan Gohman Date: Tue, 11 Aug 2009 22:40:09 +0000 (+0000) Subject: Remove the hack that turns sdiv by a power of 2 to ashr, and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=df1109434abd465a4db2e6f69ec2688866660367;p=clang Remove the hack that turns sdiv by a power of 2 to ashr, and use the new "exact" sdiv to allow LLVM optimization to perform this transformation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78739 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index e761e9f3c7..f8fae42301 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1184,19 +1184,12 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) { // Optimize out the shift for element size of 1. if (ElementSize == 1) return BytesBetween; - - // HACK: LLVM doesn't have an divide instruction that 'knows' there is no - // remainder. As such, we handle common power-of-two cases here to generate - // better code. See PR2247. - if (llvm::isPowerOf2_64(ElementSize)) { - Value *ShAmt = - llvm::ConstantInt::get(ResultType, llvm::Log2_64(ElementSize)); - return Builder.CreateAShr(BytesBetween, ShAmt, "sub.ptr.shr"); - } - - // Otherwise, do a full sdiv. + + // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since + // pointer difference in C is only defined in the case where both + // operands are pointing to elements of an array. Value *BytesPerElt = llvm::ConstantInt::get(ResultType, ElementSize); - return Builder.CreateSDiv(BytesBetween, BytesPerElt, "sub.ptr.div"); + return Builder.CreateExactSDiv(BytesBetween, BytesPerElt, "sub.ptr.div"); } }