[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