[llvm] [InstCombine] Preserve GEP no-wrap flags (PR #141113)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Thu May 22 11:01:45 PDT 2025


https://github.com/artagnon created https://github.com/llvm/llvm-project/pull/141113

None

>From e59b12ff800bd139719d7947bddf7fc042a250a9 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Tue, 13 May 2025 13:37:00 +0100
Subject: [PATCH 1/2] [InstCombine] Pre-commit tests for propogating GEP NW

---
 .../InstCombine/gep-vector-indices.ll         | 28 ++++++++++++-
 .../Transforms/InstCombine/vec_shuffle.ll     | 39 +++++++++++++++++++
 2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/gep-vector-indices.ll b/llvm/test/Transforms/InstCombine/gep-vector-indices.ll
index 660ce317a0f64..34fe769f6399b 100644
--- a/llvm/test/Transforms/InstCombine/gep-vector-indices.ll
+++ b/llvm/test/Transforms/InstCombine/gep-vector-indices.ll
@@ -12,8 +12,8 @@ define ptr @vector_splat_indices_v2i64_ext0(ptr %a) {
   ret ptr %res
 }
 
-define ptr @vector_splat_indices_nxv2i64_ext0(ptr %a) {
-; CHECK-LABEL: @vector_splat_indices_nxv2i64_ext0(
+define ptr @vector_splat_indices_nxv2i64_ext0_inbounds(ptr %a) {
+; CHECK-LABEL: @vector_splat_indices_nxv2i64_ext0_inbounds(
 ; CHECK-NEXT:    [[RES:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i64 16
 ; CHECK-NEXT:    ret ptr [[RES]]
 ;
@@ -24,6 +24,30 @@ define ptr @vector_splat_indices_nxv2i64_ext0(ptr %a) {
   ret ptr %res
 }
 
+define ptr @vector_splat_indices_nxv2i64_ext0_nuw(ptr %a) {
+; CHECK-LABEL: @vector_splat_indices_nxv2i64_ext0_nuw(
+; CHECK-NEXT:    [[RES:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 16
+; CHECK-NEXT:    ret ptr [[RES]]
+;
+  %tmp = insertelement <vscale x 2 x i64> poison, i64 4, i32 0
+  %splatof4 = shufflevector <vscale x 2 x i64> %tmp, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
+  %gep = getelementptr nuw i32, ptr %a, <vscale x 2 x i64> %splatof4
+  %res = extractelement <vscale x 2 x ptr> %gep, i32 0
+  ret ptr %res
+}
+
+define ptr @vector_splat_indices_nxv2i64_ext0_nusw(ptr %a) {
+; CHECK-LABEL: @vector_splat_indices_nxv2i64_ext0_nusw(
+; CHECK-NEXT:    [[RES:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 16
+; CHECK-NEXT:    ret ptr [[RES]]
+;
+  %tmp = insertelement <vscale x 2 x i64> poison, i64 4, i32 0
+  %splatof4 = shufflevector <vscale x 2 x i64> %tmp, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
+  %gep = getelementptr nusw i32, ptr %a, <vscale x 2 x i64> %splatof4
+  %res = extractelement <vscale x 2 x ptr> %gep, i32 0
+  ret ptr %res
+}
+
 define ptr @vector_indices_v2i64_ext0(ptr %a, <2 x i64> %indices) {
 ; CHECK-LABEL: @vector_indices_v2i64_ext0(
 ; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i64> [[INDICES:%.*]], i64 0
diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle.ll b/llvm/test/Transforms/InstCombine/vec_shuffle.ll
index fa34a42714c46..78f7ab5b7df39 100644
--- a/llvm/test/Transforms/InstCombine/vec_shuffle.ll
+++ b/llvm/test/Transforms/InstCombine/vec_shuffle.ll
@@ -261,6 +261,45 @@ define <1 x ptr> @shuffle_gep(ptr %x1, ptr %x2) {
   ret <1 x ptr> %ret
 }
 
+define <1 x ptr> @shuffle_gep_inbounds(ptr %x1, ptr %x2) {
+; CHECK-LABEL: @shuffle_gep_inbounds(
+; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <1 x ptr> poison, ptr [[X2:%.*]], i64 0
+; CHECK-NEXT:    [[RET:%.*]] = getelementptr inbounds i8, <1 x ptr> [[TMP1]], i64 5
+; CHECK-NEXT:    ret <1 x ptr> [[RET]]
+;
+  %ins.1 = insertelement <2 x ptr> poison, ptr %x1, i32 0
+  %ins.2 = insertelement <2 x ptr> %ins.1, ptr %x2, i32 1
+  %gep = getelementptr inbounds i8, <2 x ptr> %ins.2, i64 5
+  %ret = shufflevector <2 x ptr> %gep, <2 x ptr> poison, <1 x i32> <i32 1>
+  ret <1 x ptr> %ret
+}
+
+define <1 x ptr> @shuffle_gep_nuw(ptr %x1, ptr %x2) {
+; CHECK-LABEL: @shuffle_gep_nuw(
+; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <1 x ptr> poison, ptr [[X2:%.*]], i64 0
+; CHECK-NEXT:    [[RET:%.*]] = getelementptr i8, <1 x ptr> [[TMP1]], i64 5
+; CHECK-NEXT:    ret <1 x ptr> [[RET]]
+;
+  %ins.1 = insertelement <2 x ptr> poison, ptr %x1, i32 0
+  %ins.2 = insertelement <2 x ptr> %ins.1, ptr %x2, i32 1
+  %gep = getelementptr nuw i8, <2 x ptr> %ins.2, i64 5
+  %ret = shufflevector <2 x ptr> %gep, <2 x ptr> poison, <1 x i32> <i32 1>
+  ret <1 x ptr> %ret
+}
+
+define <1 x ptr> @shuffle_gep_nusw(ptr %x1, ptr %x2) {
+; CHECK-LABEL: @shuffle_gep_nusw(
+; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <1 x ptr> poison, ptr [[X2:%.*]], i64 0
+; CHECK-NEXT:    [[RET:%.*]] = getelementptr i8, <1 x ptr> [[TMP1]], i64 5
+; CHECK-NEXT:    ret <1 x ptr> [[RET]]
+;
+  %ins.1 = insertelement <2 x ptr> poison, ptr %x1, i32 0
+  %ins.2 = insertelement <2 x ptr> %ins.1, ptr %x2, i32 1
+  %gep = getelementptr nusw i8, <2 x ptr> %ins.2, i64 5
+  %ret = shufflevector <2 x ptr> %gep, <2 x ptr> poison, <1 x i32> <i32 1>
+  ret <1 x ptr> %ret
+}
+
 ; Increasing length of vector ops is not a good canonicalization.
 
 define <3 x i32> @add_wider(i32 %y, i32 %z) {

>From feaee8d91f945c16ff43e99eb29abb3d3068c944 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Thu, 22 May 2025 18:49:01 +0100
Subject: [PATCH 2/2] [InstCombine] Preserve GEP no-wrap flags

---
 llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp | 4 ++--
 llvm/test/Transforms/InstCombine/gep-vector-indices.ll   | 4 ++--
 llvm/test/Transforms/InstCombine/vec_shuffle.ll          | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index f6423cb40492e..900946e9b335b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -537,7 +537,7 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
 
           GetElementPtrInst *NewGEP = GetElementPtrInst::Create(
               GEP->getSourceElementType(), NewPtr, NewOps);
-          NewGEP->setIsInBounds(GEP->isInBounds());
+          NewGEP->setNoWrapFlags(GEP->getNoWrapFlags());
           return NewGEP;
         }
       }
@@ -1982,7 +1982,7 @@ static Value *buildNew(Instruction *I, ArrayRef<Value*> NewOps,
       ArrayRef<Value*> Idx = NewOps.slice(1);
       return Builder.CreateGEP(cast<GEPOperator>(I)->getSourceElementType(),
                                Ptr, Idx, "",
-                               cast<GEPOperator>(I)->isInBounds());
+                               cast<GEPOperator>(I)->getNoWrapFlags());
     }
   }
   llvm_unreachable("failed to rebuild vector instructions");
diff --git a/llvm/test/Transforms/InstCombine/gep-vector-indices.ll b/llvm/test/Transforms/InstCombine/gep-vector-indices.ll
index 34fe769f6399b..ce584e0400cd5 100644
--- a/llvm/test/Transforms/InstCombine/gep-vector-indices.ll
+++ b/llvm/test/Transforms/InstCombine/gep-vector-indices.ll
@@ -26,7 +26,7 @@ define ptr @vector_splat_indices_nxv2i64_ext0_inbounds(ptr %a) {
 
 define ptr @vector_splat_indices_nxv2i64_ext0_nuw(ptr %a) {
 ; CHECK-LABEL: @vector_splat_indices_nxv2i64_ext0_nuw(
-; CHECK-NEXT:    [[RES:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 16
+; CHECK-NEXT:    [[RES:%.*]] = getelementptr nuw i8, ptr [[A:%.*]], i64 16
 ; CHECK-NEXT:    ret ptr [[RES]]
 ;
   %tmp = insertelement <vscale x 2 x i64> poison, i64 4, i32 0
@@ -38,7 +38,7 @@ define ptr @vector_splat_indices_nxv2i64_ext0_nuw(ptr %a) {
 
 define ptr @vector_splat_indices_nxv2i64_ext0_nusw(ptr %a) {
 ; CHECK-LABEL: @vector_splat_indices_nxv2i64_ext0_nusw(
-; CHECK-NEXT:    [[RES:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 16
+; CHECK-NEXT:    [[RES:%.*]] = getelementptr nusw nuw i8, ptr [[A:%.*]], i64 16
 ; CHECK-NEXT:    ret ptr [[RES]]
 ;
   %tmp = insertelement <vscale x 2 x i64> poison, i64 4, i32 0
diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle.ll b/llvm/test/Transforms/InstCombine/vec_shuffle.ll
index 78f7ab5b7df39..53f9df91d6af8 100644
--- a/llvm/test/Transforms/InstCombine/vec_shuffle.ll
+++ b/llvm/test/Transforms/InstCombine/vec_shuffle.ll
@@ -277,7 +277,7 @@ define <1 x ptr> @shuffle_gep_inbounds(ptr %x1, ptr %x2) {
 define <1 x ptr> @shuffle_gep_nuw(ptr %x1, ptr %x2) {
 ; CHECK-LABEL: @shuffle_gep_nuw(
 ; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <1 x ptr> poison, ptr [[X2:%.*]], i64 0
-; CHECK-NEXT:    [[RET:%.*]] = getelementptr i8, <1 x ptr> [[TMP1]], i64 5
+; CHECK-NEXT:    [[RET:%.*]] = getelementptr nuw i8, <1 x ptr> [[TMP1]], i64 5
 ; CHECK-NEXT:    ret <1 x ptr> [[RET]]
 ;
   %ins.1 = insertelement <2 x ptr> poison, ptr %x1, i32 0
@@ -290,7 +290,7 @@ define <1 x ptr> @shuffle_gep_nuw(ptr %x1, ptr %x2) {
 define <1 x ptr> @shuffle_gep_nusw(ptr %x1, ptr %x2) {
 ; CHECK-LABEL: @shuffle_gep_nusw(
 ; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <1 x ptr> poison, ptr [[X2:%.*]], i64 0
-; CHECK-NEXT:    [[RET:%.*]] = getelementptr i8, <1 x ptr> [[TMP1]], i64 5
+; CHECK-NEXT:    [[RET:%.*]] = getelementptr nusw i8, <1 x ptr> [[TMP1]], i64 5
 ; CHECK-NEXT:    ret <1 x ptr> [[RET]]
 ;
   %ins.1 = insertelement <2 x ptr> poison, ptr %x1, i32 0



More information about the llvm-commits mailing list