]> granicus.if.org Git - clang/commitdiff
Remove the hack that turns sdiv by a power of 2 to ashr, and
authorDan Gohman <gohman@apple.com>
Tue, 11 Aug 2009 22:40:09 +0000 (22:40 +0000)
committerDan Gohman <gohman@apple.com>
Tue, 11 Aug 2009 22:40:09 +0000 (22:40 +0000)
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

lib/CodeGen/CGExprScalar.cpp

index e761e9f3c7d373f18f02f2fc969f9d647f35a978..f8fae42301533f7b6a0d137238156fb164637e64 100644 (file)
@@ -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");
   }
 }