[LLVMdev] should AlwaysInliner inline this case?

David Majnemer david.majnemer at gmail.com
Mon Jan 5 03:09:47 PST 2015


On Mon, Jan 5, 2015 at 1:40 AM, Pete Cooper <peter_cooper at apple.com> wrote:

> Hi lx, Philip
>
> I've seen an instcombine which helps with this situation. It fires when
> the function types on both sides of the bitcast have the same number of
> operands and compatible types. It then adds bitcasts on the arguments and
> removes the one on the called function.
>

It indeed does, InstCombiner::transformConstExprCastCall.


>
> I don't have IR to hand, but it would be worth passing your IR through
> instcombine to see if that helps you.
>

The following should be a sufficiently workable example of what we would
hope to transform.

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i32 @g(i32* %a) {
entry:
  %call = tail call i32 bitcast (i32 (i64)* @f to i32 (i32*)*)(i32* %a)
  ret i32 %call
}

declare i32 @f(i64)

define i32 @h(i64 %a) {
entry:
  %call = tail call i32 bitcast (i32 (i32*)* @g to i32 (i64)*)(i64 %a)
  ret i32 %call
}


>
> The idea of improving the inliner is also great, but you may find that
> it's needed for cases other than this one if i'm right about the
> instcombine.
>

Sadly, the combine fails because InstCombine
queries CastInst::isBitCastable to determine the castable-ness of the
parameter type and the argument type.  It isn't bitcastable though, it's
ptrtoint/inttoptr castable.

The following patch opens up the optimization:
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1456,7 +1456,7 @@ bool
InstCombiner::transformConstExprCastCall(CallSite CS) {
     Type *ParamTy = FT->getParamType(i);
     Type *ActTy = (*AI)->getType();

-    if (!CastInst::isBitCastable(ActTy, ParamTy))
+    if (!CastInst::isBitOrNoopPointerCastable(ActTy, ParamTy, DL))
       return false;   // Cannot transform this parameter value.

     if (AttrBuilder(CallerPAL.getParamAttributes(i + 1), i + 1).
@@ -1551,7 +1551,7 @@ bool
InstCombiner::transformConstExprCastCall(CallSite CS) {
     if ((*AI)->getType() == ParamTy) {
       Args.push_back(*AI);
     } else {
-      Args.push_back(Builder->CreateBitCast(*AI, ParamTy));
+      Args.push_back(Builder->CreateBitOrPointerCast(*AI, ParamTy));
     }

     // Add any parameter attributes.

Running opt -instcombine -inline -instcombine with this patch results in:
define i32 @g(i32* %a) {
entry:
  %0 = ptrtoint i32* %a to i64
  %call = tail call i32 @f(i64 %0)
  ret i32 %call
}

declare i32 @f(i64)

define i32 @h(i64 %a) {
entry:
  %call.i = tail call i32 @f(i64 %a)
  ret i32 %call.i
}


>
> Thanks
> Pete
>
> Sent from my iPhone
>
> On Jan 5, 2015, at 3:16 AM, Liu Xin <navy.xliu at gmail.com> wrote:
>
> Philip,
>
> I post here because I think AlwaysInliner should inline it. I want to
> detect the indirect calls for Inliner, and I want to hear inputs.
>
> let me define indirect call first in my idea. In one single expression,
> one function may be subject to bitcast more than one time. we can detect
> this situation and treat it as a regular call of last function, is that
> okay?
>
> thanks,
> --lx
>
>
> On Mon, Jan 5, 2015 at 7:32 AM, Philip Reames <listmail at philipreames.com>
> wrote:
>
>> On 01/04/2015 12:04 AM, Liu Xin wrote:
>>
>>>
>>> %294= callfloatbitcast (float(float, float*)* @__gpu_modff to
>>> float(float, i64)*)(float%293, i64 %preg.212.addr.0)
>>>
>>> as you may know, some gpu backends don't support function call. we need
>>> to make sure to inline all functions here. however, Inliner can not figure
>>> out that this is a valid callsite in this form. actually, it is.  in C
>>> words, cast a function and then call should be treat as callsite, right?
>>>
>>>  Generally, the inliner doesn't do much with indirect calls, but given
>> there is no simpler canonical case here, I expect we'll have to.
>>
>> Its possible we might even want to define this as a direct call. I'm not
>> sure what the expectations are with regards to the type of the function
>> being called and the type of the callsite.  I suspect a lot of code would
>> get confused if getCalledFunction returned __gpu_modff with it's unbitcast
>> type.  That's possibly something we should fix though.
>>
>> We'll want to get other folks input here, but a small patch to the
>> inliner to handle this case would seem reasonable to me.
>>
>> Philip
>>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150105/07d3bc01/attachment.html>


More information about the llvm-dev mailing list