[llvm] 76986bd - [GlobalISel] Legalize more G_FP(EXT|TRUNC) libcalls.
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 6 11:42:18 PST 2020
Author: Konstantin Schwarz
Date: 2020-02-06T11:41:34-08:00
New Revision: 76986bdc4633b0a8bdee1ad4f2e279f17e7f747a
URL: https://github.com/llvm/llvm-project/commit/76986bdc4633b0a8bdee1ad4f2e279f17e7f747a
DIFF: https://github.com/llvm/llvm-project/commit/76986bdc4633b0a8bdee1ad4f2e279f17e7f747a.diff
LOG: [GlobalISel] Legalize more G_FP(EXT|TRUNC) libcalls.
This adds a new helper function for retrieving the
floating point type corresponding to the specified
bit-width.
Added:
Modified:
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index ef1b74e8ad12..7b58df34ea7e 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -115,6 +115,25 @@ static LLT getLCMType(LLT Ty0, LLT Ty1) {
llvm_unreachable("not yet handled");
}
+static Type *getFloatTypeForLLT(LLVMContext &Ctx, LLT Ty) {
+
+ if (!Ty.isScalar())
+ return nullptr;
+
+ switch (Ty.getSizeInBits()) {
+ case 16:
+ return Type::getHalfTy(Ctx);
+ case 32:
+ return Type::getFloatTy(Ctx);
+ case 64:
+ return Type::getDoubleTy(Ctx);
+ case 128:
+ return Type::getFP128Ty(Ctx);
+ default:
+ return nullptr;
+ }
+}
+
LegalizerHelper::LegalizerHelper(MachineFunction &MF,
GISelChangeObserver &Observer,
MachineIRBuilder &Builder)
@@ -702,36 +721,23 @@ LegalizerHelper::libcall(MachineInstr &MI) {
case TargetOpcode::G_FEXP2:
case TargetOpcode::G_FCEIL:
case TargetOpcode::G_FFLOOR: {
- if (Size > 64) {
- LLVM_DEBUG(dbgs() << "Size " << Size << " too large to legalize.\n");
+ Type *HLTy = getFloatTypeForLLT(Ctx, LLTy);
+ if (!HLTy || (Size != 32 && Size != 64)) {
+ LLVM_DEBUG(dbgs() << "No libcall available for size " << Size << ".\n");
return UnableToLegalize;
}
- Type *HLTy = Size == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx);
auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy);
if (Status != Legalized)
return Status;
break;
}
- case TargetOpcode::G_FPEXT: {
- // FIXME: Support other floating point types (half, fp128 etc)
- unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
- unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
- if (ToSize != 64 || FromSize != 32)
- return UnableToLegalize;
- LegalizeResult Status = conversionLibcall(
- MI, MIRBuilder, Type::getDoubleTy(Ctx), Type::getFloatTy(Ctx));
- if (Status != Legalized)
- return Status;
- break;
- }
+ case TargetOpcode::G_FPEXT:
case TargetOpcode::G_FPTRUNC: {
- // FIXME: Support other floating point types (half, fp128 etc)
- unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
- unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
- if (ToSize != 32 || FromSize != 64)
+ Type *FromTy = getFloatTypeForLLT(Ctx, MRI.getType(MI.getOperand(1).getReg()));
+ Type *ToTy = getFloatTypeForLLT(Ctx, MRI.getType(MI.getOperand(0).getReg()));
+ if (!FromTy || !ToTy)
return UnableToLegalize;
- LegalizeResult Status = conversionLibcall(
- MI, MIRBuilder, Type::getFloatTy(Ctx), Type::getDoubleTy(Ctx));
+ LegalizeResult Status = conversionLibcall(MI, MIRBuilder, ToTy, FromTy );
if (Status != Legalized)
return Status;
break;
@@ -2222,24 +2228,10 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
if (Ty.isVector())
return UnableToLegalize;
Register Res = MI.getOperand(0).getReg();
- Type *ZeroTy;
LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
- switch (Ty.getSizeInBits()) {
- case 16:
- ZeroTy = Type::getHalfTy(Ctx);
- break;
- case 32:
- ZeroTy = Type::getFloatTy(Ctx);
- break;
- case 64:
- ZeroTy = Type::getDoubleTy(Ctx);
- break;
- case 128:
- ZeroTy = Type::getFP128Ty(Ctx);
- break;
- default:
- llvm_unreachable("unexpected floating-point type");
- }
+ Type *ZeroTy = getFloatTypeForLLT(Ctx, Ty);
+ if (!ZeroTy)
+ return UnableToLegalize;
ConstantFP &ZeroForNegation =
*cast<ConstantFP>(ConstantFP::getZeroValueForNegation(ZeroTy));
auto Zero = MIRBuilder.buildFConstant(Ty, ZeroForNegation);
diff --git a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
index e89a8106b0f6..4254f4f759e4 100644
--- a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
+++ b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
@@ -176,6 +176,8 @@ class GISelMITest : public ::testing::Test {
(void)s32; \
const LLT s64 = LLT::scalar(64); \
(void)s64; \
+ const LLT s128 = LLT::scalar(128); \
+ (void)s128; \
do \
SettingUpActionsBlock while (0); \
computeTables(); \
diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
index 4d3492fe99ef..5dfe741a6ddb 100644
--- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
@@ -1179,4 +1179,108 @@ TEST_F(GISelMITest, LowerSEXTINREG) {
// Check
ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
}
+
+TEST_F(GISelMITest, LibcallFPExt) {
+ setUp();
+ if (!TM)
+ return;
+
+ // Declare your legalization info
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_FPEXT).libcallFor({{s32, s16}, {s128, s64}});
+ });
+
+ LLT S16{LLT::scalar(16)};
+ LLT S32{LLT::scalar(32)};
+ LLT S128{LLT::scalar(128)};
+ auto MIBTrunc = B.buildTrunc(S16, Copies[0]);
+ auto MIBFPExt1 =
+ B.buildInstr(TargetOpcode::G_FPEXT, {S32}, {MIBTrunc});
+
+ auto MIBFPExt2 =
+ B.buildInstr(TargetOpcode::G_FPEXT, {S128}, {Copies[1]});
+ AInfo Info(MF->getSubtarget());
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, Info, Observer, B);
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.libcall(*MIBFPExt1));
+
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.libcall(*MIBFPExt2));
+ auto CheckStr = R"(
+ CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC
+ CHECK: $h0 = COPY [[TRUNC]]
+ CHECK: BL &__gnu_h2f_ieee
+ CHECK: $d0 = COPY
+ CHECK: BL &__extenddftf2
+ )";
+
+ // Check
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, LibcallFPTrunc) {
+ setUp();
+ if (!TM)
+ return;
+
+ // Declare your legalization info
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_FPTRUNC).libcallFor({{s16, s32}, {s64, s128}});
+ });
+
+ LLT S16{LLT::scalar(16)};
+ LLT S32{LLT::scalar(32)};
+ LLT S64{LLT::scalar(64)};
+ LLT S128{LLT::scalar(128)};
+ auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
+ auto MIBFPTrunc1 =
+ B.buildInstr(TargetOpcode::G_FPTRUNC, {S16}, {MIBTrunc});
+
+ auto MIBMerge = B.buildMerge(S128, {Copies[1], Copies[2]});
+
+ auto MIBFPTrunc2 =
+ B.buildInstr(TargetOpcode::G_FPTRUNC, {S64}, {MIBMerge});
+ AInfo Info(MF->getSubtarget());
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, Info, Observer, B);
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.libcall(*MIBFPTrunc1));
+
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.libcall(*MIBFPTrunc2));
+ auto CheckStr = R"(
+ CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
+ CHECK: $s0 = COPY [[TRUNC]]
+ CHECK: BL &__gnu_f2h_ieee
+ CHECK: $q0 = COPY
+ CHECK: BL &__trunctfdf2
+ )";
+
+ // Check
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, LibcallSimple) {
+ setUp();
+ if (!TM)
+ return;
+
+ // Declare your legalization info
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_FADD).libcallFor({s16});
+ });
+
+ LLT S16{LLT::scalar(16)};
+ auto MIBTrunc = B.buildTrunc(S16, Copies[0]);
+ auto MIBFADD =
+ B.buildInstr(TargetOpcode::G_FADD, {S16}, {MIBTrunc, MIBTrunc});
+
+ AInfo Info(MF->getSubtarget());
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, Info, Observer, B);
+ // Make sure we do not crash anymore
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
+ Helper.libcall(*MIBFADD));
+}
} // namespace
More information about the llvm-commits
mailing list