[llvm] [AArch64][GlobalISel] Select UMULL instruction (PR #65469)

Amara Emerson via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 7 01:30:09 PDT 2023


================
@@ -1023,11 +1022,73 @@ bool AArch64LegalizerInfo::legalizeCustom(LegalizerHelper &Helper,
     return legalizeFCopySign(MI, Helper);
   case TargetOpcode::G_EXTRACT_VECTOR_ELT:
     return legalizeExtractVectorElt(MI, MRI, Helper);
+  case TargetOpcode::G_MUL:
+    return legalizeMULL(MI, MRI, MIRBuilder, Helper);
   }
 
   llvm_unreachable("expected switch to return");
 }
 
+bool AArch64LegalizerInfo::legalizeMULL(MachineInstr &MI,
+                                        MachineRegisterInfo &MRI,
+                                        MachineIRBuilder &MIRBuilder,
+                                        LegalizerHelper &Helper) const {
+  // Get the instruction that defined the source operand
+  LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
+  MachineInstr *I1 = getDefIgnoringCopies(MI.getOperand(1).getReg(), MRI);
+  MachineInstr *I2 = getDefIgnoringCopies(MI.getOperand(2).getReg(), MRI);
+
+  // If the source operands were EXTENDED before, then UMULL can be used
+  unsigned I1Opcode = I1->getOpcode();
+  unsigned I2Opcode = I2->getOpcode();
+  if (((I1Opcode == TargetOpcode::G_ZEXT && I2Opcode == TargetOpcode::G_ZEXT) ||
+       (I1Opcode == TargetOpcode::G_SEXT &&
+        I2Opcode == TargetOpcode::G_SEXT)) &&
+      (MRI.getType(I1->getOperand(0).getReg()).getScalarSizeInBits() ==
+       MRI.getType(I1->getOperand(1).getReg()).getScalarSizeInBits() * 2) &&
+      (MRI.getType(I2->getOperand(0).getReg()).getScalarSizeInBits() ==
+       MRI.getType(I2->getOperand(1).getReg()).getScalarSizeInBits() * 2)) {
+    // {S/U}MULL{2} of the source of the extend
+    MIRBuilder.buildInstr(
+        I1Opcode == TargetOpcode::G_ZEXT ? AArch64::G_UMULL : AArch64::G_SMULL,
+        {MI.getOperand(0).getReg()},
+        {I1->getOperand(1).getReg(), I2->getOperand(1).getReg()});
+    I1->eraseFromParent();
+    I2->eraseFromParent();
+    MI.eraseFromParent();
+  }
+  // When the destination type is v2s64, scalarize the instruction
+  // Used to be handled in getActionDefinitionsBuilder
+  else if (DstTy.getNumElements() == 2 && DstTy.getScalarSizeInBits() == 64) {
----------------
aemerson wrote:

For brevity you can just do `DstTy == LLT::fixed_vector(2, 64)`, LLT constructors are all constexpr.

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


More information about the llvm-commits mailing list