aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp9
-rw-r--r--llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-index-width.ll14
2 files changed, 20 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index d645bf8..b0ba25c 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -943,18 +943,21 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
// If the base value for this address is a literal integer value, fold the
// getelementptr to the resulting integer value casted to the pointer type.
- APInt BasePtr(BitWidth, 0);
+ APInt BasePtr(DL.getPointerTypeSizeInBits(Ptr->getType()), 0);
if (auto *CE = dyn_cast<ConstantExpr>(Ptr)) {
if (CE->getOpcode() == Instruction::IntToPtr) {
if (auto *Base = dyn_cast<ConstantInt>(CE->getOperand(0)))
- BasePtr = Base->getValue().zextOrTrunc(BitWidth);
+ BasePtr = Base->getValue().zextOrTrunc(BasePtr.getBitWidth());
}
}
auto *PTy = cast<PointerType>(Ptr->getType());
if ((Ptr->isNullValue() || BasePtr != 0) &&
!DL.isNonIntegralPointerType(PTy)) {
- Constant *C = ConstantInt::get(Ptr->getContext(), Offset + BasePtr);
+ // If the index size is smaller than the pointer size, add to the low
+ // bits only.
+ BasePtr.insertBits(BasePtr.trunc(BitWidth) + Offset, 0);
+ Constant *C = ConstantInt::get(Ptr->getContext(), BasePtr);
return ConstantExpr::getIntToPtr(C, ResTy);
}
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-index-width.ll b/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-index-width.ll
new file mode 100644
index 0000000..03056e8
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-index-width.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
+
+target datalayout = "p:16:16:16:8"
+
+; The GEP should only modify the low 8 bits of the pointer.
+define ptr @test() {
+; CHECK-LABEL: define ptr @test() {
+; CHECK-NEXT: ret ptr inttoptr (i16 -256 to ptr)
+;
+ %base = inttoptr i16 -1 to ptr
+ %gep = getelementptr i8, ptr %base, i8 1
+ ret ptr %gep
+}