[llvm] [GlobalIsel] Transform build_vector(binop(_, C), ...) -> binop(bv, constant bv) (PR #73577)

Thorsten Schütt via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 28 02:53:38 PST 2023


================
@@ -6224,3 +6224,89 @@ void CombinerHelper::applyCommuteBinOpOperands(MachineInstr &MI) {
   MI.getOperand(2).setReg(LHSReg);
   Observer.changedInstr(MI);
 }
+
+// Transform build_vector of binop(_,C) -> binop(BV, constant BV).
+bool CombinerHelper::matchBuildVectorToBinOp(MachineInstr &MI,
+                                             BuildFnTy &MatchInfo) {
+  GBuildVector *BuildVector = cast<GBuildVector>(&MI);
+  Register Dst = BuildVector->getReg(0);
+
+  unsigned NumOfSources = BuildVector->getNumSources();
+  if (NumOfSources == 1)
+    return false;
+
+  LLT ElementTy = MRI.getType(BuildVector->getSourceReg(0));
+  LLT BVTy = MRI.getType(BuildVector->getReg(0));
+
+  MachineInstr *FirstDef = MRI.getVRegDef(BuildVector->getSourceReg(0));
+  const unsigned Opcode = FirstDef->getOpcode();
+  SmallVector<Register> LHS;
+
+  if (isa<GIntBinOp>(FirstDef)) {
+    SmallVector<APInt> RHS;
+
+    // Collect registers and constants and check for non-conformance.
+    for (unsigned I = 0; I < NumOfSources; ++I) {
+      // Check for integer binop of the same kind.
+      GIntBinOp *BinOp =
+          getOpcodeDef<GIntBinOp>(BuildVector->getSourceReg(I), MRI);
+      if (!BinOp || BinOp->getOpcode() != Opcode)
+        return false;
+      // Check for constant on rhs.
+      auto IConstant =
+          getIConstantVRegValWithLookThrough(BinOp->getRHSReg(), MRI);
+      if (!IConstant)
+        return false;
+      LHS.push_back(BinOp->getLHSReg());
+      RHS.push_back(IConstant->Value);
+    }
+
+    if (!isLegalOrBeforeLegalizer({Opcode, {BVTy, ElementTy}}))
+      return false;
+
+    // Binop of build_vector, integer constant build_vector.
+    MatchInfo = [=](MachineIRBuilder &B) {
+      B.setInstrAndDebugLoc(*BuildVector);
+      Register First = MRI.createGenericVirtualRegister(BVTy);
+      Register Second = MRI.createGenericVirtualRegister(BVTy);
+      B.buildBuildVector(First, LHS);
+      B.buildBuildVectorConstant(Second, RHS);
+      B.buildInstr(Opcode, {Dst}, {First, Second});
+    };
+    return true;
+  } else if (isa<GFBinOp>(FirstDef)) {
----------------
tschuett wrote:

I unfortunately have to distinguish  between integers and floats. This else checks it is a float binop. There is a return at the bottom of the function for non-binops. 

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


More information about the llvm-commits mailing list