[llvm-branch-commits] [llvm] 701620d - [SVE] Precommit test to show missing initialisation of call operand.

2023-09-25 Thread Tobias Hieta via llvm-branch-commits

Author: Paul Walker
Date: 2023-09-25T13:02:05+02:00
New Revision: 701620d58cdf00212eadabfde28cea53c5b06675

URL: 
https://github.com/llvm/llvm-project/commit/701620d58cdf00212eadabfde28cea53c5b06675
DIFF: 
https://github.com/llvm/llvm-project/commit/701620d58cdf00212eadabfde28cea53c5b06675.diff

LOG: [SVE] Precommit test to show missing initialisation of call operand.

When calling func_f8_and_v0_passed_via_memory the memory used to
hold the first vector operand is allocated but not initialised.

Added: 


Modified: 
llvm/test/CodeGen/AArch64/sve-calling-convention-mixed.ll

Removed: 




diff  --git a/llvm/test/CodeGen/AArch64/sve-calling-convention-mixed.ll 
b/llvm/test/CodeGen/AArch64/sve-calling-convention-mixed.ll
index 251e06bad004bab..bd5337083f774a1 100644
--- a/llvm/test/CodeGen/AArch64/sve-calling-convention-mixed.ll
+++ b/llvm/test/CodeGen/AArch64/sve-calling-convention-mixed.ll
@@ -64,13 +64,13 @@ define float @foo2(ptr %x0, ptr %x1) nounwind {
 ; CHECK-NEXT:ld4d { z16.d - z19.d }, p0/z, [x1]
 ; CHECK-NEXT:fmov s0, #1.
 ; CHECK-NEXT:mov w0, wzr
-; CHECK-NEXT:mov w1, #1
-; CHECK-NEXT:mov w2, #2
-; CHECK-NEXT:mov w3, #3
-; CHECK-NEXT:mov w4, #4
-; CHECK-NEXT:mov w5, #5
-; CHECK-NEXT:mov w6, #6
-; CHECK-NEXT:mov w7, #7
+; CHECK-NEXT:mov w1, #1 // =0x1
+; CHECK-NEXT:mov w2, #2 // =0x2
+; CHECK-NEXT:mov w3, #3 // =0x3
+; CHECK-NEXT:mov w4, #4 // =0x4
+; CHECK-NEXT:mov w5, #5 // =0x5
+; CHECK-NEXT:mov w6, #6 // =0x6
+; CHECK-NEXT:mov w7, #7 // =0x7
 ; CHECK-NEXT:add x9, sp, #16
 ; CHECK-NEXT:ptrue p0.d
 ; CHECK-NEXT:st1d { z16.d }, p0, [x9]
@@ -694,6 +694,36 @@ define  
@sve_ret_caller_non_sve_callee_high_range()  {
   ret  undef
 }
 
+declare void @func_f8_and_v0_passed_via_memory(float %f0, float %f1, float 
%f2, float %f3, float %f4, float %f5, float %f6, float %f7, float %f8,  %v0)
+define void @verify_all_operands_are_initialised() {
+; CHECK-LABEL: verify_all_operands_are_initialised:
+; CHECK:   // %bb.0:
+; CHECK-NEXT:stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
+; CHECK-NEXT:addvl sp, sp, #-1
+; CHECK-NEXT:sub sp, sp, #16
+; CHECK-NEXT:.cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x20, 0x22, 0x11, 
0x08, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 32 + 8 * VG
+; CHECK-NEXT:.cfi_offset w30, -8
+; CHECK-NEXT:.cfi_offset w29, -16
+; CHECK-NEXT:movi d0, #
+; CHECK-NEXT:mov w8, #1090519040 // =0x4100
+; CHECK-NEXT:fmov s1, #1.
+; CHECK-NEXT:fmov s2, #2.
+; CHECK-NEXT:fmov s3, #3.
+; CHECK-NEXT:fmov s4, #4.
+; CHECK-NEXT:fmov s5, #5.
+; CHECK-NEXT:fmov s6, #6.
+; CHECK-NEXT:fmov s7, #7.
+; CHECK-NEXT:add x0, sp, #16
+; CHECK-NEXT:str w8, [sp]
+; CHECK-NEXT:bl func_f8_and_v0_passed_via_memory
+; CHECK-NEXT:addvl sp, sp, #1
+; CHECK-NEXT:add sp, sp, #16
+; CHECK-NEXT:ldp x29, x30, [sp], #16 // 16-byte Folded Reload
+; CHECK-NEXT:ret
+  call void @func_f8_and_v0_passed_via_memory(float 0.0, float 1.0, float 2.0, 
float 3.0, float 4.0, float 5.0, float 6.0, float 7.0, float 8.0,  shufflevector ( insertelement ( 
poison, float 9.00e+00, i64 0),  poison,  zeroinitializer))
+  ret void
+}
+
 declare float @callee1(float, , , 
)
 declare float @callee2(i32, i32, i32, i32, i32, i32, i32, i32, float, , )
 declare float @callee3(float, float, , , )



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] 2c04bdb - [SVE] Ensure SVE call operands passed via memory are correctly initialised. (#66070)

2023-09-25 Thread Tobias Hieta via llvm-branch-commits

Author: paulwalker-arm
Date: 2023-09-25T13:02:05+02:00
New Revision: 2c04bdb246777f9814750230b6e0ac6e21f31464

URL: 
https://github.com/llvm/llvm-project/commit/2c04bdb246777f9814750230b6e0ac6e21f31464
DIFF: 
https://github.com/llvm/llvm-project/commit/2c04bdb246777f9814750230b6e0ac6e21f31464.diff

LOG: [SVE] Ensure SVE call operands passed via memory are correctly 
initialised. (#66070)

The stores created when passing operands via memory don't typically
maintain the chain, because they can be done in any order. Instead,
a new chain is created based on all collated stores. SVE parameters
passed via memory don't follow this idiom and try to maintain the
chain, which unfortunately can result in them being incorrectly
deadcoded when the chain is recreated.

This patch brings the SVE side in line with the non-SVE side to
ensure no stores become lost whilst also allowing greater flexibility
when ordering the stores.

Added: 


Modified: 
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/test/CodeGen/AArch64/arm64ec-varargs.ll
llvm/test/CodeGen/AArch64/sve-calling-convention-mixed.ll

Removed: 




diff  --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp 
b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index c7a6dd7deb45b3a..a1753a40a1173ab 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -7388,7 +7388,9 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
   // Ensure we generate all stores for each tuple part, whilst updating the
   // pointer after each store correctly using vscale.
   while (NumParts) {
-Chain = DAG.getStore(Chain, DL, OutVals[i], Ptr, MPI);
+SDValue Store = DAG.getStore(Chain, DL, OutVals[i], Ptr, MPI);
+MemOpChains.push_back(Store);
+
 NumParts--;
 if (NumParts > 0) {
   SDValue BytesIncrement;

diff  --git a/llvm/test/CodeGen/AArch64/arm64ec-varargs.ll 
b/llvm/test/CodeGen/AArch64/arm64ec-varargs.ll
index 3950a3026769c89..1443a563efc35e7 100644
--- a/llvm/test/CodeGen/AArch64/arm64ec-varargs.ll
+++ b/llvm/test/CodeGen/AArch64/arm64ec-varargs.ll
@@ -35,15 +35,15 @@ define void @varargs_caller() nounwind {
 ; CHECK-NEXT:sub sp, sp, #48
 ; CHECK-NEXT:mov x4, sp
 ; CHECK-NEXT:add x8, sp, #16
-; CHECK-NEXT:mov x9, #4617315517961601024
-; CHECK-NEXT:mov x0, #4607182418800017408
-; CHECK-NEXT:mov w1, #2
-; CHECK-NEXT:mov x2, #4613937818241073152
-; CHECK-NEXT:mov w3, #4
-; CHECK-NEXT:mov w5, #16
+; CHECK-NEXT:mov x9, #4617315517961601024 // =0x4014
+; CHECK-NEXT:mov x0, #4607182418800017408 // =0x3ff0
+; CHECK-NEXT:mov w1, #2 // =0x2
+; CHECK-NEXT:mov x2, #4613937818241073152 // =0x4008
+; CHECK-NEXT:mov w3, #4 // =0x4
+; CHECK-NEXT:mov w5, #16 // =0x10
 ; CHECK-NEXT:stp xzr, x30, [sp, #24] // 8-byte Folded Spill
-; CHECK-NEXT:stp x8, xzr, [sp, #8]
-; CHECK-NEXT:str x9, [sp]
+; CHECK-NEXT:stp x9, x8, [sp]
+; CHECK-NEXT:str xzr, [sp, #16]
 ; CHECK-NEXT:bl varargs_callee
 ; CHECK-NEXT:ldr x30, [sp, #32] // 8-byte Folded Reload
 ; CHECK-NEXT:add sp, sp, #48
@@ -71,16 +71,16 @@ define void @varargs_many_argscalleer() nounwind {
 ; CHECK-NEXT:sub sp, sp, #64
 ; CHECK-NEXT:movi v0.2d, #
 ; CHECK-NEXT:mov x4, sp
-; CHECK-NEXT:mov x8, #4618441417868443648
+; CHECK-NEXT:mov x8, #4618441417868443648 // =0x4018
 ; CHECK-NEXT:add x9, sp, #16
 ; CHECK-NEXT:add x3, sp, #32
-; CHECK-NEXT:mov x0, #4607182418800017408
-; CHECK-NEXT:mov x1, #4611686018427387904
-; CHECK-NEXT:mov x2, #4613937818241073152
-; CHECK-NEXT:mov w5, #16
+; CHECK-NEXT:mov x0, #4607182418800017408 // =0x3ff0
+; CHECK-NEXT:mov x1, #4611686018427387904 // =0x4000
+; CHECK-NEXT:mov x2, #4613937818241073152 // =0x4008
+; CHECK-NEXT:mov w5, #16 // =0x10
 ; CHECK-NEXT:str x30, [sp, #48] // 8-byte Folded Spill
-; CHECK-NEXT:stp q0, q0, [sp, #16]
 ; CHECK-NEXT:stp x9, x8, [sp]
+; CHECK-NEXT:stp q0, q0, [sp, #16]
 ; CHECK-NEXT:bl varargs_many_argscallee
 ; CHECK-NEXT:ldr x30, [sp, #48] // 8-byte Folded Reload
 ; CHECK-NEXT:add sp, sp, #64

diff  --git a/llvm/test/CodeGen/AArch64/sve-calling-convention-mixed.ll 
b/llvm/test/CodeGen/AArch64/sve-calling-convention-mixed.ll
index bd5337083f774a1..a97649523565dc0 100644
--- a/llvm/test/CodeGen/AArch64/sve-calling-convention-mixed.ll
+++ b/llvm/test/CodeGen/AArch64/sve-calling-convention-mixed.ll
@@ -18,10 +18,10 @@ define float @foo1(ptr %x0, ptr %x1, ptr %x2) nounwind {
 ; CHECK-NEXT:ld1d { z5.d }, p0/z, [x2]
 ; CHECK-NEXT:mov x0, sp
 ; CHECK-NEXT:ptrue p0.d
-; CHECK-NEXT:st1d { z16.d }, p0, [sp]
-; CHECK-NEXT:st1d { z17.d }, p0, [sp, #1, mul vl]
-; CHECK-NEXT:s

[llvm-branch-commits] [libcxx] a13a894 - Bump version to 17.0.2

2023-09-25 Thread Tobias Hieta via llvm-branch-commits

Author: Tobias Hieta
Date: 2023-09-25T13:03:29+02:00
New Revision: a13a89402f530330880c92841cf551ddae00ead0

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

LOG: Bump version to 17.0.2

Added: 


Modified: 
libcxx/include/__config
llvm/CMakeLists.txt
llvm/utils/gn/secondary/llvm/version.gni
llvm/utils/lit/lit/__init__.py

Removed: 




diff  --git a/libcxx/include/__config b/libcxx/include/__config
index 2049c6dfc1e5c04..c37d643414aacdd 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -40,7 +40,7 @@
 // _LIBCPP_VERSION represents the version of libc++, which matches the version 
of LLVM.
 // Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), 
_LIBCPP_VERSION is
 // defined to XXYYZZ.
-#  define _LIBCPP_VERSION 170001
+#  define _LIBCPP_VERSION 170002
 
 #  define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
 #  define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)

diff  --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 471817d68286212..0d72593809ba35f 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -15,7 +15,7 @@ if(NOT DEFINED LLVM_VERSION_MINOR)
   set(LLVM_VERSION_MINOR 0)
 endif()
 if(NOT DEFINED LLVM_VERSION_PATCH)
-  set(LLVM_VERSION_PATCH 1)
+  set(LLVM_VERSION_PATCH 2)
 endif()
 if(NOT DEFINED LLVM_VERSION_SUFFIX)
   set(LLVM_VERSION_SUFFIX)

diff  --git a/llvm/utils/gn/secondary/llvm/version.gni 
b/llvm/utils/gn/secondary/llvm/version.gni
index b5ddeed7be33e26..27b6fa8c928d6b2 100644
--- a/llvm/utils/gn/secondary/llvm/version.gni
+++ b/llvm/utils/gn/secondary/llvm/version.gni
@@ -1,4 +1,4 @@
 llvm_version_major = 17
 llvm_version_minor = 0
-llvm_version_patch = 1
+llvm_version_patch = 2
 llvm_version = "$llvm_version_major.$llvm_version_minor.$llvm_version_patch"

diff  --git a/llvm/utils/lit/lit/__init__.py b/llvm/utils/lit/lit/__init__.py
index 6691f8cccf6c340..db19e8440df0d2f 100644
--- a/llvm/utils/lit/lit/__init__.py
+++ b/llvm/utils/lit/lit/__init__.py
@@ -2,7 +2,7 @@
 
 __author__ = "Daniel Dunbar"
 __email__ = "dan...@minormatter.com"
-__versioninfo__ = (17, 0, 1)
+__versioninfo__ = (17, 0, 2)
 __version__ = ".".join(str(v) for v in __versioninfo__) + "dev"
 
 __all__ = []



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] 4813589 - [GVN] Also remove phi nodes from VN table (PR65447)

2023-09-25 Thread Tobias Hieta via llvm-branch-commits

Author: Nikita Popov
Date: 2023-09-25T13:04:45+02:00
New Revision: 481358974fb0f732e33d503c224492a543f4d7bd

URL: 
https://github.com/llvm/llvm-project/commit/481358974fb0f732e33d503c224492a543f4d7bd
DIFF: 
https://github.com/llvm/llvm-project/commit/481358974fb0f732e33d503c224492a543f4d7bd.diff

LOG: [GVN] Also remove phi nodes from VN table (PR65447)

Followup to D158849: We also need to remove the phi node from the
VN table, which is not handled by removeInstruction().

Fixes https://github.com/llvm/llvm-project/issues/65447.

(cherry picked from commit 18e77760ce5e42d9057f69c3e64a8300d01a48ac)

Added: 
llvm/test/Transforms/GVN/pr65447.ll

Modified: 
llvm/lib/Transforms/Scalar/GVN.cpp

Removed: 




diff  --git a/llvm/lib/Transforms/Scalar/GVN.cpp 
b/llvm/lib/Transforms/Scalar/GVN.cpp
index b074c7c88b73505..4cfc0bacefbc570 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -2780,8 +2780,10 @@ bool GVNPass::processBlock(BasicBlock *BB) {
   // identical phis, and the second or later passes can eliminate them.
   SmallPtrSet PHINodesToRemove;
   ChangedFunction |= EliminateDuplicatePHINodes(BB, PHINodesToRemove);
-  for (PHINode *PN : PHINodesToRemove)
+  for (PHINode *PN : PHINodesToRemove) {
+VN.erase(PN);
 removeInstruction(PN);
+  }
 
   for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
BI != BE;) {

diff  --git a/llvm/test/Transforms/GVN/pr65447.ll 
b/llvm/test/Transforms/GVN/pr65447.ll
new file mode 100644
index 000..1b951e907e82220
--- /dev/null
+++ b/llvm/test/Transforms/GVN/pr65447.ll
@@ -0,0 +1,71 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --version 3
+; RUN: opt -S -passes=gvn < %s | FileCheck %s
+
+; Make sure deduplicated phi nodes are removed from the VN map.
+define i64 @f() {
+; CHECK-LABEL: define i64 @f() {
+; CHECK-NEXT:  BB:
+; CHECK-NEXT:store i1 false, ptr null, align 1
+; CHECK-NEXT:br label [[BB2D:%.*]]
+; CHECK:   BB2a:
+; CHECK-NEXT:br label [[BB2B:%.*]]
+; CHECK:   BB2b:
+; CHECK-NEXT:[[L93_PRE_PRE:%.*]] = load i1, ptr inttoptr (i64 -1 to ptr), 
align 1
+; CHECK-NEXT:br label [[BB2C:%.*]]
+; CHECK:   BB2c:
+; CHECK-NEXT:[[L93_PRE:%.*]] = phi i1 [ [[L93_PRE_PRE]], [[BB2B]] ], [ 
true, [[BB2D]] ]
+; CHECK-NEXT:[[AZ2:%.*]] = phi i1 [ true, [[BB2B]] ], [ [[AZ:%.*]], 
[[BB2D]] ]
+; CHECK-NEXT:[[DOTPHI_TRANS_INSERT:%.*]] = sext i1 [[AZ2]] to i64
+; CHECK-NEXT:[[GEP2_PHI_TRANS_INSERT:%.*]] = getelementptr i1, ptr null, 
i64 [[DOTPHI_TRANS_INSERT]]
+; CHECK-NEXT:br label [[BB2D]]
+; CHECK:   BB2d:
+; CHECK-NEXT:[[L93_PRE5:%.*]] = phi i1 [ [[L93_PRE]], [[BB2C]] ], [ false, 
[[BB:%.*]] ]
+; CHECK-NEXT:[[AZ]] = phi i1 [ [[AZ2]], [[BB2C]] ], [ false, [[BB]] ]
+; CHECK-NEXT:[[TMP0:%.*]] = sext i1 [[AZ]] to i64
+; CHECK-NEXT:[[GEP2:%.*]] = getelementptr i1, ptr null, i64 [[TMP0]]
+; CHECK-NEXT:store i1 [[AZ]], ptr null, align 2
+; CHECK-NEXT:br i1 [[L93_PRE5]], label [[BB2C]], label [[BB1E:%.*]]
+; CHECK:   BB1e:
+; CHECK-NEXT:br i1 [[AZ]], label [[BB2F:%.*]], label [[BB4:%.*]]
+; CHECK:   BB2f:
+; CHECK-NEXT:store i1 true, ptr null, align 2
+; CHECK-NEXT:br label [[BB2B]]
+; CHECK:   BB4:
+; CHECK-NEXT:br label [[BB4]]
+;
+BB:
+  store i1 false, ptr null, align 1
+  br label %BB2d
+
+BB2a: ; No predecessors!
+  br label %BB2b
+
+BB2b:   ; preds = %BB2f, %BB2a
+  br label %BB2c
+
+BB2c: ; preds = %BB2d, %BB2b
+  %0 = phi i1 [ true, %BB2b ], [ %1, %BB2d ]
+  br label %BB2d
+
+BB2d:  ; preds = %BB2c, %BB
+  %1 = phi i1 [ %0, %BB2c ], [ false, %BB ]
+  %2 = sext i1 %1 to i64
+  %gep2 = getelementptr i1, ptr null, i64 %2
+  %L93 = load i1, ptr %gep2, align 1
+  %Az = load i1, ptr null, align 2
+  store i1 %1, ptr null, align 2
+  br i1 %L93, label %BB2c, label %BB1e
+
+BB1e:; preds = %BB2d
+  br i1 %Az, label %BB2f, label %BB4
+
+BB2f:; preds = %BB1e
+  store i1 true, ptr null, align 2
+  br label %BB2b
+
+BB4:  ; preds = %BB1e, %BB4
+  br label %BB4
+
+; uselistorder directives
+  uselistorder label %BB4, { 1, 0 }
+}



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] 9f77e96 - [GVN] Invalidate MDA when deduplicating phi nodes

2023-09-25 Thread Tobias Hieta via llvm-branch-commits

Author: Nikita Popov
Date: 2023-09-25T13:04:45+02:00
New Revision: 9f77e96186be77a2bd07feb0b83681f452fc967d

URL: 
https://github.com/llvm/llvm-project/commit/9f77e96186be77a2bd07feb0b83681f452fc967d
DIFF: 
https://github.com/llvm/llvm-project/commit/9f77e96186be77a2bd07feb0b83681f452fc967d.diff

LOG: [GVN] Invalidate MDA when deduplicating phi nodes

Duplicate phi nodes were being directly removed, without
invalidating MDA. This could result in a new phi node being
allocated at the same address, incorrectly reusing a cache entry.

Fix this by optionally allowing EliminateDuplicatePHINodes() to
collect phi nodes to remove into a vector, which allows GVN to
handle removal itself.

Fixes https://github.com/llvm/llvm-project/issues/64598.

Differential Revision: https://reviews.llvm.org/D158849

(cherry picked from commit 7c229f6e85478bb0626a5e598f47b7be94bb50b0)

Added: 
llvm/test/Transforms/GVN/pr64598.ll

Modified: 
llvm/include/llvm/Transforms/Utils/Local.h
llvm/lib/Transforms/Scalar/GVN.cpp
llvm/lib/Transforms/Utils/Local.cpp

Removed: 




diff  --git a/llvm/include/llvm/Transforms/Utils/Local.h 
b/llvm/include/llvm/Transforms/Utils/Local.h
index 4578af069814d02..d23db1574e9daa4 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -162,8 +162,18 @@ bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock 
*BB,
 /// Check for and eliminate duplicate PHI nodes in this block. This doesn't try
 /// to be clever about PHI nodes which 
diff er only in the order of the incoming
 /// values, but instcombine orders them so it usually won't matter.
+///
+/// This overload removes the duplicate PHI nodes directly.
 bool EliminateDuplicatePHINodes(BasicBlock *BB);
 
+/// Check for and eliminate duplicate PHI nodes in this block. This doesn't try
+/// to be clever about PHI nodes which 
diff er only in the order of the incoming
+/// values, but instcombine orders them so it usually won't matter.
+///
+/// This overload collects the PHI nodes to be removed into the ToRemove set.
+bool EliminateDuplicatePHINodes(BasicBlock *BB,
+SmallPtrSetImpl &ToRemove);
+
 /// This function is used to do simplification of a CFG.  For example, it
 /// adjusts branches to branches to eliminate the extra hop, it eliminates
 /// unreachable basic blocks, and does other peephole optimization of the CFG.

diff  --git a/llvm/lib/Transforms/Scalar/GVN.cpp 
b/llvm/lib/Transforms/Scalar/GVN.cpp
index 03e8a2507b45c9d..b074c7c88b73505 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -2778,7 +2778,10 @@ bool GVNPass::processBlock(BasicBlock *BB) {
   // use our normal hash approach for phis.  Instead, simply look for
   // obvious duplicates.  The first pass of GVN will tend to create
   // identical phis, and the second or later passes can eliminate them.
-  ChangedFunction |= EliminateDuplicatePHINodes(BB);
+  SmallPtrSet PHINodesToRemove;
+  ChangedFunction |= EliminateDuplicatePHINodes(BB, PHINodesToRemove);
+  for (PHINode *PN : PHINodesToRemove)
+removeInstruction(PN);
 
   for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
BI != BE;) {

diff  --git a/llvm/lib/Transforms/Utils/Local.cpp 
b/llvm/lib/Transforms/Utils/Local.cpp
index f153ace5d3fc53a..eeb0446c11975d7 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1247,7 +1247,9 @@ bool 
llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
   return true;
 }
 
-static bool EliminateDuplicatePHINodesNaiveImpl(BasicBlock *BB) {
+static bool
+EliminateDuplicatePHINodesNaiveImpl(BasicBlock *BB,
+SmallPtrSetImpl &ToRemove) {
   // This implementation doesn't currently consider undef operands
   // specially. Theoretically, two phis which are identical except for
   // one having an undef where the other doesn't could be collapsed.
@@ -1263,12 +1265,14 @@ static bool 
EliminateDuplicatePHINodesNaiveImpl(BasicBlock *BB) {
 // Note that we only look in the upper square's triangle,
 // we already checked that the lower triangle PHI's aren't identical.
 for (auto J = I; PHINode *DuplicatePN = dyn_cast(J); ++J) {
+  if (ToRemove.contains(DuplicatePN))
+continue;
   if (!DuplicatePN->isIdenticalToWhenDefined(PN))
 continue;
   // A duplicate. Replace this PHI with the base PHI.
   ++NumPHICSEs;
   DuplicatePN->replaceAllUsesWith(PN);
-  DuplicatePN->eraseFromParent();
+  ToRemove.insert(DuplicatePN);
   Changed = true;
 
   // The RAUW can change PHIs that we already visited.
@@ -1279,7 +1283,9 @@ static bool 
EliminateDuplicatePHINodesNaiveImpl(BasicBlock *BB) {
   return Changed;
 }
 
-static bool EliminateDuplicatePHINodesSetBasedImpl(BasicBlock *BB) {
+static bool
+EliminateDuplicatePHINodesSetBasedIm