[llvm] [RISCV][GISel] Added GISelPRedicateCodes to LeadingOnes*Mask (PR #119886)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 13 10:51:40 PST 2024


================
@@ -493,7 +493,15 @@ def LeadingOnesMask : PatLeaf<(imm), [{
   if (!N->hasOneUse())
     return false;
   return !isInt<32>(N->getSExtValue()) && isMask_64(~N->getSExtValue());
-}], TrailingZeros>;
+}], TrailingZeros> {
+  let GISelPredicateCode = [{
+    if (!MRI.hasOneNonDBGUse(MI.getOperand(0).getReg()))
+      return false;
+    const auto &MO = MI.getOperand(1);
----------------
topperc wrote:

> > The (imm) in the PatLeaf should guarantee this is only called for G_CONSTANT
> 
> I took a look through the generated match table code, and I couldn't find what guaranteed this, which is part of where my confusion came from.
> 
> The handler for `GIM_CheckCxxInsnPredicate` doesn't check the opcode before calling `testMIPredicate_MI` (which contains this C++), and if you look at e.g. `MatchTable0` in `RISCVGenGlobalISel.inc`, there's not always a `GIM_CheckOpcode` with `G_CONSTANT` before `GIM_CheckCxxInsnPredicate`.

GIM_CheckCxxInsnPredicate can be used for other opcodes than G_CONSTANT. The opcode check should be based on the root specified in the `PatLeaf` or `PatFrag`. In this case it was G_CONSTANT. For `GICXXPred_MI_Predicate_add_non_imm12` and , the opcode is G_ADD which is checked by the top level `GIM_SwitchOpcode` instead of a `GIM_CheckOpcode`.

https://github.com/llvm/llvm-project/pull/119886


More information about the llvm-commits mailing list