Skip to content

[GISel] Infer the type of an immediate when there is one element in TEC #77399

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 9, 2024

Conversation

s-barannikov
Copy link
Contributor

When there is just one element in the type equivalence class (TEC), inferNamedOperandType fails because it does not consider the passed operand as a suitable one. This is incorrect when inferring the type of an (unnamed) immediate operand.

When there is just one element in the type equivalence class (TEC),
`inferNamedOperandType` fails because it does not consider the passed
operand as a suitable one. This is incorrect when inferring the type of
an (unnamed) immediate operand.
@llvmbot
Copy link
Member

llvmbot commented Jan 9, 2024

@llvm/pr-subscribers-llvm-globalisel

Author: Sergei Barannikov (s-barannikov)

Changes

When there is just one element in the type equivalence class (TEC), inferNamedOperandType fails because it does not consider the passed operand as a suitable one. This is incorrect when inferring the type of an (unnamed) immediate operand.


Full diff: https://github.com/llvm/llvm-project/pull/77399.diff

2 Files Affected:

  • (modified) llvm/test/TableGen/GlobalISelCombinerEmitter/type-inference.td (+23-4)
  • (modified) llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp (+9-6)
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/type-inference.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/type-inference.td
index c9ffe4e7adb3db..ed4e0e411c7afd 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/type-inference.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/type-inference.td
@@ -1,5 +1,5 @@
 // RUN: llvm-tblgen -I %p/../../../include -gen-global-isel-combiner \
-// RUN:     -gicombiner-debug-typeinfer -combiners=MyCombiner %s 2>&1 | \
+// RUN:     -gicombiner-debug-typeinfer -combiners=MyCombiner %s 2>&1 >/dev/null | \
 // RUN: FileCheck %s
 
 // Checks reasoning of the inference rules.
@@ -10,13 +10,15 @@ include "llvm/Target/GlobalISel/Combine.td"
 def MyTargetISA : InstrInfo;
 def MyTarget : Target { let InstructionSet = MyTargetISA; }
 
+// This also checks that the type of a def is preferred when inferring the type
+// of an immediate.
 // CHECK:      Rule Operand Type Equivalence Classes for inference_mul_by_neg_one:
 // CHECK-NEXT:         Groups for __inference_mul_by_neg_one_match_0:             [dst, x]
 // CHECK-NEXT:         Groups for __inference_mul_by_neg_one_apply_0:             [dst, x]
 // CHECK-NEXT: Final Type Equivalence Classes: [dst, x]
-// CHECK-NEXT: INFER: imm 0 -> GITypeOf<$x>
+// CHECK-NEXT: INFER: imm 0 -> GITypeOf<$dst>
 // CHECK-NEXT: Apply patterns for rule inference_mul_by_neg_one after inference:
-// CHECK-NEXT:   (CodeGenInstructionPattern name:__inference_mul_by_neg_one_apply_0 G_SUB operands:[<def>$dst, (GITypeOf<$x> 0), $x])
+// CHECK-NEXT:   (CodeGenInstructionPattern name:__inference_mul_by_neg_one_apply_0 G_SUB operands:[<def>$dst, (GITypeOf<$dst> 0), $x])
 def inference_mul_by_neg_one: GICombineRule <
   (defs root:$dst),
   (match (G_MUL $dst, $x, -1)),
@@ -61,8 +63,25 @@ def infer_variadic_outs: GICombineRule <
          (COPY $dst, $tmp))
 >;
 
+// Check that the type of an immediate is inferred when there is just one
+// element in the corresponding equivalence class.
+// CHECK:      Rule Operand Type Equivalence Classes for infer_imm_0:
+// CHECK-NEXT:   Groups for __infer_imm_0_match_0: [dst]
+// CHECK-NEXT:   Groups for __infer_imm_0_apply_0: [dst]
+// CHECK-NEXT: Final Type Equivalence Classes: [dst]
+// CHECK-NEXT: INFER: imm 1 -> GITypeOf<$dst>
+// CHECK-NEXT: INFER: imm 2 -> GITypeOf<$dst>
+// CHECK-NEXT: Apply patterns for rule infer_imm_0 after inference:
+// CHECK-NEXT:   (CodeGenInstructionPattern name:__infer_imm_0_apply_0 G_ADD operands:[<def>$dst, (GITypeOf<$dst> 1), (GITypeOf<$dst> 2)])
+def infer_imm_0 : GICombineRule<
+  (defs root:$dst),
+  (match (G_ADD $dst, 0, 3)),
+  (apply (G_ADD $dst, 1, 2))
+>;
+
 def MyCombiner: GICombiner<"GenMyCombiner", [
   inference_mul_by_neg_one,
   infer_complex_tempreg,
-  infer_variadic_outs
+  infer_variadic_outs,
+  infer_imm_0,
 ]>;
diff --git a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
index 89aca87a28ec0d..9121139be93540 100644
--- a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
@@ -284,7 +284,8 @@ class CombineRuleOperandTypeChecker : private OperandTypeChecker {
   /// succeed.
   PatternType inferNamedOperandType(const InstructionPattern &IP,
                                     StringRef OpName,
-                                    const TypeEquivalenceClasses &TECs) const;
+                                    const TypeEquivalenceClasses &TECs,
+                                    bool AllowSelf = false) const;
 
   const Record &RuleDef;
   SmallVector<InstructionPattern *, 8> MatchPats;
@@ -428,7 +429,8 @@ PatternType CombineRuleOperandTypeChecker::inferImmediateType(
 
       // Named operand with the same name, try to infer that.
       if (PatternType InferTy =
-              inferNamedOperandType(IP, Op.getOperandName(), TECs))
+              inferNamedOperandType(IP, Op.getOperandName(), TECs,
+                                    /*IncludeSelf=*/true))
         return InferTy;
     }
   }
@@ -438,16 +440,17 @@ PatternType CombineRuleOperandTypeChecker::inferImmediateType(
 
 PatternType CombineRuleOperandTypeChecker::inferNamedOperandType(
     const InstructionPattern &IP, StringRef OpName,
-    const TypeEquivalenceClasses &TECs) const {
+    const TypeEquivalenceClasses &TECs, bool AllowSelf) const {
   // This is the simplest possible case, we just need to find a TEC that
-  // contains OpName. Look at all other operands in equivalence class and try to
-  // find a suitable one.
+  // contains OpName. Look at all operands in equivalence class and try to
+  // find a suitable one. If `AllowSelf` is true, the operand itself is also
+  // considered suitable.
 
   // Check for a def of a matched pattern. This is guaranteed to always
   // be a register so we can blindly use that.
   StringRef GoodOpName;
   for (auto It = TECs.findLeader(OpName); It != TECs.member_end(); ++It) {
-    if (*It == OpName)
+    if (!AllowSelf && *It == OpName)
       continue;
 
     const auto LookupRes = MatchOpTable.lookup(*It);

Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with nit

@@ -428,7 +429,8 @@ PatternType CombineRuleOperandTypeChecker::inferImmediateType(

// Named operand with the same name, try to infer that.
if (PatternType InferTy =
inferNamedOperandType(IP, Op.getOperandName(), TECs))
inferNamedOperandType(IP, Op.getOperandName(), TECs,
/*IncludeSelf=*/true))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Operand name doesn't match the function definition's "AllowSelf"

Copy link
Contributor

@Pierre-vh Pierre-vh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@s-barannikov s-barannikov merged commit f92b928 into llvm:main Jan 9, 2024
@s-barannikov s-barannikov deleted the gisel/type-infer-imm branch January 9, 2024 10:49
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
…EC (llvm#77399)

When there is just one element in the type equivalence class (TEC),
`inferNamedOperandType` fails because it does not consider the passed
operand as a suitable one. This is incorrect when inferring the type of
an (unnamed) immediate operand.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants