mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
GlobalISel: Fix round lowering
I used the implementation for floor instead of round. It also turns out the OpenCL builtin library wasn't using the round builtin, but implemented the expanded form.
This commit is contained in:
parent
96d6178694
commit
29f6af5a39
@ -275,6 +275,7 @@ public:
|
||||
LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI);
|
||||
LegalizeResult lowerFMad(MachineInstr &MI);
|
||||
LegalizeResult lowerIntrinsicRound(MachineInstr &MI);
|
||||
LegalizeResult lowerFFloor(MachineInstr &MI);
|
||||
LegalizeResult lowerUnmergeValues(MachineInstr &MI);
|
||||
LegalizeResult lowerShuffleVector(MachineInstr &MI);
|
||||
LegalizeResult lowerDynStackAlloc(MachineInstr &MI);
|
||||
|
@ -2194,6 +2194,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
|
||||
}
|
||||
case TargetOpcode::G_FMAD:
|
||||
return lowerFMad(MI);
|
||||
case TargetOpcode::G_FFLOOR:
|
||||
return lowerFFloor(MI);
|
||||
case TargetOpcode::G_INTRINSIC_ROUND:
|
||||
return lowerIntrinsicRound(MI);
|
||||
case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: {
|
||||
@ -4646,6 +4648,39 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerFMad(MachineInstr &MI) {
|
||||
|
||||
LegalizerHelper::LegalizeResult
|
||||
LegalizerHelper::lowerIntrinsicRound(MachineInstr &MI) {
|
||||
Register DstReg = MI.getOperand(0).getReg();
|
||||
Register X = MI.getOperand(1).getReg();
|
||||
const unsigned Flags = MI.getFlags();
|
||||
const LLT Ty = MRI.getType(DstReg);
|
||||
const LLT CondTy = Ty.changeElementSize(1);
|
||||
|
||||
// round(x) =>
|
||||
// t = trunc(x);
|
||||
// d = fabs(x - t);
|
||||
// o = copysign(1.0f, x);
|
||||
// return t + (d >= 0.5 ? o : 0.0);
|
||||
|
||||
auto T = MIRBuilder.buildIntrinsicTrunc(Ty, X, Flags);
|
||||
|
||||
auto Diff = MIRBuilder.buildFSub(Ty, X, T, Flags);
|
||||
auto AbsDiff = MIRBuilder.buildFAbs(Ty, Diff, Flags);
|
||||
auto Zero = MIRBuilder.buildFConstant(Ty, 0.0);
|
||||
auto One = MIRBuilder.buildFConstant(Ty, 1.0);
|
||||
auto Half = MIRBuilder.buildFConstant(Ty, 0.5);
|
||||
auto SignOne = MIRBuilder.buildFCopysign(Ty, One, X);
|
||||
|
||||
auto Cmp = MIRBuilder.buildFCmp(CmpInst::FCMP_OGE, CondTy, AbsDiff, Half,
|
||||
Flags);
|
||||
auto Sel = MIRBuilder.buildSelect(Ty, Cmp, SignOne, Zero, Flags);
|
||||
|
||||
MIRBuilder.buildFAdd(DstReg, T, Sel, Flags);
|
||||
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
}
|
||||
|
||||
LegalizerHelper::LegalizeResult
|
||||
LegalizerHelper::lowerFFloor(MachineInstr &MI) {
|
||||
Register DstReg = MI.getOperand(0).getReg();
|
||||
Register SrcReg = MI.getOperand(1).getReg();
|
||||
unsigned Flags = MI.getFlags();
|
||||
@ -4656,8 +4691,8 @@ LegalizerHelper::lowerIntrinsicRound(MachineInstr &MI) {
|
||||
// if (src < 0.0 && src != result)
|
||||
// result += -1.0.
|
||||
|
||||
auto Zero = MIRBuilder.buildFConstant(Ty, 0.0);
|
||||
auto Trunc = MIRBuilder.buildIntrinsicTrunc(Ty, SrcReg, Flags);
|
||||
auto Zero = MIRBuilder.buildFConstant(Ty, 0.0);
|
||||
|
||||
auto Lt0 = MIRBuilder.buildFCmp(CmpInst::FCMP_OLT, CondTy,
|
||||
SrcReg, Zero, Flags);
|
||||
@ -4666,7 +4701,7 @@ LegalizerHelper::lowerIntrinsicRound(MachineInstr &MI) {
|
||||
auto And = MIRBuilder.buildAnd(CondTy, Lt0, NeTrunc);
|
||||
auto AddVal = MIRBuilder.buildSITOFP(Ty, And);
|
||||
|
||||
MIRBuilder.buildFAdd(DstReg, Trunc, AddVal);
|
||||
MIRBuilder.buildFAdd(DstReg, Trunc, AddVal, Flags);
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2441,4 +2441,36 @@ TEST_F(GISelMITest, LowerInsert) {
|
||||
// Check
|
||||
EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
|
||||
}
|
||||
|
||||
// Test lowering of G_FFLOOR
|
||||
TEST_F(GISelMITest, LowerFFloor) {
|
||||
setUp();
|
||||
if (!TM)
|
||||
return;
|
||||
|
||||
// Declare your legalization info
|
||||
DefineLegalizerInfo(A, {});
|
||||
// Build Instr
|
||||
auto Floor = B.buildFFloor(LLT::scalar(64), Copies[0], MachineInstr::MIFlag::FmNoInfs);
|
||||
AInfo Info(MF->getSubtarget());
|
||||
DummyGISelObserver Observer;
|
||||
LegalizerHelper Helper(*MF, Info, Observer, B);
|
||||
// Perform Legalization
|
||||
EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
|
||||
Helper.lower(*Floor, 0, LLT()));
|
||||
|
||||
auto CheckStr = R"(
|
||||
CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
|
||||
CHECK: [[TRUNC:%[0-9]+]]:_(s64) = ninf G_INTRINSIC_TRUNC [[COPY]]
|
||||
CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_FCONSTANT double 0.000000e+00
|
||||
CHECK: [[CMP0:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(olt), [[COPY]]:_(s64), [[ZERO]]:_
|
||||
CHECK: [[CMP1:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(one), [[COPY]]:_(s64), [[TRUNC]]:_
|
||||
CHECK: [[AND:%[0-9]+]]:_(s1) = G_AND [[CMP0]]:_, [[CMP1]]:_
|
||||
CHECK: [[ITOFP:%[0-9]+]]:_(s64) = G_SITOFP [[AND]]
|
||||
= ninf G_FADD [[TRUNC]]:_, [[ITOFP]]:_
|
||||
)";
|
||||
|
||||
// Check
|
||||
EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
|
||||
}
|
||||
} // namespace
|
||||
|
Loading…
Reference in New Issue
Block a user