[RISCV] Only combine (or (GREVI x, shamt), x) -> GORCI if shamt is a power of 2.
authorCraig Topper <craig.topper@sifive.com>
Mon, 30 Nov 2020 15:06:32 +0000 (07:06 -0800)
committerCraig Topper <craig.topper@sifive.com>
Mon, 30 Nov 2020 16:10:39 +0000 (08:10 -0800)
GORCI performs an OR between each stage. So we need to ensure only
one stage is active before doing this combine.

Initial attempts at finding a test case for this failed due to
the order things get combined. It's most likely that we'll form
one stage of GREVI then combine to GORCI before the two stages of
GREVI are able to be formed and combined with each other to form
a multi stage GREVI.

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

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

index 7a0d797..380b1a7 100644 (file)
@@ -1238,8 +1238,8 @@ static SDValue combineORToGREV(SDValue Op, SelectionDAG &DAG,
 }
 
 // Matches any the following pattern as a GORCI(W) operation
-// 1.  (or (GREVI x, shamt), x)
-// 2.  (or x, (GREVI x, shamt))
+// 1.  (or (GREVI x, shamt), x) if shamt is a power of 2
+// 2.  (or x, (GREVI x, shamt)) if shamt is a power of 2
 // 3.  (or (or (BITMANIP_SHL x), x), (BITMANIP_SRL x))
 // Note that with the variant of 3.,
 //     (or (or (BITMANIP_SHL x), (BITMANIP_SRL x)), x)
@@ -1258,7 +1258,8 @@ static SDValue combineORToGORC(SDValue Op, SelectionDAG &DAG,
     for (const auto &OpPair :
          {std::make_pair(Op0, Op1), std::make_pair(Op1, Op0)}) {
       if (OpPair.first.getOpcode() == RISCVISD::GREVI &&
-          OpPair.first.getOperand(0) == OpPair.second)
+          OpPair.first.getOperand(0) == OpPair.second &&
+          isPowerOf2_32(OpPair.first.getConstantOperandVal(1)))
         return DAG.getNode(RISCVISD::GORCI, DL, VT, OpPair.second,
                            OpPair.first.getOperand(1));
     }