blob: 292281a09a5fa6505c5ccf27e23af3f766bcf2c6 [file] [log] [blame]
//===- PatternMatchTest.cpp -----------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "LegalizerHelperTest.h"
namespace {
// Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,
// in which case it becomes CTTZ_ZERO_UNDEF with select.
TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ0) {
if (!TM)
return;
// Declare your legalization info
DefineLegalizerInfo(
A, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({s64}); });
// Build Instr
auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]);
AInfo Info(MF->getSubtarget());
LegalizerHelper Helper(*MF, Info);
// Perform Legalization
ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF %0
CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
)";
// Check
ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
}
// CTTZ expansion in terms of CTLZ
TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ1) {
if (!TM)
return;
// Declare your legalization info
DefineLegalizerInfo(A,
{ getActionDefinitionsBuilder(G_CTLZ).legalFor({s64}); });
// Build Instr
auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]);
AInfo Info(MF->getSubtarget());
LegalizerHelper Helper(*MF, Info);
// Perform Legalization
ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_
CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_
)";
// Check
ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
}
// CTTZ expansion in terms of CTPOP
TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ2) {
if (!TM)
return;
// Declare your legalization info
DefineLegalizerInfo(
A, { getActionDefinitionsBuilder(G_CTPOP).legalFor({s64}); });
// Build
auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]);
AInfo Info(MF->getSubtarget());
LegalizerHelper Helper(*MF, Info);
ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]]
)";
// Check
ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
}
// CTTZ_ZERO_UNDEF expansion in terms of CTTZ
TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ3) {
if (!TM)
return;
// Declare your legalization info
DefineLegalizerInfo(A,
{ getActionDefinitionsBuilder(G_CTTZ).legalFor({s64}); });
// Build
auto MIBCTTZ =
B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, LLT::scalar(64), Copies[0]);
AInfo Info(MF->getSubtarget());
LegalizerHelper Helper(*MF, Info);
ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
CHECK: CTTZ
)";
// Check
ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
}
// CTLZ expansion in terms of CTLZ_ZERO_UNDEF
TEST_F(LegalizerHelperTest, LowerBitCountingCTLZ0) {
if (!TM)
return;
// Declare your legalization info
DefineLegalizerInfo(
A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({s64}); });
// Build
auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, LLT::scalar(64), Copies[0]);
AInfo Info(MF->getSubtarget());
LegalizerHelper Helper(*MF, Info);
ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0
CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
)";
// Check
ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
}
// CTLZ expansion
TEST_F(LegalizerHelperTest, LowerBitCountingCTLZ1) {
if (!TM)
return;
// Declare your legalization info
DefineLegalizerInfo(A,
{ getActionDefinitionsBuilder(G_CTPOP).legalFor({s8}); });
// Build
// Trunc it to s8.
LLT s8{LLT::scalar(8)};
auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, s8, MIBTrunc);
AInfo Info(MF->getSubtarget());
LegalizerHelper Helper(*MF, Info);
ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_
CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_
CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2
CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_
CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_
CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4
CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_
CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_
CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_
CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_
)";
// Check
ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
}
} // namespace