From: Daniel Dunbar Date: Tue, 5 Aug 2008 00:47:03 +0000 (+0000) Subject: Bug fix, CodeGen of (void*) - (void*) was broken. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=820b03398fdcc8f1f6c60ace55b708e311fa8ce4;p=clang Bug fix, CodeGen of (void*) - (void*) was broken. - git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54338 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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"); } diff --git a/test/CodeGen/2008-08-04-void-pointer-arithmetic.c b/test/CodeGen/2008-08-04-void-pointer-arithmetic.c new file mode 100644 index 0000000000..fc54dcac5e --- /dev/null +++ b/test/CodeGen/2008-08-04-void-pointer-arithmetic.c @@ -0,0 +1,6 @@ +// RUN: clang --emit-llvm -o - %s +// + +int f0(void *a, void *b) { + return a - b; +}