This is an archive of the discontinued LLVM Phabricator instance.

[SimplifyLibCalls] Take size of int into consideration when emitting ldexp/ldexpf
ClosedPublic

Authored by bjope on Mar 26 2021, 1:08 PM.

Details

Summary

When rewriting

powf(2.0, itofp(x)) -> ldexpf(1.0, x)
exp2(sitofp(x)) -> ldexp(1.0, sext(x))
exp2(uitofp(x)) -> ldexp(1.0, zext(x))

the wrong type was used for the second argument in the ldexp/ldexpf
libc call, for target architectures with 16 bit "int" type.
The transform incorrectly used a bitcasted function pointer with
a 32-bit argument when emitting the ldexp/ldexpf call for such
targets.

The fault is solved by using the correct function prototype
in the call, by asking TargetLibraryInfo about the size of "int".
TargetLibraryInfo by default derives the size of the int type by
assuming that it is 16 bits for 16-bit architectures, and
32 bits otherwise. If this isn't true for a target it should be
possible to override that default in the TargetLibraryInfo
initializer.

Diff Detail

Event Timeline

bjope created this revision.Mar 26 2021, 1:08 PM
bjope requested review of this revision.Mar 26 2021, 1:08 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 26 2021, 1:08 PM
bjope added a comment.Apr 6 2021, 2:40 AM

Seems like there is little interest in this, but I was not sure really who to call for review from the beginning. Please let me know if you aren't interested in reviewing this by removing yourselves as reviewer (that way I know I need to find some other candidates).

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
1529

One thing that could be noticed is that emitBinaryFloatFnCall uses Module::getOrInsertFunction. Without this patch the getOrInsertFunction helper actually identifies that the function prototype is wrong, so it returns a function pointer that is bitcasted to the requested function pointer type. Isn't that weird in most cases, at least when we actually is emitting a call to the function?
I suspect that the bitcasted function pointer only is needed in certain scenarious when doing some kind of instrumentation (e.g. when the address is of interest rather than when one actually wants to emit a call to the function).

Maybe there should be a second flavor of Module::getOrInsertFunction that rather asserts when there is a mismatch rather than returning a bitcasted function pointer, that can be used in most cases, such as in emitBinaryFloatFnCall? That way problems like this could end up as ICE rather than miscompile.

The idea of introducing SizeOfInt to TargetLibraryInfo looks quite reasonable to me, although I am not too familiar with this part of target description.

Maybe @aykevl has some comments on this?

llvm/include/llvm/Analysis/TargetLibraryInfo.h
55

This initialization is probably redundant.

llvm/lib/Analysis/TargetLibraryInfo.cpp
1510

I wonder whether every support library implementation on every 16-bit target satisfies this. Another question is about other usages of ->isIntegerTy(32) in this file. Meanwhile, at least one such usage, for htonl/ntohl, seems to be exactly according to specification. Maybe this should be postponed to other patches (provided the issues can be detected easily enough).

Just as a note: there are 21 occurrences of inIntegerTy(32), 17 ones of isIntegerTy() (of any size) and even 1 isIntegerTy(16) (for htons/ntohs).

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
1780–1785

Shouldn't it be TLI->getIntSize() as well?

bjope added inline comments.Apr 12 2021, 1:52 AM
llvm/lib/Analysis/TargetLibraryInfo.cpp
1510

Yes, there are indeed more places that might need to be fixed. I figured it was easier to start off with only adding the framework for detecting "size of int" and used ldexp as a first use case.

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
1780–1785

This patch only fixes "ldexp" family of libcalls. I'm dealing with "powi" in D99439 (having this patch as parent).

I think you should ask on llvm-dev about this :)

bjope added a comment.Apr 12 2021, 1:37 PM

I think you should ask on llvm-dev about this :)

I actually started out by doing that a couple of weeks ago, https://lists.llvm.org/pipermail/llvm-dev/2021-March/149370.html , but there was very little reponse so I prepared these patches to get things/discussions going. But still not much response except @atrosinenko that thinks it might be reasonable to handle this some way (maybe like this).

I think that I at least need the blessing from someone familiar with MSP430 and AVR to move forward with this patch (and also D99439). Those are the only in-tree targets with non 32-bit int types afaict. Maybe MSP430 and AVR don't care about these libcalls? Then it should not be a problem for those targets either (if someone knows about that, then please let me know).

xbolva00 added inline comments.May 11 2021, 1:41 PM
llvm/include/llvm/Analysis/TargetLibraryInfo.h
55

Not resolved yet.

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
1780–1785

Can you add atleast fixme or todo?

llvm/test/Transforms/InstCombine/pow_fp_int.ll
2

Why this change?

bjope updated this revision to Diff 347009.May 21 2021, 6:29 AM

Rebased and addressed review comments.

bjope marked 4 inline comments as done.May 21 2021, 6:38 AM
bjope added inline comments.
llvm/test/Transforms/InstCombine/pow_fp_int.ll
2

The test case now depends on the default triple (there are some tests checking for ldexpf). So if building with msp430 or avr being the default target the test would fail otherwise.

craig.topper added inline comments.
llvm/lib/Analysis/TargetLibraryInfo.cpp
155

becuase -> because

bjope updated this revision to Diff 347505.May 24 2021, 2:41 PM

Spelling corrected in code comments.

This revision was not accepted when it landed; it landed in state Needs Review.Jun 2 2021, 2:41 AM
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.

Commited without approval?

bjope added a comment.Jun 2 2021, 4:10 AM

Commited without approval?

Ah, right. I missed that when pushing the approved patches that depended on this one.

Maybe we can have a post-commit review of this.
IMHO this is a quite straight forward fix. Nobody has expressed any major concern about the actual solution for 2 months (it has plenty of reviewers and this has been brought up on llvm-dev).