[llvm] 6467b49 - [InstCombine] Preserve all flags in phi of gep fold

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 19 03:14:02 PDT 2024


Author: Nikita Popov
Date: 2024-06-19T12:13:54+02:00
New Revision: 6467b49480cbf2aaa7cf22a0dab1d7b15fe54fd1

URL: https://github.com/llvm/llvm-project/commit/6467b49480cbf2aaa7cf22a0dab1d7b15fe54fd1
DIFF: https://github.com/llvm/llvm-project/commit/6467b49480cbf2aaa7cf22a0dab1d7b15fe54fd1.diff

LOG: [InstCombine] Preserve all flags in phi of gep fold

Preserve the intersection of all flags. Add GEPNoWrapFlags::all()
to serve as the initialization value for the intersection.

Added: 
    

Modified: 
    llvm/include/llvm/IR/GEPNoWrapFlags.h
    llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
    llvm/test/Transforms/InstCombine/opaque-ptr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/GEPNoWrapFlags.h b/llvm/include/llvm/IR/GEPNoWrapFlags.h
index 4d456cc691032..55a25c69193f2 100644
--- a/llvm/include/llvm/IR/GEPNoWrapFlags.h
+++ b/llvm/include/llvm/IR/GEPNoWrapFlags.h
@@ -44,6 +44,9 @@ class GEPNoWrapFlags {
       : Flags(IsInBounds ? (InBoundsFlag | NUSWFlag) : 0) {}
 
   static GEPNoWrapFlags none() { return GEPNoWrapFlags(); }
+  static GEPNoWrapFlags all() {
+    return GEPNoWrapFlags(InBoundsFlag | NUSWFlag | NUWFlag);
+  }
   static GEPNoWrapFlags inBounds() {
     return GEPNoWrapFlags(InBoundsFlag | NUSWFlag);
   }

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
index dd8eb4688d3c9..0ee9bc5fecb72 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -513,7 +513,7 @@ Instruction *InstCombinerImpl::foldPHIArgGEPIntoPHI(PHINode &PN) {
   // especially bad when the PHIs are in the header of a loop.
   bool NeededPhi = false;
 
-  bool AllInBounds = true;
+  GEPNoWrapFlags NW = GEPNoWrapFlags::all();
 
   // Scan to see if all operands are the same opcode, and all have one user.
   for (Value *V : drop_begin(PN.incoming_values())) {
@@ -523,7 +523,7 @@ Instruction *InstCombinerImpl::foldPHIArgGEPIntoPHI(PHINode &PN) {
         GEP->getNumOperands() != FirstInst->getNumOperands())
       return nullptr;
 
-    AllInBounds &= GEP->isInBounds();
+    NW &= GEP->getNoWrapFlags();
 
     // Keep track of whether or not all GEPs are of alloca pointers.
     if (AllBasePointersAreAllocas &&
@@ -605,8 +605,7 @@ Instruction *InstCombinerImpl::foldPHIArgGEPIntoPHI(PHINode &PN) {
   Value *Base = FixedOperands[0];
   GetElementPtrInst *NewGEP =
       GetElementPtrInst::Create(FirstInst->getSourceElementType(), Base,
-                                ArrayRef(FixedOperands).slice(1));
-  if (AllInBounds) NewGEP->setIsInBounds();
+                                ArrayRef(FixedOperands).slice(1), NW);
   PHIArgMergedDebugLoc(NewGEP, PN);
   return NewGEP;
 }

diff  --git a/llvm/test/Transforms/InstCombine/opaque-ptr.ll b/llvm/test/Transforms/InstCombine/opaque-ptr.ll
index 75020343b1d8a..df85547f56d74 100644
--- a/llvm/test/Transforms/InstCombine/opaque-ptr.ll
+++ b/llvm/test/Transforms/InstCombine/opaque-ptr.ll
@@ -541,6 +541,58 @@ join:
   ret ptr %phi
 }
 
+define ptr @phi_of_gep_flags_1(i1 %c, ptr %p) {
+; CHECK-LABEL: @phi_of_gep_flags_1(
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK:       if:
+; CHECK-NEXT:    br label [[JOIN:%.*]]
+; CHECK:       else:
+; CHECK-NEXT:    br label [[JOIN]]
+; CHECK:       join:
+; CHECK-NEXT:    [[PHI:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 4
+; CHECK-NEXT:    ret ptr [[PHI]]
+;
+  br i1 %c, label %if, label %else
+
+if:
+  %gep1 = getelementptr inbounds i32, ptr %p, i64 1
+  br label %join
+
+else:
+  %gep2 = getelementptr nusw nuw i32, ptr %p, i64 1
+  br label %join
+
+join:
+  %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
+  ret ptr %phi
+}
+
+define ptr @phi_of_gep_flags_2(i1 %c, ptr %p) {
+; CHECK-LABEL: @phi_of_gep_flags_2(
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK:       if:
+; CHECK-NEXT:    br label [[JOIN:%.*]]
+; CHECK:       else:
+; CHECK-NEXT:    br label [[JOIN]]
+; CHECK:       join:
+; CHECK-NEXT:    [[PHI:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 4
+; CHECK-NEXT:    ret ptr [[PHI]]
+;
+  br i1 %c, label %if, label %else
+
+if:
+  %gep1 = getelementptr nusw nuw i32, ptr %p, i64 1
+  br label %join
+
+else:
+  %gep2 = getelementptr nuw i32, ptr %p, i64 1
+  br label %join
+
+join:
+  %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
+  ret ptr %phi
+}
+
 define ptr @phi_of_gep_
diff erent_type(i1 %c, ptr %p) {
 ; CHECK-LABEL: @phi_of_gep_
diff erent_type(
 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]


        


More information about the llvm-commits mailing list