aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2008-08-05 00:47:03 +0000
committerDaniel Dunbar <daniel@zuster.org>2008-08-05 00:47:03 +0000
commit820b03398fdcc8f1f6c60ace55b708e311fa8ce4 (patch)
treec137700a96c5570a3a88e39a981a9df48ec6f1a7 /lib/CodeGen/CGExprScalar.cpp
parent4489fe10fa073eb326e2c8906db170f009050911 (diff)
Bug fix, CodeGen of (void*) - (void*) was broken.
- <rdar://problem/6122967> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54338 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--lib/CodeGen/CGExprScalar.cpp15
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index e8adc59e9f..1f5324d71d 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -851,6 +851,8 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
}
+ // The GNU void* - int case is automatically handled here because
+ // our LLVM type for void* is i8*.
return Builder.CreateGEP(Ops.LHS, Idx, "sub.ptr");
}
@@ -866,19 +868,26 @@ Value *ScalarExprEmitter::VisitBinSub(const BinaryOperator *E) {
const QualType LHSType = E->getLHS()->getType();
const QualType LHSElementType = LHSType->getAsPointerType()->getPointeeType();
- uint64_t ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8;
+ uint64_t ElementSize;
+
+ // Handle GCC extension for pointer arithmetic on void* types.
+ if (LHSElementType->isVoidType()) {
+ ElementSize = 1;
+ } else {
+ ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8;
+ }
const llvm::Type *ResultType = ConvertType(E->getType());
LHS = Builder.CreatePtrToInt(LHS, ResultType, "sub.ptr.lhs.cast");
RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
Value *BytesBetween = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
-
+
// 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.
if (llvm::isPowerOf2_64(ElementSize)) {
Value *ShAmt =
- llvm::ConstantInt::get(ResultType, llvm::Log2_64(ElementSize));
+ llvm::ConstantInt::get(ResultType, llvm::Log2_64(ElementSize));
return Builder.CreateAShr(BytesBetween, ShAmt, "sub.ptr.shr");
}