<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Jan 17, 2018, 5:56 PM Rafael Avila de Espindola <<a href="mailto:rafael.espindola@gmail.com">rafael.espindola@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Reid Kleckner <<a href="mailto:rnk@google.com" target="_blank" rel="noreferrer">rnk@google.com</a>> writes:<br>
<br>
>> Index: lib/Target/X86/X86ISelLowering.cpp<br>
>> > ===================================================================<br>
>> > --- lib/Target/X86/X86ISelLowering.cpp<br>
>> > +++ lib/Target/X86/X86ISelLowering.cpp<br>
>> > @@ -3732,11 +3732,23 @@<br>
>> >      }<br>
>> >    } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))<br>
>> {<br>
>> >      const Module *Mod = DAG.getMachineFunction().<br>
>> getFunction().getParent();<br>
>> > -    unsigned char OpFlags =<br>
>> > -        Subtarget.classifyGlobalFunctionReference(nullptr, *Mod);<br>
>> > +    // If PLT must be avoided then the call should be via GOTPCREL.<br>
>> > +    unsigned char OpFlags = X86II::MO_GOTPCREL;<br>
>> > +<br>
>> > +    if (!Mod->getAvoidPLT()) {<br>
>> > +      OpFlags = Subtarget.classifyGlobalFunctionReference(nullptr,<br>
>> *Mod);<br>
>> > +    }<br>
>> ><br>
>> >      Callee = DAG.getTargetExternalSymbol(<br>
>> >          S->getSymbol(), getPointerTy(DAG.getDataLayout()), OpFlags);<br>
>> > +<br>
>> > +    if (OpFlags == X86II::MO_GOTPCREL) {<br>
>> > +      Callee = DAG.getNode(X86ISD::WrapperRIP, dl,<br>
>> > +          getPointerTy(DAG.getDataLayout()), Callee);<br>
>> > +      Callee = DAG.getLoad(<br>
>> > +          getPointerTy(DAG.getDataLayout()), dl, DAG.getEntryNode(),<br>
>> Callee,<br>
>> > +          MachinePointerInfo::getGOT(DAG.getMachineFunction()));<br>
>> > +    }<br>
>><br>
>> The logic should be added to shouldAssumeDSOLocal.<br>
>><br>
><br>
> We might need to extend shouldAssumeDSOLocal to know that we are calling a<br>
> function. We only have an ExternalSymbol in this case, not a GlobalValue,<br>
> so GV there will be null.<br>
<br>
My memory in these areas is fuzzy. Do we never create a GV for a call to<br>
an intrinsic or do we lose it at some point in the codegen path? If it is<br>
lost, could we track it a bit longer?<br>
<br>
For this patch, is there any other case when GV is null? If that only<br>
happens when calling an intrinsic shouldAssumeDSOLocal can use that to<br>
know that it is a call.<br>
<br>
Maybe it can always return false if GV is null?<br>
<br>
There are 3 ways of calling a function:<br>
<br>
call foo<br>
call foo@plt<br>
call *foo@got<br>
<br>
if shouldAssumeDSOLocal returns true, we are supposed to use the first<br>
one. If it returns false, one of the last two.<br>
<br>
Now, "call "foo" is almost identical to "call foo@plt" as the linker can<br>
convert plt calls if the target is local. If the only case when GV is<br>
null is a call to an intrinsic, it is safe to return false.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">It looks like that's the case. However it looks pretty ugly. Also if we do decide to go down this path we need to figure out where to add the nonlazybind attribute to the intrinsic. </div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Cheers,<br>
Rafael<br>
</blockquote></div></div></div>