diff options
author | Nikita Popov <npopov@redhat.com> | 2024-06-19 12:13:12 +0200 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2024-06-19 12:13:54 +0200 |
commit | 6467b49480cbf2aaa7cf22a0dab1d7b15fe54fd1 (patch) | |
tree | 4041588678c225b7258a8050041778c16c6263f8 | |
parent | e7b4b437fbbf087ac4955ed5945c3e2f3dd2b702 (diff) | |
download | llvm-6467b49480cbf2aaa7cf22a0dab1d7b15fe54fd1.zip llvm-6467b49480cbf2aaa7cf22a0dab1d7b15fe54fd1.tar.gz llvm-6467b49480cbf2aaa7cf22a0dab1d7b15fe54fd1.tar.bz2 |
[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.
-rw-r--r-- | llvm/include/llvm/IR/GEPNoWrapFlags.h | 3 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp | 7 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/opaque-ptr.ll | 52 |
3 files changed, 58 insertions, 4 deletions
diff --git a/llvm/include/llvm/IR/GEPNoWrapFlags.h b/llvm/include/llvm/IR/GEPNoWrapFlags.h index 4d456cc..55a25c6 100644 --- a/llvm/include/llvm/IR/GEPNoWrapFlags.h +++ b/llvm/include/llvm/IR/GEPNoWrapFlags.h @@ -44,6 +44,9 @@ public: : 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 dd8eb46..0ee9bc5 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 7502034..df85547 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_different_type(i1 %c, ptr %p) { ; CHECK-LABEL: @phi_of_gep_different_type( ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] |