> Well first, I would think the point of using __builtin is to specifically get 
> the intrinsic, and not use the library function.

The point, at the C level, is to get a certain set of semantics. The 
__builtin_* calls are marked as readnone in the IR, in theory giving them the 
desired semantics. As you point out below, this is likely not strong enough....

> I don’t think they are treated the same as libcalls in most situations, but 
> the current situation is not easy to follow. 

For optimizations in SimplifyLibCalls, we try to treat both the same way.

> First, I mostly care about targets that do not have calls and 
> TargetLibraryInfo isn’t particularly helpful or meaningful as is. I think if 
> there is an equivalent intrinsic for the library function, it should always 
> be used instead for consistency.

Interestingly, the only adjustment that TargetLibraryInfo makes for your target 
is:

  // There are no library implementations of mempcy and memset for r600 and
  // these can be difficult to lower in the backend.
  if (T.getArch() == Triple::r600) {
    TLI.setUnavailable(LibFunc::memcpy);
    TLI.setUnavailable(LibFunc::memset);
    TLI.setUnavailable(LibFunc::memset_pattern16);
    return;
  }

and so this probably does "work" for you -- but I do see your point. A true 
freestanding implementation might really not have these calls, and TLI might 
actually reflect that fact, rendering this scheme of using the libc calls (even 
marked as readnone) as suboptimal.

> The current state where a call is sometimes treated as an intrinsic and 
> sometimes isn't is pretty confusing (It’s also something else I probably need 
> to add support for for minnum / maxnum). Some places end up trying to 
> consider both forms, or some forget one or the other. 

Yes, in theory we try to locate all relevant optimizations inside of 
SimplifyLibCalls; perhaps in practice this does not quite capture everything.

> Maybe there should be a pass that translates all of the libcalls into 
> equivalent intrinsics?

I think this is a reasonable idea. It could be done inside of SimplifyLibCalls.

> Intrinsics are considered many more places than query TargetLibraryInfo, e.g. 
> isSafeToSpeculativelyExecute checks many intrinsics but no libcalls.

This is a good point. In theory we could do a better job at this for some known 
libcalls, but you're right, isSafeToSpeculativelyExecute does not return true 
for readnone functions, and noted in the function:

    return false; // The called function could have undefined behavior or
                  // side-effects, even if marked readnone nounwind.

as a side note, I've been thinking about adding some kind of "safe to 
speculate" metadata for loads/calls; this is another use case ;) Nevertheless, 
we could use TLI here too and specifically handle certain known libcalls.

> I’m also not sure how the call form interacts with -fno-builtin.

We nicely mark the functions as 'nobuiltin'. This is a bug. :(

> I don’t think a regular call can / is considered as a candidate for 
> vectorization, but the intrinsics are.

They certainly can be (when marked readnone) and are. The vectorizers handle 
the translation.

In short, I understand what you're saying, and I support canonicalizing on the 
intrinsics for these builtin operations. However, this would be a change to an 
established engineering decision, and I'd not approve this here without some 
discussion on llvmdev. Can you please write an RFC there? I want to make sure 
that everyone is on the same page.

http://reviews.llvm.org/D5896



_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to