[AArch64][GlobalISel] Legalize 128-bit types for FABS (#104753)
This patch adds a common lower action for `G_FABS`, which generates `and
x8, x8, #0x7fffffffffffffff` to reset the sign bit. The action does not
support vectors since `G_AND` does not support fp128.
This approach is different than what SDAG is doing. SDAG stores the
value onto stack, clears the sign bit in the most significant byte, and
loads the value back into register. This involves multiple memory ops
and sounds slower.
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index f818c4e..3640b77 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -4255,6 +4255,8 @@
return lowerShlSat(MI);
case G_ABS:
return lowerAbsToAddXor(MI);
+ case G_FABS:
+ return lowerFAbs(MI);
case G_SELECT:
return lowerSelect(MI);
case G_IS_FPCLASS:
@@ -8761,6 +8763,22 @@
return Legalized;
}
+LegalizerHelper::LegalizeResult LegalizerHelper::lowerFAbs(MachineInstr &MI) {
+ Register SrcReg = MI.getOperand(1).getReg();
+ Register DstReg = MI.getOperand(0).getReg();
+
+ LLT Ty = MRI.getType(DstReg);
+
+ // Reset sign bit
+ MIRBuilder.buildAnd(
+ DstReg, SrcReg,
+ MIRBuilder.buildConstant(
+ Ty, APInt::getSignedMaxValue(Ty.getScalarSizeInBits())));
+
+ MI.eraseFromParent();
+ return Legalized;
+}
+
LegalizerHelper::LegalizeResult
LegalizerHelper::lowerVectorReduction(MachineInstr &MI) {
Register SrcReg = MI.getOperand(1).getReg();