-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
[LLVM][IR] When evaluating GEP offsets don't assume ConstantInt is a scalar. #117162
Conversation
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-llvm-analysis Author: Paul Walker (paulwalker-arm) ChangesFull diff: https://github.com/llvm/llvm-project/pull/117162.diff 4 Files Affected:
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"
|
llvm/lib/IR/Operator.cpp
Outdated
APInt(Offset.getBitWidth(), SL->getElementOffset(ElementIdx)), | ||
1)) | ||
if (V->getType()->isIntegerTy()) { | ||
if (auto ConstOffset = dyn_cast<ConstantInt>(V)) { |
There was a problem hiding this comment.
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()) {
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
llvm/lib/IR/Operator.cpp
Outdated
continue; | ||
} | ||
if (!AccumulateOffset(ConstOffset->getValue(), | ||
GTI.getSequentialElementStride(DL))) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
eb0abc2
to
1e78b2f
Compare
There was a problem hiding this 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...
LLVM Buildbot has detected a new failure on builder 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
|
No description provided.