aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2024-06-19 12:13:12 +0200
committerNikita Popov <npopov@redhat.com>2024-06-19 12:13:54 +0200
commit6467b49480cbf2aaa7cf22a0dab1d7b15fe54fd1 (patch)
tree4041588678c225b7258a8050041778c16c6263f8
parente7b4b437fbbf087ac4955ed5945c3e2f3dd2b702 (diff)
downloadllvm-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.h3
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp7
-rw-r--r--llvm/test/Transforms/InstCombine/opaque-ptr.ll52
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:%.*]]