]> granicus.if.org Git - llvm/commitdiff
[GlobalISel] Check LLT size matches memory size for non-truncating stores.
authorAmara Emerson <aemerson@apple.com>
Fri, 2 Aug 2019 23:33:13 +0000 (23:33 +0000)
committerAmara Emerson <aemerson@apple.com>
Fri, 2 Aug 2019 23:33:13 +0000 (23:33 +0000)
This was causing a bug where non-truncating stores would be selected instead of truncating ones.

Differential Revision: https://reviews.llvm.org/D64845

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367737 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 82f924bcb180d8e6728d4ab72b362f442392d005..cf31294bfe0990f06d4168908940b3281c8447e1 100644 (file)
@@ -44,6 +44,11 @@ def inst_c : Instruction {
   let InOperandList = (ins GPR32:$src0, GPR32:$src1);
 }
 
+def inst_d : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins GPR32:$src0, GPR32:$src1);
+}
+
 // SDAG: case 2: {
 // SDAG-NEXT: // Predicate_pat_frag_b
 // SDAG-NEXT: SDNode *N = Node;
@@ -115,10 +120,20 @@ def : Pat <
   (inst_c GPR32:$src0, GPR32:$src1)
 >;
 
-// Test truncstore with specific MemoryVT
+// Test non-truncstore has a size equal to LLT check.
 // GISEL: GIM_Try, /*On fail goto*//*Label 3*/ {{[0-9]+}}, // Rule ID 3 //
 // GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
 // GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_STORE,
+// GISEL-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
+def : Pat <
+  (store GPR32:$src0, GPR32:$src1),
+  (inst_d GPR32:$src0, GPR32:$src1)
+>;
+
+// Test truncstore with specific MemoryVT
+// GISEL: GIM_Try, /*On fail goto*//*Label 4*/ {{[0-9]+}}, // Rule ID 4 //
+// 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,
index 7e17dafc832dd6ebe4f1540b2ed62bde7470d18b..06cdfd4ab5970c5f0eb4519c47e7c37473cd956e 100644 (file)
@@ -3347,11 +3347,19 @@ 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;
+    if (Predicate.isStore()) {
+      if (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;
+      }
+      if (Predicate.isNonTruncStore()) {
+        // We need to check the sizes match here otherwise we could incorrectly
+        // match truncating stores with non-truncating ones.
+        InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
+            0, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);
+      }
     }
 
     // No check required. We already did it by swapping the opcode.