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

David Green via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 11 01:19:04 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();
----------------
davemgreen wrote:

Can you remove these erase's from the extends. They might have other uses, which would then cause this to crash later on. It might be good to have a test for that too, where the extends have multiple uses.

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


More information about the llvm-commits mailing list