AArch64SelectionDAGTest.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. //===- llvm/unittest/CodeGen/AArch64SelectionDAGTest.cpp -------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/CodeGen/SelectionDAG.h"
  9. #include "llvm/Analysis/OptimizationRemarkEmitter.h"
  10. #include "llvm/AsmParser/Parser.h"
  11. #include "llvm/CodeGen/MachineModuleInfo.h"
  12. #include "llvm/CodeGen/TargetLowering.h"
  13. #include "llvm/Support/SourceMgr.h"
  14. #include "llvm/Support/TargetRegistry.h"
  15. #include "llvm/Support/TargetSelect.h"
  16. #include "llvm/Target/TargetMachine.h"
  17. #include "gtest/gtest.h"
  18. using namespace llvm;
  19. namespace {
  20. class AArch64SelectionDAGTest : public testing::Test {
  21. protected:
  22. static void SetUpTestCase() {
  23. InitializeAllTargets();
  24. InitializeAllTargetMCs();
  25. }
  26. void SetUp() override {
  27. StringRef Assembly = "define void @f() { ret void }";
  28. Triple TargetTriple("aarch64--");
  29. std::string Error;
  30. const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
  31. // FIXME: These tests do not depend on AArch64 specifically, but we have to
  32. // initialize a target. A skeleton Target for unittests would allow us to
  33. // always run these tests.
  34. if (!T)
  35. return;
  36. TargetOptions Options;
  37. TM = std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine*>(
  38. T->createTargetMachine("AArch64", "", "", Options, None, None,
  39. CodeGenOpt::Aggressive)));
  40. if (!TM)
  41. return;
  42. SMDiagnostic SMError;
  43. M = parseAssemblyString(Assembly, SMError, Context);
  44. if (!M)
  45. report_fatal_error(SMError.getMessage());
  46. M->setDataLayout(TM->createDataLayout());
  47. F = M->getFunction("f");
  48. if (!F)
  49. report_fatal_error("F?");
  50. MachineModuleInfo MMI(TM.get());
  51. MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F), 0,
  52. MMI);
  53. DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOpt::None);
  54. if (!DAG)
  55. report_fatal_error("DAG?");
  56. OptimizationRemarkEmitter ORE(F);
  57. DAG->init(*MF, ORE, nullptr, nullptr, nullptr);
  58. }
  59. LLVMContext Context;
  60. std::unique_ptr<LLVMTargetMachine> TM;
  61. std::unique_ptr<Module> M;
  62. Function *F;
  63. std::unique_ptr<MachineFunction> MF;
  64. std::unique_ptr<SelectionDAG> DAG;
  65. };
  66. TEST_F(AArch64SelectionDAGTest, computeKnownBits_ZERO_EXTEND_VECTOR_INREG) {
  67. if (!TM)
  68. return;
  69. SDLoc Loc;
  70. auto Int8VT = EVT::getIntegerVT(Context, 8);
  71. auto Int16VT = EVT::getIntegerVT(Context, 16);
  72. auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);
  73. auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);
  74. auto InVec = DAG->getConstant(0, Loc, InVecVT);
  75. auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
  76. auto DemandedElts = APInt(2, 3);
  77. KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
  78. EXPECT_TRUE(Known.isZero());
  79. }
  80. TEST_F(AArch64SelectionDAGTest, computeKnownBits_EXTRACT_SUBVECTOR) {
  81. if (!TM)
  82. return;
  83. SDLoc Loc;
  84. auto IntVT = EVT::getIntegerVT(Context, 8);
  85. auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
  86. auto IdxVT = EVT::getIntegerVT(Context, 64);
  87. auto Vec = DAG->getConstant(0, Loc, VecVT);
  88. auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
  89. auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
  90. auto DemandedElts = APInt(3, 7);
  91. KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
  92. EXPECT_TRUE(Known.isZero());
  93. }
  94. TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG) {
  95. if (!TM)
  96. return;
  97. SDLoc Loc;
  98. auto Int8VT = EVT::getIntegerVT(Context, 8);
  99. auto Int16VT = EVT::getIntegerVT(Context, 16);
  100. auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);
  101. auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);
  102. auto InVec = DAG->getConstant(1, Loc, InVecVT);
  103. auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
  104. auto DemandedElts = APInt(2, 3);
  105. EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 15u);
  106. }
  107. TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_EXTRACT_SUBVECTOR) {
  108. if (!TM)
  109. return;
  110. SDLoc Loc;
  111. auto IntVT = EVT::getIntegerVT(Context, 8);
  112. auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
  113. auto IdxVT = EVT::getIntegerVT(Context, 64);
  114. auto Vec = DAG->getConstant(1, Loc, VecVT);
  115. auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
  116. auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
  117. auto DemandedElts = APInt(3, 7);
  118. EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 7u);
  119. }
  120. TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) {
  121. if (!TM)
  122. return;
  123. TargetLowering TL(*TM);
  124. SDLoc Loc;
  125. auto IntVT = EVT::getIntegerVT(Context, 8);
  126. auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
  127. auto IdxVT = EVT::getIntegerVT(Context, 64);
  128. auto Vec = DAG->getConstant(1, Loc, VecVT);
  129. auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
  130. auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
  131. auto DemandedElts = APInt(3, 7);
  132. auto KnownUndef = APInt(3, 0);
  133. auto KnownZero = APInt(3, 0);
  134. TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
  135. EXPECT_EQ(TL.SimplifyDemandedVectorElts(Op, DemandedElts, KnownUndef,
  136. KnownZero, TLO),
  137. false);
  138. }
  139. // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
  140. TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {
  141. if (!TM)
  142. return;
  143. SDLoc Loc;
  144. auto IntVT = EVT::getIntegerVT(Context, 8);
  145. auto UnknownOp = DAG->getRegister(0, IntVT);
  146. auto Mask = DAG->getConstant(0x8A, Loc, IntVT);
  147. auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
  148. auto N1 = DAG->getConstant(0x55, Loc, IntVT);
  149. auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1);
  150. // N0 = ?000?0?0
  151. // N1 = 01010101
  152. // =>
  153. // Known.One = 01010101 (0x55)
  154. // Known.Zero = 00100000 (0x20)
  155. KnownBits Known = DAG->computeKnownBits(Op);
  156. EXPECT_EQ(Known.Zero, APInt(8, 0x20));
  157. EXPECT_EQ(Known.One, APInt(8, 0x55));
  158. }
  159. // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
  160. TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
  161. if (!TM)
  162. return;
  163. SDLoc Loc;
  164. auto IntVT = EVT::getIntegerVT(Context, 8);
  165. auto N0 = DAG->getConstant(0x55, Loc, IntVT);
  166. auto UnknownOp = DAG->getRegister(0, IntVT);
  167. auto Mask = DAG->getConstant(0x2e, Loc, IntVT);
  168. auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
  169. auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
  170. // N0 = 01010101
  171. // N1 = 00?0???0
  172. // =>
  173. // Known.One = 00000001 (0x1)
  174. // Known.Zero = 10000000 (0x80)
  175. KnownBits Known = DAG->computeKnownBits(Op);
  176. EXPECT_EQ(Known.Zero, APInt(8, 0x80));
  177. EXPECT_EQ(Known.One, APInt(8, 0x1));
  178. }
  179. } // end anonymous namespace