[llvm] [ConstantFolding] Fix handling of index width != pointer width (PR #130608)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 10 07:04:05 PDT 2025
https://github.com/nikic updated https://github.com/llvm/llvm-project/pull/130608
>From c5ce591577e1226147c34da24c85eb852428b4d0 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
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 <npopov at redhat.com>
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<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
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
More information about the llvm-commits
mailing list