Skip to content

Commit 1be2e42

Browse files
committed
[ConstantFolding] Fix handling of index width != pointer width
Per LangRef: > The offsets are then added to the low bits of the base address up to the index type width, with silently-wrapping two’s complement arithmetic. If the pointer size is larger than the index size, this means that the bits outside the index type width will not be affected.
1 parent c5ce591 commit 1be2e42

File tree

2 files changed

+7
-4
lines changed

2 files changed

+7
-4
lines changed

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -943,18 +943,21 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
943943

944944
// If the base value for this address is a literal integer value, fold the
945945
// getelementptr to the resulting integer value casted to the pointer type.
946-
APInt BasePtr(BitWidth, 0);
946+
APInt BasePtr(DL.getPointerTypeSizeInBits(Ptr->getType()), 0);
947947
if (auto *CE = dyn_cast<ConstantExpr>(Ptr)) {
948948
if (CE->getOpcode() == Instruction::IntToPtr) {
949949
if (auto *Base = dyn_cast<ConstantInt>(CE->getOperand(0)))
950-
BasePtr = Base->getValue().zextOrTrunc(BitWidth);
950+
BasePtr = Base->getValue().zextOrTrunc(BasePtr.getBitWidth());
951951
}
952952
}
953953

954954
auto *PTy = cast<PointerType>(Ptr->getType());
955955
if ((Ptr->isNullValue() || BasePtr != 0) &&
956956
!DL.isNonIntegralPointerType(PTy)) {
957-
Constant *C = ConstantInt::get(Ptr->getContext(), Offset + BasePtr);
957+
// If the index size is smaller than the pointer size, add to the low
958+
// bits only.
959+
BasePtr.insertBits(BasePtr.trunc(BitWidth) + Offset, 0);
960+
Constant *C = ConstantInt::get(Ptr->getContext(), BasePtr);
958961
return ConstantExpr::getIntToPtr(C, ResTy);
959962
}
960963

llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-index-width.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ target datalayout = "p:16:16:16:8"
66
; The GEP should only modify the low 8 bits of the pointer.
77
define ptr @test() {
88
; CHECK-LABEL: define ptr @test() {
9-
; CHECK-NEXT: ret ptr null
9+
; CHECK-NEXT: ret ptr inttoptr (i16 -256 to ptr)
1010
;
1111
%base = inttoptr i16 -1 to ptr
1212
%gep = getelementptr i8, ptr %base, i8 1

0 commit comments

Comments
 (0)