llvm.org GIT mirror llvm / 9e194fb
Merging r296093 and r296260: ------------------------------------------------------------------------ r296093 | ctopper | 2017-02-23 22:38:24 -0800 (Thu, 23 Feb 2017) | 1 line [ExecutionDepsFix] Use range-based for loop. NFC ------------------------------------------------------------------------ ------------------------------------------------------------------------ r296260 | ctopper | 2017-02-25 10:12:25 -0800 (Sat, 25 Feb 2017) | 18 lines [ExecutionDepsFix] Don't make copies of LiveReg objects when collecting operands for soft instructions Summary: While collecting operands we make copies of the LiveReg objects which are stored in the LiveRegs array. If the instruction uses the same register multiple times we end up with multiple copies. Later we iterate through the collected list of LiveReg objects and merge DomainValues. In the process of doing this the merge function can change the contents of the original LiveReg object in the LiveRegs array, but not the copies that have been made. So when we get to the second usage of the register we end up seeing a stale copy of the LiveReg object. To fix this I've stopped copying and now just store a pointer to the original LiveReg object. Another option might be to avoid adding the same register to the Regs array twice, but this approach seemed simpler. The included test case exposes this bug due to an AVX-512 masked OR instruction using the same register for the passthru operand and one of the inputs to the OR operation. Fixes PR30284. Reviewers: RKSimon, stoklund, MatzeB, spatel, myatsina Reviewed By: RKSimon Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D30242 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_40@296380 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 2 years ago
2 changed file(s) with 31 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
706706
707707 // Kill off any remaining uses that don't match available, and build a list of
708708 // incoming DomainValues that we want to merge.
709 SmallVector Regs;
710 for (SmallVectorImpl::iterator i=used.begin(), e=used.end(); i!=e; ++i) {
711 int rx = *i;
709 SmallVector Regs;
710 for (int rx : used) {
712711 assert(LiveRegs && "no space allocated for live registers");
713712 const LiveReg &LR = LiveRegs[rx];
714713 // This useless DomainValue could have been missed above.
717716 continue;
718717 }
719718 // Sorted insertion.
720 bool Inserted = false;
721 for (SmallVectorImpl::iterator i = Regs.begin(), e = Regs.end();
722 i != e && !Inserted; ++i) {
723 if (LR.Def < i->Def) {
724 Inserted = true;
725 Regs.insert(i, LR);
726 }
727 }
728 if (!Inserted)
729 Regs.push_back(LR);
719 auto I = std::upper_bound(Regs.begin(), Regs.end(), &LR,
720 [](const LiveReg *LHS, const LiveReg *RHS) {
721 return LHS->Def < RHS->Def;
722 });
723 Regs.insert(I, &LR);
730724 }
731725
732726 // doms are now sorted in order of appearance. Try to merge them all, giving
734728 DomainValue *dv = nullptr;
735729 while (!Regs.empty()) {
736730 if (!dv) {
737 dv = Regs.pop_back_val().Value;
731 dv = Regs.pop_back_val()->Value;
738732 // Force the first dv to match the current instruction.
739733 dv->AvailableDomains = dv->getCommonDomains(available);
740734 assert(dv->AvailableDomains && "Domain should have been filtered");
741735 continue;
742736 }
743737
744 DomainValue *Latest = Regs.pop_back_val().Value;
738 DomainValue *Latest = Regs.pop_back_val()->Value;
745739 // Skip already merged values.
746740 if (Latest == dv || Latest->Next)
747741 continue;
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -mattr=avx512dq | FileCheck %s
2
3 define void @f_f___un_3C_unf_3E_un_3C_unf_3E_() {
4 ; CHECK-LABEL: f_f___un_3C_unf_3E_un_3C_unf_3E_:
5 ; CHECK: # BB#0:
6 ; CHECK-NEXT: vmovapd 0, %zmm0
7 ; CHECK-NEXT: vmovapd 64, %zmm1
8 ; CHECK-NEXT: vmovapd {{.*#+}} zmm2 = [0,16,0,16,0,16,0,16,0,16,0,16,0,16,0,16]
9 ; CHECK-NEXT: kshiftrw $8, %k0, %k1
10 ; CHECK-NEXT: vorpd %zmm2, %zmm1, %zmm1 {%k1}
11 ; CHECK-NEXT: vorpd %zmm2, %zmm0, %zmm0 {%k1}
12 ; CHECK-NEXT: vmovapd %zmm0, 0
13 ; CHECK-NEXT: vmovapd %zmm1, 64
14 ; CHECK-NEXT: retl
15 %a_load22 = load <16 x i64>, <16 x i64>* null, align 1
16 %bitop = or <16 x i64> %a_load22,
17 %v.i = load <16 x i64>, <16 x i64>* null
18 %v1.i41 = select <16 x i1> undef, <16 x i64> %bitop, <16 x i64> %v.i
19 store <16 x i64> %v1.i41, <16 x i64>* null
20 ret void
21 }