[llvm] [SandboxIR] Implement Value::stripAndAccumulateConstantOffsets() (PR #224784)

Vasileios Porpodas via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 18 17:51:59 PDT 2026


https://github.com/vporpo created https://github.com/llvm/llvm-project/pull/224784

This patch implements the Sandbox IR version of Value::stripAndAccumulateConstantOffsets(), mirroring LLVM IR.

>From 0ffb586d2c9e67dcb89550697a34bbec37a7db31 Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vasileios.porpodas at amd.com>
Date: Fri, 18 Sep 2026 18:49:30 +0000
Subject: [PATCH] [SandboxIR] Implement
 Value::stripAndAccumulateConstantOffsets()

This patch implements the Sandbox IR version of Value::stripAndAccumulateConstantOffsets(), mirroring LLVM IR.
---
 llvm/include/llvm/SandboxIR/Value.h        | 19 ++++++++++++
 llvm/lib/SandboxIR/Value.cpp               | 15 ++++++++++
 llvm/unittests/SandboxIR/SandboxIRTest.cpp | 34 ++++++++++++++++++++++
 3 files changed, 68 insertions(+)

diff --git a/llvm/include/llvm/SandboxIR/Value.h b/llvm/include/llvm/SandboxIR/Value.h
index e50c4c996625dc..847d673ab9f235 100644
--- a/llvm/include/llvm/SandboxIR/Value.h
+++ b/llvm/include/llvm/SandboxIR/Value.h
@@ -292,6 +292,25 @@ class Value {
   /// \Returns the LLVM IR name of the bottom-most LLVM value.
   StringRef getName() const { return Val->getName(); }
 
+  const Value *stripAndAccumulateConstantOffsets(
+      const DataLayout &DL, APInt &Offset, bool AllowNonInbounds,
+      bool AllowInvariantGroup = false,
+      function_ref<bool(Value &Value, APInt &Offset)> ExternalAnalysis =
+          nullptr,
+      bool LookThroughIntToPtr = false) const;
+
+  Value *stripAndAccumulateConstantOffsets(
+      const DataLayout &DL, APInt &Offset, bool AllowNonInbounds,
+      bool AllowInvariantGroup = false,
+      function_ref<bool(Value &Value, APInt &Offset)> ExternalAnalysis =
+          nullptr,
+      bool LookThroughIntToPtr = false) {
+    return const_cast<Value *>(
+        static_cast<const Value *>(this)->stripAndAccumulateConstantOffsets(
+            DL, Offset, AllowNonInbounds, AllowInvariantGroup, ExternalAnalysis,
+            LookThroughIntToPtr));
+  }
+
 #ifndef NDEBUG
   /// Should crash if there is something wrong with the instruction.
   virtual void verify() const = 0;
diff --git a/llvm/lib/SandboxIR/Value.cpp b/llvm/lib/SandboxIR/Value.cpp
index 94b4a4c9a406fb..b8d25821dca73f 100644
--- a/llvm/lib/SandboxIR/Value.cpp
+++ b/llvm/lib/SandboxIR/Value.cpp
@@ -77,6 +77,21 @@ void Value::replaceAllUsesWith(Value *Other) {
   Val->replaceAllUsesWith(Other->Val);
 }
 
+const Value *Value::stripAndAccumulateConstantOffsets(
+    const DataLayout &DL, APInt &Offset, bool AllowNonInbounds,
+    bool AllowInvariantGroup,
+    function_ref<bool(Value &Value, APInt &Offset)> ExternalAnalysis,
+    bool LookThroughIntToPtr) const {
+  auto LLVMExternalAnalysis = [&ExternalAnalysis, this](llvm::Value &LLVMValue,
+                                                        APInt &Offset) -> bool {
+    Value &ValueRef = *Ctx.getValue(&LLVMValue);
+    return ExternalAnalysis(ValueRef, Offset);
+  };
+  const llvm::Value *LLVMV = Val->stripAndAccumulateConstantOffsets(
+      DL, Offset, AllowNonInbounds, AllowInvariantGroup, LLVMExternalAnalysis);
+  return Ctx.getValue(LLVMV);
+}
+
 #ifndef NDEBUG
 std::string Value::getUid() const {
   std::stringstream SS;
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 4110cd8e2a2b71..b5151b5ecd7d8e 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -1743,6 +1743,40 @@ define void @foo(ptr %ptr) {
   EXPECT_EQ(St1->getOperand(0), Ld0);
 }
 
+TEST_F(SandboxIRTest, Value_stripAndAccumulate) {
+  parseIR(C, R"IR(
+define void @foo(ptr %ptr, <2 x ptr> %ptrs) {
+  %gep0 = getelementptr i8, ptr %ptr, i32 0
+  ret void
+}
+)IR");
+  Function &LLVMF = *M->getFunction("foo");
+  const DataLayout &DL = M->getDataLayout();
+  BasicBlock *LLVMBB = &*LLVMF.begin();
+  auto LLVMIt = LLVMBB->begin();
+  auto *LLVMGEP = &*LLVMIt++;
+  sandboxir::Context Ctx(C);
+  Ctx.createFunction(&LLVMF);
+  auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
+  auto It = BB->begin();
+  auto *GEP = &*It++;
+
+  unsigned Bits = DL.getIndexTypeSizeInBits(LLVMGEP->getType());
+  APInt Offset(Bits, 0);
+  bool AllowNonInbounds = true;
+  bool AllowInvariantGroup = true;
+  function_ref<bool(sandboxir::Value &, APInt &)> ExternalAnalysis = nullptr;
+  auto *Res = GEP->stripAndAccumulateConstantOffsets(
+      DL, Offset, AllowNonInbounds, AllowInvariantGroup, ExternalAnalysis);
+
+  APInt LLVMOffset(Bits, 0);
+  function_ref<bool(llvm::Value &, APInt &)> LLVMExternalAnalysis = nullptr;
+  auto *LLVMRes = LLVMGEP->stripAndAccumulateConstantOffsets(
+      DL, LLVMOffset, AllowNonInbounds, AllowInvariantGroup, LLVMExternalAnalysis);
+  EXPECT_EQ(Res, Ctx.getValue(LLVMRes));
+  EXPECT_EQ(Offset, LLVMOffset);
+}
+
 // Check that the operands/users are counted correctly.
 //  I1
 // /  \



More information about the llvm-commits mailing list