From d084d87a88f8d5ed5ca123da1b4ae63c4c68e6de Mon Sep 17 00:00:00 2001 From: Pedro Lobo Date: Fri, 25 Jul 2025 00:14:29 +0100 Subject: [PATCH] [ConstantFolding] Merge constant gep `inrange` attributes When folding a gep+gep into a single gep, intersect their `inrange` attributes. --- llvm/lib/Analysis/ConstantFolding.cpp | 11 ++++---- .../Transforms/InstSimplify/ConstProp/gep.ll | 28 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index ec78386def24f..759c553111d06 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -929,12 +929,11 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, if (!AllConstantInt) break; - // TODO: Try to intersect two inrange attributes? - if (!InRange) { - InRange = GEP->getInRange(); - if (InRange) - // Adjust inrange by offset until now. - InRange = InRange->sextOrTrunc(BitWidth).subtract(Offset); + // Adjust inrange offset and intersect inrange attributes + if (auto GEPRange = GEP->getInRange()) { + auto AdjustedGEPRange = GEPRange->sextOrTrunc(BitWidth).subtract(Offset); + InRange = + InRange ? InRange->intersectWith(AdjustedGEPRange) : AdjustedGEPRange; } Ptr = cast(GEP->getOperand(0)); diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/gep.ll b/llvm/test/Transforms/InstSimplify/ConstProp/gep.ll index 763257986e1f7..5b249068286f4 100644 --- a/llvm/test/Transforms/InstSimplify/ConstProp/gep.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/gep.ll @@ -29,3 +29,31 @@ define ptr @f2() { ; ret ptr getelementptr (ptr, ptr getelementptr inbounds inrange(0, 8) ([3 x ptr], ptr @vt, i64 0, i64 1), i64 3) } + +define ptr @f3() { +; CHECK-LABEL: @f3( +; CHECK-NEXT: ret ptr getelementptr inbounds nuw inrange(-8, 0) (i8, ptr @vt, i64 16) +; + ret ptr getelementptr inrange(-16, 8) (ptr, ptr getelementptr inbounds inrange(0, 8) ([3 x ptr], ptr @vt, i64 0, i64 1), i64 1) +} + +define ptr @f4() { +; CHECK-LABEL: @f4( +; CHECK-NEXT: ret ptr getelementptr inbounds nuw inrange(-8, 8) (i8, ptr @vt, i64 16) +; + ret ptr getelementptr inrange(-16, 8) (ptr, ptr getelementptr inbounds inrange(0, 24) ([3 x ptr], ptr @vt, i64 0, i64 1), i64 1) +} + +define ptr @f5() { +; CHECK-LABEL: @f5( +; CHECK-NEXT: ret ptr getelementptr inbounds nuw inrange(0, 0) (i8, ptr @vt, i64 16) +; + ret ptr getelementptr inrange(0, 8) (ptr, ptr getelementptr inbounds inrange(0, 8) ([3 x ptr], ptr @vt, i64 0, i64 0), i64 2) +} + +define ptr @f6() { +; CHECK-LABEL: @f6( +; CHECK-NEXT: ret ptr getelementptr inbounds nuw inrange(-8, 8) (i8, ptr @vt, i64 16) +; + ret ptr getelementptr inrange(-8, 8) (ptr, ptr getelementptr inbounds inrange(-8, 16) ([3 x ptr], ptr @vt, i64 0, i64 1), i64 1) +}