[llvm] [AArch64][GlobalISel] Improve lowering of vector fp16 fptrunc and fpext (PR #163398)

Cullen Rhodes via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 17 05:46:16 PDT 2025


================
@@ -901,6 +901,200 @@ unsigned getCmpOperandFoldingProfit(Register CmpOp, MachineRegisterInfo &MRI) {
   return 0;
 }
 
+// Helper function for matchFpTruncFpTrunc.
+// Checks that the given definition belongs to an FPTRUNC and that the source is
+// not an integer, as no rounding is necessary due to the range of values
+bool checkTruncSrc(MachineRegisterInfo &MRI, MachineInstr *MaybeFpTrunc) {
+  if (!MaybeFpTrunc || MaybeFpTrunc->getOpcode() != TargetOpcode::G_FPTRUNC)
+    return false;
+
+  // Check the source is 64 bits as we only want to match a very specific
+  // pattern
+  Register FpTruncSrc = MaybeFpTrunc->getOperand(1).getReg();
+  LLT SrcTy = MRI.getType(FpTruncSrc);
+  if (SrcTy.getScalarSizeInBits() != 64)
+    return false;
+
+  // Need to check the float didn't come from an int as no rounding is
+  // neccessary
+  MachineInstr *FpTruncSrcDef = getDefIgnoringCopies(FpTruncSrc, MRI);
+  if (FpTruncSrcDef->getOpcode() == TargetOpcode::G_SITOFP ||
+      FpTruncSrcDef->getOpcode() == TargetOpcode::G_UITOFP)
+    return false;
+
+  return true;
+}
+
+// To avoid double rounding issues we need to lower FPTRUNC(FPTRUNC) to an odd
+// rounding truncate and a normal truncate. When
+// truncating an FP that came from an integer this is not a problem as the range
+// of values is lower in the int
+bool matchFpTruncFpTrunc(MachineInstr &MI, MachineRegisterInfo &MRI) {
+  if (MI.getOpcode() != TargetOpcode::G_FPTRUNC)
+    return false;
+
+  // Check the destination is 16 bits as we only want to match a very specific
+  // pattern
+  Register Dst = MI.getOperand(0).getReg();
+  LLT DstTy = MRI.getType(Dst);
+  if (DstTy.getScalarSizeInBits() != 16)
+    return false;
+
+  Register Src = MI.getOperand(1).getReg();
+
+  MachineInstr *ParentDef = getDefIgnoringCopies(Src, MRI);
+  if (!ParentDef)
+    return false;
+
+  MachineInstr *FpTruncDef;
+  switch (ParentDef->getOpcode()) {
+  default:
+    return false;
+  case TargetOpcode::G_CONCAT_VECTORS: {
+    // Expecting exactly two FPTRUNCs
+    if (ParentDef->getNumOperands() != 3)
+      return false;
+
+    // All operands need to be FPTRUNC
+    for (unsigned OpIdx = 1, NumOperands = ParentDef->getNumOperands();
+         OpIdx != NumOperands; ++OpIdx) {
----------------
c-rhodes wrote:

ah ok, I didn't consider that 👍 

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


More information about the llvm-commits mailing list