OSDN Git Service

[ValueTracking] Fix a misuse of APInt in GetPointerBaseWithConstantOffset
authorFlorian Hahn <flo@fhahn.com>
Fri, 4 Jan 2019 14:53:22 +0000 (14:53 +0000)
committerFlorian Hahn <flo@fhahn.com>
Fri, 4 Jan 2019 14:53:22 +0000 (14:53 +0000)
commit5692e204f17c4d491a6125d3230656df32a7f991
treed0aa2645cae202cfc7bad02c78d8047abcb6a4db
parent1943349b126ed6d91c680c0f53b2559adef12f9f
[ValueTracking] Fix a misuse of APInt in GetPointerBaseWithConstantOffset

GetPointerBaseWithConstantOffset include this code, where ByteOffset
and GEPOffset are both of type llvm::APInt :

  ByteOffset += GEPOffset.getSExtValue();

The problem with this line is that getSExtValue() returns an int64_t, but
the += matches an overload for uint64_t. The problem is that the resulting
APInt is no longer considered to be signed. That in turn causes assertion
failures later on if the relevant pointer type is > 64 bits in width and
the GEPOffset was negative.

Changing it to

  ByteOffset += GEPOffset.sextOrTrunc(ByteOffset.getBitWidth());

resolves the issue and explicitly performs the sign-extending
or truncation. Additionally, instead of asserting later if the result
is > 64 bits, it breaks out of the loop in that case.

See also
 https://reviews.llvm.org/D24729
 https://reviews.llvm.org/D24772

This commit must be merged after D38662 in order for the test to pass.

Patch by Michael Ferguson <mpfergu@gmail.com>.

Reviewers: reames, sanjoy, hfinkel

Reviewed By: hfinkel

Differential Revision: https://reviews.llvm.org/D38501

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350395 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Analysis/ValueTracking.cpp
test/Analysis/ValueTracking/gep-negative-issue.ll [new file with mode: 0644]