|
| 1 | +Index: llvm/trunk/lib/Target/X86/X86DomainReassignment.cpp |
| 2 | +=================================================================== |
| 3 | +--- a/lib/Target/X86/X86DomainReassignment.cpp |
| 4 | ++++ b/lib/Target/X86/X86DomainReassignment.cpp |
| 5 | +@@ -26,6 +26,7 @@ |
| 6 | + #include "llvm/CodeGen/MachineRegisterInfo.h" |
| 7 | + #include "llvm/CodeGen/TargetRegisterInfo.h" |
| 8 | + #include "llvm/Support/Debug.h" |
| 9 | ++#include "llvm/Support/Printable.h" |
| 10 | + #include <bitset> |
| 11 | + |
| 12 | + using namespace llvm; |
| 13 | +@@ -291,8 +292,12 @@ |
| 14 | + /// Domains which this closure can legally be reassigned to. |
| 15 | + std::bitset<NumDomains> LegalDstDomains; |
| 16 | + |
| 17 | ++ /// An ID to uniquely identify this closure, even when it gets |
| 18 | ++ /// moved around |
| 19 | ++ unsigned ID; |
| 20 | ++ |
| 21 | + public: |
| 22 | +- Closure(std::initializer_list<RegDomain> LegalDstDomainList) { |
| 23 | ++ Closure(unsigned ID, std::initializer_list<RegDomain> LegalDstDomainList) : ID(ID) { |
| 24 | + for (RegDomain D : LegalDstDomainList) |
| 25 | + LegalDstDomains.set(D); |
| 26 | + } |
| 27 | +@@ -328,6 +333,10 @@ |
| 28 | + return Instrs; |
| 29 | + } |
| 30 | + |
| 31 | ++ unsigned getID() const { |
| 32 | ++ return ID; |
| 33 | ++ } |
| 34 | ++ |
| 35 | + }; |
| 36 | + |
| 37 | + class X86DomainReassignment : public MachineFunctionPass { |
| 38 | +@@ -339,7 +365,7 @@ |
| 39 | + DenseSet<unsigned> EnclosedEdges; |
| 40 | + |
| 41 | + /// All instructions that are included in some closure. |
| 42 | +- DenseMap<MachineInstr *, Closure *> EnclosedInstrs; |
| 43 | ++ DenseMap<MachineInstr *, unsigned> EnclosedInstrs; |
| 44 | + |
| 45 | + public: |
| 46 | + static char ID; |
| 47 | +@@ -416,14 +442,14 @@ |
| 48 | + void X86DomainReassignment::encloseInstr(Closure &C, MachineInstr *MI) { |
| 49 | + auto I = EnclosedInstrs.find(MI); |
| 50 | + if (I != EnclosedInstrs.end()) { |
| 51 | +- if (I->second != &C) |
| 52 | ++ if (I->second != C.getID()) |
| 53 | + // Instruction already belongs to another closure, avoid conflicts between |
| 54 | + // closure and mark this closure as illegal. |
| 55 | + C.setAllIllegal(); |
| 56 | + return; |
| 57 | + } |
| 58 | + |
| 59 | +- EnclosedInstrs[MI] = &C; |
| 60 | ++ EnclosedInstrs[MI] = C.getID(); |
| 61 | + C.addInstruction(MI); |
| 62 | + |
| 63 | + // Mark closure as illegal for reassignment to domains, if there is no |
| 64 | +@@ -705,6 +731,7 @@ |
| 65 | + std::vector<Closure> Closures; |
| 66 | + |
| 67 | + // Go over all virtual registers and calculate a closure. |
| 68 | ++ unsigned ClosureID = 0; |
| 69 | + for (unsigned Idx = 0; Idx < MRI->getNumVirtRegs(); ++Idx) { |
| 70 | + unsigned Reg = TargetRegisterInfo::index2VirtReg(Idx); |
| 71 | + |
| 72 | +@@ -717,20 +744,21 @@ |
| 73 | + continue; |
| 74 | + |
| 75 | + // Calculate closure starting with Reg. |
| 76 | +- Closure C({MaskDomain}); |
| 77 | ++ Closure C(ClosureID++, {MaskDomain}); |
| 78 | + buildClosure(C, Reg); |
| 79 | + |
| 80 | + // Collect all closures that can potentially be converted. |
| 81 | + if (!C.empty() && C.isLegal(MaskDomain)) |
| 82 | + Closures.push_back(std::move(C)); |
| 83 | + } |
| 84 | + |
| 85 | +- for (Closure &C : Closures) |
| 86 | ++ for (Closure &C : Closures) { |
| 87 | + if (isReassignmentProfitable(C, MaskDomain)) { |
| 88 | + reassign(C, MaskDomain); |
| 89 | + ++NumClosuresConverted; |
| 90 | + Changed = true; |
| 91 | + } |
| 92 | ++ } |
| 93 | + |
| 94 | + DeleteContainerSeconds(Converters); |
| 95 | + |
| 96 | +Index: llvm/trunk/test/CodeGen/X86/domain-reassignment-test.ll |
| 97 | +=================================================================== |
| 98 | +--- a/test/CodeGen/X86/domain-reassignment-test.ll |
| 99 | ++++ b/test/CodeGen/X86/domain-reassignment-test.ll |
| 100 | +@@ -0,0 +1,37 @@ |
| 101 | ++; RUN: llc -mcpu=skylake-avx512 -mtriple=x86_64-unknown-linux-gnu %s -o - | FileCheck %s |
| 102 | ++; RUN: llc -mcpu=skylake-avx512 -mtriple=x86_64-unknown-linux-gnu %s -o - | llvm-mc |
| 103 | ++ |
| 104 | ++; Check that the X86 domain reassignment pass doesn't introduce an illegal |
| 105 | ++; test instruction. See PR37396 |
| 106 | ++define void @japi1_foo2_34617() { |
| 107 | ++pass2: |
| 108 | ++ br label %if5 |
| 109 | ++ |
| 110 | ++L174: |
| 111 | ++ %tmp = icmp sgt <2 x i64> undef, zeroinitializer |
| 112 | ++ %tmp1 = icmp sle <2 x i64> undef, undef |
| 113 | ++ %tmp2 = and <2 x i1> %tmp, %tmp1 |
| 114 | ++ %tmp3 = extractelement <2 x i1> %tmp2, i32 0 |
| 115 | ++ %tmp4 = extractelement <2 x i1> %tmp2, i32 1 |
| 116 | ++ %tmp106 = and i1 %tmp4, %tmp3 |
| 117 | ++ %tmp107 = zext i1 %tmp106 to i8 |
| 118 | ++ %tmp108 = and i8 %tmp122, %tmp107 |
| 119 | ++ %tmp109 = icmp eq i8 %tmp108, 0 |
| 120 | ++; CHECK-NOT: testb {{%k[0-7]}} |
| 121 | ++ br i1 %tmp109, label %L188, label %L190 |
| 122 | ++ |
| 123 | ++if5: |
| 124 | ++ %b.055 = phi i8 [ 1, %pass2 ], [ %tmp122, %if5 ] |
| 125 | ++ %tmp118 = icmp sgt i64 undef, 0 |
| 126 | ++ %tmp119 = icmp sle i64 undef, undef |
| 127 | ++ %tmp120 = and i1 %tmp118, %tmp119 |
| 128 | ++ %tmp121 = zext i1 %tmp120 to i8 |
| 129 | ++ %tmp122 = and i8 %b.055, %tmp121 |
| 130 | ++ br i1 undef, label %L174, label %if5 |
| 131 | ++ |
| 132 | ++L188: |
| 133 | ++ unreachable |
| 134 | ++ |
| 135 | ++L190: |
| 136 | ++ ret void |
| 137 | ++} |
0 commit comments