llvm.org GIT mirror llvm / 59e121a
TableGen/GlobalISel: Fix handling of truncstore patterns This was failing to import the AMDGPU truncstore patterns. The truncating stores from 32-bit to 8/16 were then somehow being incorrectly selected to a 4-byte store. A separate check is emitted for the LLT size in comparison to the specific memory VT, which looks strange to me but makes sense based on the hierarchy of PatFrags used for the default truncstore PatFrags. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366129 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault a month ago
2 changed file(s) with 46 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
3535 def inst_b : Instruction {
3636 let OutOperandList = (outs GPR32:$dst);
3737 let InOperandList = (ins GPR32:$src);
38 }
39
40 def inst_c : Instruction {
41 let OutOperandList = (outs);
42 let InOperandList = (ins GPR32:$src0, GPR32:$src1);
3843 }
3944
4045 // SDAG: case 2: {
8287 (pat_frag_b GPR32:$src),
8388 (inst_b GPR32:$src)
8489 >;
90
91
92 def truncstorei16_addrspace : PatFrag<(ops node:$val, node:$ptr),
93 (truncstore node:$val, node:$ptr)> {
94 let IsStore = 1;
95 let MemoryVT = i16;
96 let AddressSpaces = [ 123, 455 ];
97 }
98
99 // Test truncstore without a specific MemoryVT
100 // GISEL: GIM_Try, /*On fail goto*//*Label 2*/ 133, // Rule ID 2 //
101 // GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
102 // GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_STORE,
103 // GISEL-NEXT: GIM_CheckMemorySizeLessThanLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
104 // GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic,
105 // GISEL-NEXT: // MIs[0] src0
106 // GISEL-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
107 def : Pat <
108 (truncstore GPR32:$src0, GPR32:$src1),
109 (inst_c GPR32:$src0, GPR32:$src1)
110 >;
111
112 // Test truncstore with specific MemoryVT
113 // GISEL: GIM_Try, /*On fail goto*//*Label 3*/ 181, // Rule ID 3 //
114 // GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
115 // GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_STORE,
116 // GISEL-NEXT: GIM_CheckMemorySizeLessThanLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
117 // GISEL-NEXT: GIM_CheckMemoryAddressSpace, /*MI*/0, /*MMO*/0, /*NumAddrSpace*/2, /*AddrSpace*/123, /*AddrSpace*/455,
118 // GISEL-NEXT: GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/2,
119 def : Pat <
120 (truncstorei16_addrspace GPR32:$src0, GPR32:$src1),
121 (inst_c GPR32:$src0, GPR32:$src1)
122 >;
313313 Predicate.isSignExtLoad() || Predicate.isZeroExtLoad())
314314 continue;
315315
316 if (Predicate.isNonTruncStore())
316 if (Predicate.isNonTruncStore() || Predicate.isTruncStore())
317317 continue;
318318
319319 if (Predicate.isLoad() && Predicate.getMemoryVT())
33003300 continue;
33013301 }
33023302
3303 if (Predicate.isStore() && Predicate.isTruncStore()) {
3304 // FIXME: If MemoryVT is set, we end up with 2 checks for the MMO size.
3305 InsnMatcher.addPredicate(
3306 0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
3307 continue;
3308 }
3309
33033310 // No check required. We already did it by swapping the opcode.
33043311 if (!SrcGIEquivOrNull->isValueUnset("IfSignExtend") &&
33053312 Predicate.isSignExtLoad())