diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -823,6 +823,16 @@ return true; } + /// Helper function to replace all uses of \p V with \p NV. Return true if + /// there is any change. + bool changeValueAfterManifest(Value &V, Value &NV) { + bool Changed = false; + for (auto &U : V.uses()) + Changed |= changeUseAfterManifest(U, NV); + + return Changed; + } + /// Get pointer operand of memory accessing instruction. If \p I is /// not a memory accessing instruction, return nullptr. If \p AllowVolatile, /// is set to false and the instruction is volatile, return nullptr. diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -2574,9 +2574,7 @@ return ChangeStatus::UNCHANGED; UndefValue &UV = *UndefValue::get(V.getType()); - bool AnyChange = false; - for (Use &U : V.uses()) - AnyChange |= A.changeUseAfterManifest(U, UV); + bool AnyChange = A.changeValueAfterManifest(V, UV); return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; } @@ -4149,7 +4147,7 @@ if (!V.user_empty() && &V != C && V.getType() == C->getType()) { LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C << "\n"); - replaceAllInstructionUsesWith(V, *C); + A.changeValueAfterManifest(V, *C); Changed = ChangeStatus::CHANGED; } } diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll @@ -9,7 +9,7 @@ ; CHECK-SAME: (i1 [[C:%.*]], i32* noalias nocapture nofree nonnull readonly dereferenceable(4) [[A:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A_0:%.*]] = load i32, i32* null -; CHECK-NEXT: br i1 false, label [[T:%.*]], label [[F:%.*]] +; CHECK-NEXT: br label [[F:%.*]] ; CHECK: T: ; CHECK-NEXT: unreachable ; CHECK: F: diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll @@ -6,7 +6,7 @@ ; CHECK-LABEL: define {{[^@]+}}@callee ; CHECK-SAME: (i1 [[C:%.*]], i32* noalias nocapture nofree readnone [[P:%.*]]) ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]] +; CHECK-NEXT: br label [[T:%.*]] ; CHECK: T: ; CHECK-NEXT: ret i32 17 ; CHECK: F: diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll @@ -6,11 +6,11 @@ define internal i32 @callee(i1 %C, i32* %P) { ; CHECK-LABEL: define {{[^@]+}}@callee ; CHECK-SAME: (i1 [[C:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) -; CHECK-NEXT: br i1 false, label [[T:%.*]], label [[F:%.*]] +; CHECK-NEXT: br label [[F:%.*]] ; CHECK: T: ; CHECK-NEXT: unreachable ; CHECK: F: -; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4 +; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P:%.*]], align 4 ; CHECK-NEXT: ret i32 [[X]] ; br i1 %C, label %T, label %F diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll @@ -17,7 +17,7 @@ ; CHECK-LABEL: define {{[^@]+}}@fn ; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P1:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P2:%.*]]) ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* @c, align 8, !tbaa !0 +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* undef, align 8, !tbaa !0 ; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @g, align 4, !tbaa !4 ; CHECK-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP1]] to i8 diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll --- a/llvm/test/Transforms/Attributor/value-simplify.ll +++ b/llvm/test/Transforms/Attributor/value-simplify.ll @@ -145,7 +145,7 @@ define internal i1 @ipccp2i(i1 %a) { ; CHECK-LABEL: define {{[^@]+}}@ipccp2i ; CHECK-SAME: (i1 returned [[A:%.*]]) #0 -; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]] +; CHECK-NEXT: br label %t ; CHECK: t: ; CHECK-NEXT: ret i1 true ; CHECK: f: