1 //===- llvm/unittest/CodeGen/GlobalISel/LegalizerInfoTest.cpp -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 11 #include "llvm/Target/TargetOpcodes.h" 12 #include "gtest/gtest.h" 13 14 using namespace llvm; 15 16 // Define a couple of pretty printers to help debugging when things go wrong. 17 namespace llvm { 18 std::ostream & 19 operator<<(std::ostream &OS, const llvm::LegalizerInfo::LegalizeAction Act) { 20 switch (Act) { 21 case LegalizerInfo::Lower: OS << "Lower"; break; 22 case LegalizerInfo::Legal: OS << "Legal"; break; 23 case LegalizerInfo::NarrowScalar: OS << "NarrowScalar"; break; 24 case LegalizerInfo::WidenScalar: OS << "WidenScalar"; break; 25 case LegalizerInfo::FewerElements: OS << "FewerElements"; break; 26 case LegalizerInfo::MoreElements: OS << "MoreElements"; break; 27 case LegalizerInfo::Libcall: OS << "Libcall"; break; 28 case LegalizerInfo::Custom: OS << "Custom"; break; 29 case LegalizerInfo::Unsupported: OS << "Unsupported"; break; 30 case LegalizerInfo::NotFound: OS << "NotFound"; 31 } 32 return OS; 33 } 34 35 std::ostream & 36 operator<<(std::ostream &OS, const llvm::LLT Ty) { 37 std::string Repr; 38 raw_string_ostream SS{Repr}; 39 Ty.print(SS); 40 OS << SS.str(); 41 return OS; 42 } 43 } 44 45 namespace { 46 47 48 TEST(LegalizerInfoTest, ScalarRISC) { 49 using namespace TargetOpcode; 50 LegalizerInfo L; 51 // Typical RISCy set of operations based on AArch64. 52 L.setAction({G_ADD, LLT::scalar(8)}, LegalizerInfo::WidenScalar); 53 L.setAction({G_ADD, LLT::scalar(16)}, LegalizerInfo::WidenScalar); 54 L.setAction({G_ADD, LLT::scalar(32)}, LegalizerInfo::Legal); 55 L.setAction({G_ADD, LLT::scalar(64)}, LegalizerInfo::Legal); 56 L.computeTables(); 57 58 // Check we infer the correct types and actually do what we're told. 59 ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(8)}), 60 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32))); 61 ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(16)}), 62 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32))); 63 ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(32)}), 64 std::make_pair(LegalizerInfo::Legal, LLT::scalar(32))); 65 ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(64)}), 66 std::make_pair(LegalizerInfo::Legal, LLT::scalar(64))); 67 68 // Make sure the default for over-sized types applies. 69 ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(128)}), 70 std::make_pair(LegalizerInfo::NarrowScalar, LLT::scalar(64))); 71 } 72 73 TEST(LegalizerInfoTest, VectorRISC) { 74 using namespace TargetOpcode; 75 LegalizerInfo L; 76 // Typical RISCy set of operations based on ARM. 77 L.setScalarInVectorAction(G_ADD, LLT::scalar(8), LegalizerInfo::Legal); 78 L.setScalarInVectorAction(G_ADD, LLT::scalar(16), LegalizerInfo::Legal); 79 L.setScalarInVectorAction(G_ADD, LLT::scalar(32), LegalizerInfo::Legal); 80 81 L.setAction({G_ADD, LLT::vector(8, 8)}, LegalizerInfo::Legal); 82 L.setAction({G_ADD, LLT::vector(16, 8)}, LegalizerInfo::Legal); 83 L.setAction({G_ADD, LLT::vector(4, 16)}, LegalizerInfo::Legal); 84 L.setAction({G_ADD, LLT::vector(8, 16)}, LegalizerInfo::Legal); 85 L.setAction({G_ADD, LLT::vector(2, 32)}, LegalizerInfo::Legal); 86 L.setAction({G_ADD, LLT::vector(4, 32)}, LegalizerInfo::Legal); 87 L.computeTables(); 88 89 // Check we infer the correct types and actually do what we're told for some 90 // simple cases. 91 ASSERT_EQ(L.getAction({G_ADD, LLT::vector(2, 8)}), 92 std::make_pair(LegalizerInfo::MoreElements, LLT::vector(8, 8))); 93 ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 8)}), 94 std::make_pair(LegalizerInfo::Legal, LLT::vector(8, 8))); 95 ASSERT_EQ( 96 L.getAction({G_ADD, LLT::vector(8, 32)}), 97 std::make_pair(LegalizerInfo::FewerElements, LLT::vector(4, 32))); 98 } 99 100 TEST(LegalizerInfoTest, MultipleTypes) { 101 using namespace TargetOpcode; 102 LegalizerInfo L; 103 LLT p0 = LLT::pointer(0, 64); 104 LLT s32 = LLT::scalar(32); 105 LLT s64 = LLT::scalar(64); 106 107 // Typical RISCy set of operations based on AArch64. 108 L.setAction({G_PTRTOINT, 0, s64}, LegalizerInfo::Legal); 109 L.setAction({G_PTRTOINT, 1, p0}, LegalizerInfo::Legal); 110 111 L.setAction({G_PTRTOINT, 0, s32}, LegalizerInfo::WidenScalar); 112 L.computeTables(); 113 114 // Check we infer the correct types and actually do what we're told. 115 ASSERT_EQ(L.getAction({G_PTRTOINT, 0, s64}), 116 std::make_pair(LegalizerInfo::Legal, s64)); 117 ASSERT_EQ(L.getAction({G_PTRTOINT, 1, p0}), 118 std::make_pair(LegalizerInfo::Legal, p0)); 119 } 120 } 121