From e5ed15195b71b8fa440e67d49db0168bb58e4e8a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 11 Feb 2009 07:21:43 +0000 Subject: [PATCH] finish off codegen support for sub of pointer to functions, finishing off rdar://6520707 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64295 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExprScalar.cpp | 9 +++++++-- test/CodeGen/exprs.c | 7 +++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index b9dcc078d4..a94eef1151 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -965,8 +965,9 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) { uint64_t ElementSize; - // Handle GCC extension for pointer arithmetic on void* types. - if (LHSElementType->isVoidType()) { + // Handle GCC extension for pointer arithmetic on void* and function pointer + // types. + if (LHSElementType->isVoidType() || LHSElementType->isFunctionType()) { ElementSize = 1; } else { ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8; @@ -977,6 +978,10 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) { RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast"); Value *BytesBetween = Builder.CreateSub(LHS, RHS, "sub.ptr.sub"); + // 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. diff --git a/test/CodeGen/exprs.c b/test/CodeGen/exprs.c index 07a9158744..81742673c2 100644 --- a/test/CodeGen/exprs.c +++ b/test/CodeGen/exprs.c @@ -52,3 +52,10 @@ void eMaisUma() { if (*t) return; } + +// rdar://6520707 +void f0(void (*fp)(void), void (*fp2)(void)) { + int x = fp - fp2; +} + +