Skip to content

[LLVM][IR] When evaluating GEP offsets don't assume ConstantInt is a scalar. #117162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 4, 2024

Conversation

paulwalker-arm
Copy link
Collaborator

No description provided.

@llvmbot llvmbot added llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:ir llvm:analysis Includes value tracking, cost tables and constant folding llvm:transforms labels Nov 21, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 21, 2024

@llvm/pr-subscribers-llvm-ir
@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-llvm-analysis

Author: Paul Walker (paulwalker-arm)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/117162.diff

4 Files Affected:

  • (modified) llvm/lib/Analysis/ConstantFolding.cpp (+1-1)
  • (modified) llvm/lib/IR/Operator.cpp (+25-21)
  • (modified) llvm/test/Transforms/InstCombine/gep-vector-indices.ll (+1)
  • (modified) llvm/test/Transforms/InstSimplify/gep.ll (+1)
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 1971c28fc4c4de..47b96e00c7765a 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -881,7 +881,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
   Type *IntIdxTy = DL.getIndexType(Ptr->getType());
 
   for (unsigned i = 1, e = Ops.size(); i != e; ++i)
-    if (!isa<ConstantInt>(Ops[i]))
+    if (!isa<ConstantInt>(Ops[i]) || !Ops[i]->getType()->isIntegerTy())
       return nullptr;
 
   unsigned BitWidth = DL.getTypeSizeInBits(IntIdxTy);
diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp
index 199eb4d90f5565..522e2ba9e59acf 100644
--- a/llvm/lib/IR/Operator.cpp
+++ b/llvm/lib/IR/Operator.cpp
@@ -127,8 +127,10 @@ bool GEPOperator::accumulateConstantOffset(
   // Fast path for canonical getelementptr i8 form.
   if (SourceType->isIntegerTy(8) && !ExternalAnalysis) {
     if (auto *CI = dyn_cast<ConstantInt>(Index.front())) {
-      Offset += CI->getValue().sextOrTrunc(Offset.getBitWidth());
-      return true;
+      if (CI->getType()->isIntegerTy()) {
+        Offset += CI->getValue().sextOrTrunc(Offset.getBitWidth());
+        return true;
+      }
     }
     return false;
   }
@@ -163,28 +165,30 @@ bool GEPOperator::accumulateConstantOffset(
     Value *V = GTI.getOperand();
     StructType *STy = GTI.getStructTypeOrNull();
     // Handle ConstantInt if possible.
-    if (auto ConstOffset = dyn_cast<ConstantInt>(V)) {
-      if (ConstOffset->isZero())
-        continue;
-      // if the type is scalable and the constant is not zero (vscale * n * 0 =
-      // 0) bailout.
-      if (ScalableType)
-        return false;
-      // Handle a struct index, which adds its field offset to the pointer.
-      if (STy) {
-        unsigned ElementIdx = ConstOffset->getZExtValue();
-        const StructLayout *SL = DL.getStructLayout(STy);
-        // Element offset is in bytes.
-        if (!AccumulateOffset(
-                APInt(Offset.getBitWidth(), SL->getElementOffset(ElementIdx)),
-                1))
+    if (V->getType()->isIntegerTy()) {
+      if (auto ConstOffset = dyn_cast<ConstantInt>(V)) {
+        if (ConstOffset->isZero())
+          continue;
+        // if the type is scalable and the constant is not zero (vscale * n * 0
+        // = 0) bailout.
+        if (ScalableType)
+          return false;
+        // Handle a struct index, which adds its field offset to the pointer.
+        if (STy) {
+          unsigned ElementIdx = ConstOffset->getZExtValue();
+          const StructLayout *SL = DL.getStructLayout(STy);
+          // Element offset is in bytes.
+          if (!AccumulateOffset(
+                  APInt(Offset.getBitWidth(), SL->getElementOffset(ElementIdx)),
+                  1))
+            return false;
+          continue;
+        }
+        if (!AccumulateOffset(ConstOffset->getValue(),
+                              GTI.getSequentialElementStride(DL)))
           return false;
         continue;
       }
-      if (!AccumulateOffset(ConstOffset->getValue(),
-                            GTI.getSequentialElementStride(DL)))
-        return false;
-      continue;
     }
 
     // The operand is not constant, check if an external analysis was provided.
diff --git a/llvm/test/Transforms/InstCombine/gep-vector-indices.ll b/llvm/test/Transforms/InstCombine/gep-vector-indices.ll
index e9534e45ec141d..9f33f4e9c206a0 100644
--- a/llvm/test/Transforms/InstCombine/gep-vector-indices.ll
+++ b/llvm/test/Transforms/InstCombine/gep-vector-indices.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -passes=instcombine %s -S | FileCheck %s
+; RUN: opt -passes=instcombine -use-constant-int-for-fixed-length-splat %s -S | FileCheck %s
 
 define ptr @vector_splat_indices_v2i64_ext0(ptr %a) {
 ; CHECK-LABEL: @vector_splat_indices_v2i64_ext0(
diff --git a/llvm/test/Transforms/InstSimplify/gep.ll b/llvm/test/Transforms/InstSimplify/gep.ll
index b23494fc56aa4e..a330f5cbc92681 100644
--- a/llvm/test/Transforms/InstSimplify/gep.ll
+++ b/llvm/test/Transforms/InstSimplify/gep.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
+; RUN: opt -S -passes=instsimplify -use-constant-int-for-fixed-length-splat < %s | FileCheck %s
 
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 

APInt(Offset.getBitWidth(), SL->getElementOffset(ElementIdx)),
1))
if (V->getType()->isIntegerTy()) {
if (auto ConstOffset = dyn_cast<ConstantInt>(V)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the interest of keeping the indentation down, I'd write this as:

auto *ConstOffset = dyn_cast<ConstantInt>(V);
if (ConstOffset && ConstOffset->getType()->isIntegerTy()) {
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

continue;
}
if (!AccumulateOffset(ConstOffset->getValue(),
GTI.getSequentialElementStride(DL)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also update the very similar code in collectOffset() below?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I've been trying to rely purely on existing testing but it seems this was not covered so I've added a new one.

@paulwalker-arm paulwalker-arm changed the title [LLVM][IR] When evaluting GEP offsets don't assume ConstantInt is a scalar. [LLVM][IR] When evaluating GEP offsets don't assume ConstantInt is a scalar. Nov 21, 2024
@paulwalker-arm paulwalker-arm force-pushed the vector-constants-ir-gep branch from eb0abc2 to 1e78b2f Compare November 21, 2024 17:14
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. We probably should support vectors here in the future, but that's going to have fallout, so this is fine for now...

@paulwalker-arm paulwalker-arm merged commit a88653a into llvm:main Dec 4, 2024
8 checks passed
@paulwalker-arm paulwalker-arm deleted the vector-constants-ir-gep branch December 4, 2024 12:45
@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 4, 2024

LLVM Buildbot has detected a new failure on builder llvm-clang-aarch64-darwin running on doug-worker-5 while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/190/builds/10688

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM :: ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll' FAILED ********************
Exit Code: 2

Command Output (stderr):
--
RUN: at line 1: /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli -jit-kind=orc-lazy -compile-threads=2 -thread-entry hello /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll | /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/FileCheck /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll
+ /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli -jit-kind=orc-lazy -compile-threads=2 -thread-entry hello /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll
+ /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/FileCheck /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
 #0 0x0000000101895b84 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100e75b84)
 #1 0x0000000101893c08 llvm::sys::RunSignalHandlers() (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100e73c08)
 #2 0x0000000101896240 SignalHandler(int) (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100e76240)
 #3 0x0000000198f82584 (/usr/lib/system/libsystem_platform.dylib+0x18047a584)
 #4 0x0000000198f5121c (/usr/lib/system/libsystem_pthread.dylib+0x18044921c)
 #5 0x0000000198e77ad0 (/usr/lib/libc++.1.dylib+0x18036fad0)
 #6 0x0000000101457740 void llvm::detail::UniqueFunctionBase<void, llvm::Expected<llvm::DenseMap<llvm::orc::SymbolStringPtr, llvm::orc::ExecutorSymbolDef, llvm::DenseMapInfo<llvm::orc::SymbolStringPtr, void>, llvm::detail::DenseMapPair<llvm::orc::SymbolStringPtr, llvm::orc::ExecutorSymbolDef>>>>::CallImpl<llvm::orc::Platform::lookupInitSymbols(llvm::orc::ExecutionSession&, llvm::DenseMap<llvm::orc::JITDylib*, llvm::orc::SymbolLookupSet, llvm::DenseMapInfo<llvm::orc::JITDylib*, void>, llvm::detail::DenseMapPair<llvm::orc::JITDylib*, llvm::orc::SymbolLookupSet>> const&)::$_44>(void*, llvm::Expected<llvm::DenseMap<llvm::orc::SymbolStringPtr, llvm::orc::ExecutorSymbolDef, llvm::DenseMapInfo<llvm::orc::SymbolStringPtr, void>, llvm::detail::DenseMapPair<llvm::orc::SymbolStringPtr, llvm::orc::ExecutorSymbolDef>>>&) (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100a37740)
 #7 0x0000000101452ef4 llvm::orc::AsynchronousSymbolQuery::handleComplete(llvm::orc::ExecutionSession&)::RunQueryCompleteTask::run() (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100a32ef4)
 #8 0x0000000101501770 void* std::__1::__thread_proxy[abi:un170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, llvm::orc::DynamicThreadPoolTaskDispatcher::dispatch(std::__1::unique_ptr<llvm::orc::Task, std::__1::default_delete<llvm::orc::Task>>)::$_0>>(void*) (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100ae1770)
 #9 0x0000000198f51f94 (/usr/lib/system/libsystem_pthread.dylib+0x180449f94)
#10 0x0000000198f4cd34 (/usr/lib/system/libsystem_pthread.dylib+0x180444d34)
FileCheck error: '<stdin>' is empty.
FileCheck command line:  /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/FileCheck /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll

--

********************


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:analysis Includes value tracking, cost tables and constant folding llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:ir llvm:transforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants