]> granicus.if.org Git - llvm/commitdiff
TableGen/GlobalISel: Fix handling of truncstore patterns
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Mon, 15 Jul 2019 21:15:20 +0000 (21:15 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Mon, 15 Jul 2019 21:15:20 +0000 (21:15 +0000)
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

test/TableGen/address-space-patfrags.td
utils/TableGen/GlobalISelEmitter.cpp

index f6c5d11449803635d11a222801ef3ee6aaafbe08..029170e8414fac630eb6fb01c607d70e66003cd9 100644 (file)
@@ -38,6 +38,11 @@ def inst_b : Instruction {
   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 @@ def : Pat <
   (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 4940d911f66373960f82a670ec21d953b833f4c0..f1c02134198bd3e431e288b4698d72de7260cbbc 100644 (file)
@@ -314,7 +314,7 @@ static Error isTrivialOperatorNode(const TreePatternNode *N) {
         Predicate.isSignExtLoad() || Predicate.isZeroExtLoad())
       continue;
 
-    if (Predicate.isNonTruncStore())
+    if (Predicate.isNonTruncStore() || Predicate.isTruncStore())
       continue;
 
     if (Predicate.isLoad() && Predicate.getMemoryVT())
@@ -3301,6 +3301,13 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
       continue;
     }
 
+    if (Predicate.isStore() && Predicate.isTruncStore()) {
+      // FIXME: If MemoryVT is set, we end up with 2 checks for the MMO size.
+      InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
+        0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
+      continue;
+    }
+
     // No check required. We already did it by swapping the opcode.
     if (!SrcGIEquivOrNull->isValueUnset("IfSignExtend") &&
         Predicate.isSignExtLoad())