| //===- 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 |