summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-08-11 22:40:09 +0000
committerDan Gohman <gohman@apple.com>2009-08-11 22:40:09 +0000
commit1cebe567354972233d9a473f22d47980519d042c (patch)
tree82dead535f0d1fe0c6d04b4145fad742fbc7e8d5
parentabdcbc7ef2ecfcc821a02d5a3094cd6374d1fa8f (diff)
downloadbcm5719-llvm-1cebe567354972233d9a473f22d47980519d042c.tar.gz
bcm5719-llvm-1cebe567354972233d9a473f22d47980519d042c.zip
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. llvm-svn: 78739
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp17
1 files changed, 5 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index e761e9f3c7d..f8fae423015 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/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");
}
}
OpenPOWER on IntegriCloud