[llvm] [LLVM][IR] When evaluating GEP offsets don't assume ConstantInt is a scalar. (PR #117162)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 21 09:15:02 PST 2024
https://github.com/paulwalker-arm updated https://github.com/llvm/llvm-project/pull/117162
>From 1e78b2fea60d3740f3c0624ef1a1d80512562027 Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Tue, 19 Nov 2024 12:48:44 +0000
Subject: [PATCH] [LLVM][IR] When evaluating GEP offsets don't assume
ConstantInt is a scalar.
---
llvm/lib/Analysis/ConstantFolding.cpp | 2 +-
llvm/lib/IR/Operator.cpp | 9 ++++++---
llvm/test/Transforms/GVN/opaque-ptr.ll | 9 +++++++++
llvm/test/Transforms/InstCombine/gep-vector-indices.ll | 1 +
llvm/test/Transforms/InstSimplify/gep.ll | 1 +
5 files changed, 18 insertions(+), 4 deletions(-)
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..24aeb5003b6094 100644
--- a/llvm/lib/IR/Operator.cpp
+++ b/llvm/lib/IR/Operator.cpp
@@ -126,7 +126,8 @@ bool GEPOperator::accumulateConstantOffset(
APInt &Offset, function_ref<bool(Value &, APInt &)> ExternalAnalysis) {
// Fast path for canonical getelementptr i8 form.
if (SourceType->isIntegerTy(8) && !ExternalAnalysis) {
- if (auto *CI = dyn_cast<ConstantInt>(Index.front())) {
+ auto *CI = dyn_cast<ConstantInt>(Index.front());
+ if (CI && CI->getType()->isIntegerTy()) {
Offset += CI->getValue().sextOrTrunc(Offset.getBitWidth());
return true;
}
@@ -163,7 +164,8 @@ bool GEPOperator::accumulateConstantOffset(
Value *V = GTI.getOperand();
StructType *STy = GTI.getStructTypeOrNull();
// Handle ConstantInt if possible.
- if (auto ConstOffset = dyn_cast<ConstantInt>(V)) {
+ auto *ConstOffset = dyn_cast<ConstantInt>(V);
+ if (ConstOffset && ConstOffset->getType()->isIntegerTy()) {
if (ConstOffset->isZero())
continue;
// if the type is scalable and the constant is not zero (vscale * n * 0 =
@@ -222,7 +224,8 @@ bool GEPOperator::collectOffset(
Value *V = GTI.getOperand();
StructType *STy = GTI.getStructTypeOrNull();
// Handle ConstantInt if possible.
- if (auto ConstOffset = dyn_cast<ConstantInt>(V)) {
+ auto *ConstOffset = dyn_cast<ConstantInt>(V);
+ if (ConstOffset && ConstOffset->getType()->isIntegerTy()) {
if (ConstOffset->isZero())
continue;
// If the type is scalable and the constant is not zero (vscale * n * 0 =
diff --git a/llvm/test/Transforms/GVN/opaque-ptr.ll b/llvm/test/Transforms/GVN/opaque-ptr.ll
index 4a0f9d319501c8..8a7e4205848598 100644
--- a/llvm/test/Transforms/GVN/opaque-ptr.ll
+++ b/llvm/test/Transforms/GVN/opaque-ptr.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=gvn < %s | FileCheck %s
+; RUN: opt -S -passes=gvn -use-constant-int-for-fixed-length-splat < %s | FileCheck %s
declare void @use(ptr)
declare void @use.i32(i32)
@@ -58,6 +59,10 @@ define void @gep_cse_offset_canonicalization(ptr %p, i64 %idx, i64 %idx2) {
; CHECK-NEXT: call void @use(ptr [[GEP6]])
; CHECK-NEXT: call void @use(ptr [[GEP6_SAME]])
; CHECK-NEXT: call void @use(ptr [[GEP6_DIFFERENT]])
+; CHECK-NEXT: %gep7 = getelementptr <16 x i32>, ptr %p, i64 1
+; CHECK-NEXT: %gep7.different = getelementptr <16 x i32>, ptr %p, <16 x i64> splat (i64 1)
+; CHECK-NEXT: call void @use(ptr %gep7)
+; CHECK-NEXT: call void @use(<16 x ptr> %gep7.different)
; CHECK-NEXT: ret void
;
%gep1 = getelementptr i64, ptr %p, i64 1
@@ -101,6 +106,10 @@ define void @gep_cse_offset_canonicalization(ptr %p, i64 %idx, i64 %idx2) {
call void @use(ptr %gep6)
call void @use(ptr %gep6.same)
call void @use(ptr %gep6.different)
+ %gep7 = getelementptr <16 x i32>, ptr %p, i64 1
+ %gep7.different = getelementptr <16 x i32>, ptr %p, <16 x i64> splat (i64 1)
+ call void @use(ptr %gep7)
+ call void @use(<16 x ptr> %gep7.different)
ret void
}
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"
More information about the llvm-commits
mailing list