This is an archive of the discontinued LLVM Phabricator instance.

[SimplifyLibCalls] avoid slicing 64-bit integers in an ILP32 build (PR #54739)
ClosedPublic

Authored by msebor on Apr 10 2022, 1:51 PM.

Details

Summary

Passing a 64-bit result of a call like Value::getZExtValue() as an argument to StringRef::substr() in a 32-bit build truncates the value and, in the two test cases in bug 54739, leads to incorrect folding. The attached change adjusts the calls to StringRef::substr() to avoid the truncation in these two instances.

I considered changing StringRef::substr() to use uint64_t but since the use of size_t in the StringRef API is pervasive and due to its interplay with StringRef::npos and sometimes std::string::npos and the potential for unintended semantic changes, decided against it. I reviewed the rest of SimplifyLibCalls.cpp for similar problems and didn't spot any, but I suspect there may be others in the rest of the code base.

Tested on x86_64-linux in ILP32 and LP64 modes. (The ILP32 test run shows a few crashes that appear unrelated to this change.)

Diff Detail

Event Timeline

msebor created this revision.Apr 10 2022, 1:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 10 2022, 1:51 PM
msebor requested review of this revision.Apr 10 2022, 1:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 10 2022, 1:51 PM

ILP32 test run shows a few crashes that appear unrelated to this change

Is this even supported? I am wondering whether it is worth to fix it at all (and make code worse to read) if there are more crashes anyway.

nikic retitled this revision from avoid slicing 64-bit integers in an ILP32 build (PR #54739) to [SimplifyLibCalls] avoid slicing 64-bit integers in an ILP32 build (PR #54739).Apr 11 2022, 2:30 AM
nikic added a comment.Apr 11 2022, 3:26 AM

If we don't want to change the StringRef API, possibly add a common helper to this file?

static StringRef substr(StringRef Str, uint64_t Len) {
  // Avoid truncating the length if size_t is 32-bits.
  return Len >= Str.size() ? Str : Str.substr(0, Len);
}

ILP32 test run shows a few crashes that appear unrelated to this change

Is this even supported? I am wondering whether it is worth to fix it at all (and make code worse to read) if there are more crashes anyway.

I opened PR 54129 with more details. It would be good to know if building 64-bit programs with a 32-bit Clang/LLVM isn't meant to work (if it isn't, adding an error to point that out would be helpful).

ILP32 test run shows a few crashes that appear unrelated to this change

Is this even supported? I am wondering whether it is worth to fix it at all (and make code worse to read) if there are more crashes anyway.

It's one of those things where its not intentionally unsupported, but gets very little testing these days. There's very little reason to run 32-bit LLVM on a 64-bit host, and most cross-compiles are going to be on 64-bit hosts.

If we don't want to change the StringRef API, possibly add a common helper to this file?

Agree.

msebor updated this revision to Diff 421998.Apr 11 2022, 12:13 PM

This revision adds the suggested substr helper function.

nikic added inline comments.Apr 11 2022, 12:19 PM
llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
207

This comment is redundant with the function comment now.

463

We shouldn't need both the std::min and the helper function.

msebor updated this revision to Diff 422005.Apr 11 2022, 12:34 PM

Anything else?

nikic accepted this revision.Apr 11 2022, 12:49 PM

LGTM

This revision is now accepted and ready to land.Apr 11 2022, 12:49 PM
This revision was landed with ongoing or failed builds.Apr 26 2022, 4:21 PM
This revision was automatically updated to reflect the committed changes.