[llvm] [X86][GlobalISel] Enable scalar versions of G_UITOFP and G_FPTOUI (PR #100079)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 16 05:27:24 PDT 2024
================
@@ -7108,6 +7108,77 @@ LegalizerHelper::lowerU64ToF32BitOps(MachineInstr &MI) {
return Legalized;
}
+// Expand s32 = G_UITOFP s64 to an IEEE float representation using bit
+// operations and G_SITOFP
+LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerU64ToF32WithSITOFP(MachineInstr &MI) {
+ auto [Dst, Src] = MI.getFirst2Regs();
+ const LLT S64 = LLT::scalar(64);
+ const LLT S32 = LLT::scalar(32);
+ const LLT S1 = LLT::scalar(1);
+
+ assert(MRI.getType(Src) == S64 && MRI.getType(Dst) == S32);
+
+ // For i64 < INT_MAX we simply reuse SITOFP.
+ // Otherwise, divide i64 by 2, round result by ORing with the lowest bit
+ // saved before division, convert to float by SITOFP, multiply the result
+ // by 2.
+ auto One = MIRBuilder.buildConstant(S64, 1);
+ auto Zero = MIRBuilder.buildConstant(S64, 0);
+ // Result if Src < INT_MAX
+ auto SmallResult = MIRBuilder.buildSITOFP(S32, Src);
+ // Result if Src >= INT_MAX
+ auto Halved = MIRBuilder.buildLShr(S64, Src, One);
+ auto LowerBit = MIRBuilder.buildAnd(S64, Src, One);
+ auto RoundedHalved = MIRBuilder.buildOr(S64, Halved, LowerBit);
+ auto HalvedFP = MIRBuilder.buildSITOFP(S32, RoundedHalved);
+ auto LargeResult = MIRBuilder.buildFAdd(S32, HalvedFP, HalvedFP);
+ // Choose
+ auto IsLarge =
+ MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_SLT, S1, Src, Zero);
----------------
arsenm wrote:
IsLarge = slt x, 0?
https://github.com/llvm/llvm-project/pull/100079
More information about the llvm-commits
mailing list