diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index fa6ee95d33d10..d6f55bbea7abe 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -2499,11 +2499,11 @@ void GVNPass::assignBlockRPONumber(Function &F) { bool GVNPass::replaceOperandsForInBlockEquality(Instruction *Instr) const { bool Changed = false; for (unsigned OpNum = 0; OpNum < Instr->getNumOperands(); ++OpNum) { - Value *Operand = Instr->getOperand(OpNum); - auto It = ReplaceOperandsWithMap.find(Operand); + Use &Operand = Instr->getOperandUse(OpNum); + auto It = ReplaceOperandsWithMap.find(Operand.get()); if (It != ReplaceOperandsWithMap.end()) { - // Do not replace lifetime alloca argument with something else. - if (Instr->isLifetimeStartOrEnd()) + const DataLayout &DL = Instr->getDataLayout(); + if (!canReplacePointersInUseIfEqual(Operand, It->second, DL)) continue; LLVM_DEBUG(dbgs() << "GVN replacing: " << *Operand << " with " diff --git a/llvm/test/Transforms/GVN/assume-equal.ll b/llvm/test/Transforms/GVN/assume-equal.ll index a27b0e45bf9e1..0c922daf82b32 100644 --- a/llvm/test/Transforms/GVN/assume-equal.ll +++ b/llvm/test/Transforms/GVN/assume-equal.ll @@ -343,6 +343,50 @@ meh: ret i1 %k } +define i8 @assume_ptr_eq_different_prov_matters(ptr %p, ptr %p2) { +; CHECK-LABEL: define i8 @assume_ptr_eq_different_prov_matters( +; CHECK-SAME: ptr [[P:%.*]], ptr [[P2:%.*]]) { +; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P]], [[P2]] +; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) +; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P2]], align 1 +; CHECK-NEXT: ret i8 [[V]] +; + %cmp = icmp eq ptr %p, %p2 + call void @llvm.assume(i1 %cmp) + %v = load i8, ptr %p2 + ret i8 %v +} + +define i1 @assume_ptr_eq_different_prov_does_not_matter(ptr %p, ptr %p2) { +; CHECK-LABEL: define i1 @assume_ptr_eq_different_prov_does_not_matter( +; CHECK-SAME: ptr [[P:%.*]], ptr [[P2:%.*]]) { +; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P]], [[P2]] +; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) +; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[P]], null +; CHECK-NEXT: ret i1 [[C]] +; + %cmp = icmp eq ptr %p, %p2 + call void @llvm.assume(i1 %cmp) + %c = icmp eq ptr %p2, null + ret i1 %c +} + +define i8 @assume_ptr_eq_same_prov(ptr %p, i64 %x) { +; CHECK-LABEL: define i8 @assume_ptr_eq_same_prov( +; CHECK-SAME: ptr [[P:%.*]], i64 [[X:%.*]]) { +; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P]], [[P2]] +; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) +; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1 +; CHECK-NEXT: ret i8 [[V]] +; + %p2 = getelementptr i8, ptr %p, i64 %x + %cmp = icmp eq ptr %p, %p2 + call void @llvm.assume(i1 %cmp) + %v = load i8, ptr %p2 + ret i8 %v +} + declare noalias ptr @_Znwm(i64) declare void @_ZN1AC1Ev(ptr) declare void @llvm.assume(i1) diff --git a/llvm/test/Transforms/GVN/lifetime-simple.ll b/llvm/test/Transforms/GVN/lifetime-simple.ll index 30883bd9dc6d3..89ca127a47fda 100644 --- a/llvm/test/Transforms/GVN/lifetime-simple.ll +++ b/llvm/test/Transforms/GVN/lifetime-simple.ll @@ -29,7 +29,7 @@ define void @assume_eq_arg(ptr %arg) { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[ALLOCA]], [[ARG]] ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[ALLOCA]]) -; CHECK-NEXT: store volatile i32 0, ptr [[ARG]], align 4 +; CHECK-NEXT: store volatile i32 0, ptr [[ALLOCA]], align 4 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[ALLOCA]]) ; CHECK-NEXT: ret void ;