From c5ce591577e1226147c34da24c85eb852428b4d0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 10 Mar 2025 14:58:48 +0100 Subject: [PATCH 1/2] Add test --- .../ConstProp/inttoptr-gep-index-width.ll | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-index-width.ll 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 0000000000000..9f462db684e2d --- /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 null +; + %base = inttoptr i16 -1 to ptr + %gep = getelementptr i8, ptr %base, i8 1 + ret ptr %gep +} From 1be2e4239a9da242fc23f03a3e1c4895e16bb0ac Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 10 Mar 2025 14:56:22 +0100 Subject: [PATCH 2/2] [ConstantFolding] Fix handling of index width != pointer width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- llvm/lib/Analysis/ConstantFolding.cpp | 9 ++++++--- .../InstSimplify/ConstProp/inttoptr-gep-index-width.ll | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index d645bf8f7b621..b0ba25c3c16ac 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(Ptr)) { if (CE->getOpcode() == Instruction::IntToPtr) { if (auto *Base = dyn_cast(CE->getOperand(0))) - BasePtr = Base->getValue().zextOrTrunc(BitWidth); + BasePtr = Base->getValue().zextOrTrunc(BasePtr.getBitWidth()); } } auto *PTy = cast(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 index 9f462db684e2d..03056e8361e21 100644 --- a/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-index-width.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/inttoptr-gep-index-width.ll @@ -6,7 +6,7 @@ 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 null +; CHECK-NEXT: ret ptr inttoptr (i16 -256 to ptr) ; %base = inttoptr i16 -1 to ptr %gep = getelementptr i8, ptr %base, i8 1