Index: test/TableGen/address-space-patfrags.td =================================================================== --- test/TableGen/address-space-patfrags.td +++ test/TableGen/address-space-patfrags.td @@ -38,6 +38,11 @@ let InOperandList = (ins GPR32:$src); } +def inst_c : Instruction { + let OutOperandList = (outs); + let InOperandList = (ins GPR32:$src0, GPR32:$src1); +} + // SDAG: case 2: { // SDAG: // Predicate_pat_frag_a // SDAG-NEXT: SDNode *N = Node; @@ -83,3 +88,36 @@ (pat_frag_b GPR32:$src), (inst_b GPR32:$src) >; + + +def truncstorei16_addrspace : PatFrag<(ops node:$val, node:$ptr), + (truncstore node:$val, node:$ptr)> { + let IsStore = 1; + let MemoryVT = i16; + let AddressSpaces = [ 123, 455 ]; +} + +// Test truncstore without a specific MemoryVT +// GISEL: GIM_Try, /*On fail goto*//*Label 2*/ 133, // Rule ID 2 // +// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, +// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_STORE, +// GISEL-NEXT: GIM_CheckMemorySizeLessThanLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0, +// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic, +// GISEL-NEXT: // MIs[0] src0 +// GISEL-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +def : Pat < + (truncstore GPR32:$src0, GPR32:$src1), + (inst_c GPR32:$src0, GPR32:$src1) +>; + +// Test truncstore with specific MemoryVT +// GISEL: GIM_Try, /*On fail goto*//*Label 3*/ 181, // Rule ID 3 // +// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, +// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_STORE, +// GISEL-NEXT: GIM_CheckMemorySizeLessThanLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0, +// GISEL-NEXT: GIM_CheckMemoryAddressSpace, /*MI*/0, /*MMO*/0, /*NumAddrSpace*/2, /*AddrSpace*/123, /*AddrSpace*/455, +// GISEL-NEXT: GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/2, +def : Pat < + (truncstorei16_addrspace GPR32:$src0, GPR32:$src1), + (inst_c GPR32:$src0, GPR32:$src1) +>; Index: utils/TableGen/GlobalISelEmitter.cpp =================================================================== --- utils/TableGen/GlobalISelEmitter.cpp +++ utils/TableGen/GlobalISelEmitter.cpp @@ -318,7 +318,7 @@ Predicate.isSignExtLoad() || Predicate.isZeroExtLoad()) continue; - if (Predicate.isNonTruncStore()) + if (Predicate.isNonTruncStore() || Predicate.isTruncStore()) continue; if (Predicate.isLoad() && Predicate.getMemoryVT()) @@ -3305,6 +3305,13 @@ continue; } + if (Predicate.isStore() && Predicate.isTruncStore()) { + // FIXME: If MemoryVT is set, we end up with 2 checks for the MMO size. + InsnMatcher.addPredicate( + 0, MemoryVsLLTSizePredicateMatcher::LessThan, 0); + continue; + } + // No check required. We already did it by swapping the opcode. if (!SrcGIEquivOrNull->isValueUnset("IfSignExtend") && Predicate.isSignExtLoad())