1 //===---- llvm/unittest/CodeGen/SelectionDAGPatternMatchTest.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 9 #include "llvm/Analysis/OptimizationRemarkEmitter.h" 10 #include "llvm/AsmParser/Parser.h" 11 #include "llvm/CodeGen/MachineModuleInfo.h" 12 #include "llvm/CodeGen/SDPatternMatch.h" 13 #include "llvm/CodeGen/TargetLowering.h" 14 #include "llvm/IR/Module.h" 15 #include "llvm/MC/TargetRegistry.h" 16 #include "llvm/Support/SourceMgr.h" 17 #include "llvm/Support/TargetSelect.h" 18 #include "llvm/Target/TargetMachine.h" 19 #include "gtest/gtest.h" 20 21 using namespace llvm; 22 23 class SelectionDAGPatternMatchTest : public testing::Test { 24 protected: 25 static void SetUpTestCase() { 26 InitializeAllTargets(); 27 InitializeAllTargetMCs(); 28 } 29 30 void SetUp() override { 31 StringRef Assembly = "@g = global i32 0\n" 32 "@g_alias = alias i32, i32* @g\n" 33 "define i32 @f() {\n" 34 " %1 = load i32, i32* @g\n" 35 " ret i32 %1\n" 36 "}"; 37 38 Triple TargetTriple("riscv64--"); 39 std::string Error; 40 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); 41 // FIXME: These tests do not depend on RISCV specifically, but we have to 42 // initialize a target. A skeleton Target for unittests would allow us to 43 // always run these tests. 44 if (!T) 45 GTEST_SKIP(); 46 47 TargetOptions Options; 48 TM = std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>( 49 T->createTargetMachine("riscv64", "", "+m,+f,+d,+v", Options, 50 std::nullopt, std::nullopt, 51 CodeGenOptLevel::Aggressive))); 52 if (!TM) 53 GTEST_SKIP(); 54 55 SMDiagnostic SMError; 56 M = parseAssemblyString(Assembly, SMError, Context); 57 if (!M) 58 report_fatal_error(SMError.getMessage()); 59 M->setDataLayout(TM->createDataLayout()); 60 61 F = M->getFunction("f"); 62 if (!F) 63 report_fatal_error("F?"); 64 G = M->getGlobalVariable("g"); 65 if (!G) 66 report_fatal_error("G?"); 67 AliasedG = M->getNamedAlias("g_alias"); 68 if (!AliasedG) 69 report_fatal_error("AliasedG?"); 70 71 MachineModuleInfo MMI(TM.get()); 72 73 MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F), 74 0, MMI); 75 76 DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None); 77 if (!DAG) 78 report_fatal_error("DAG?"); 79 OptimizationRemarkEmitter ORE(F); 80 DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); 81 } 82 83 TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) { 84 return DAG->getTargetLoweringInfo().getTypeAction(Context, VT); 85 } 86 87 EVT getTypeToTransformTo(EVT VT) { 88 return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT); 89 } 90 91 LLVMContext Context; 92 std::unique_ptr<LLVMTargetMachine> TM; 93 std::unique_ptr<Module> M; 94 Function *F; 95 GlobalVariable *G; 96 GlobalAlias *AliasedG; 97 std::unique_ptr<MachineFunction> MF; 98 std::unique_ptr<SelectionDAG> DAG; 99 }; 100 101 TEST_F(SelectionDAGPatternMatchTest, matchValueType) { 102 SDLoc DL; 103 auto Int32VT = EVT::getIntegerVT(Context, 32); 104 auto Float32VT = EVT::getFloatingPointVT(32); 105 auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4); 106 107 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT); 108 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Float32VT); 109 SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT); 110 111 using namespace SDPatternMatch; 112 EXPECT_TRUE(sd_match(Op0, m_SpecificVT(Int32VT))); 113 EVT BindVT; 114 EXPECT_TRUE(sd_match(Op1, m_VT(BindVT))); 115 EXPECT_EQ(BindVT, Float32VT); 116 EXPECT_TRUE(sd_match(Op0, m_IntegerVT())); 117 EXPECT_TRUE(sd_match(Op1, m_FloatingPointVT())); 118 EXPECT_TRUE(sd_match(Op2, m_VectorVT())); 119 EXPECT_FALSE(sd_match(Op2, m_ScalableVectorVT())); 120 } 121 122 TEST_F(SelectionDAGPatternMatchTest, matchTernaryOp) { 123 SDLoc DL; 124 auto Int32VT = EVT::getIntegerVT(Context, 32); 125 126 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT); 127 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT); 128 129 SDValue ICMP_UGT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGT); 130 SDValue ICMP_EQ01 = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETEQ); 131 SDValue ICMP_EQ10 = DAG->getSetCC(DL, MVT::i1, Op1, Op0, ISD::SETEQ); 132 133 using namespace SDPatternMatch; 134 ISD::CondCode CC; 135 EXPECT_TRUE(sd_match(ICMP_UGT, m_SetCC(m_Value(), m_Value(), 136 m_SpecificCondCode(ISD::SETUGT)))); 137 EXPECT_TRUE( 138 sd_match(ICMP_UGT, m_SetCC(m_Value(), m_Value(), m_CondCode(CC)))); 139 EXPECT_TRUE(CC == ISD::SETUGT); 140 EXPECT_FALSE(sd_match( 141 ICMP_UGT, m_SetCC(m_Value(), m_Value(), m_SpecificCondCode(ISD::SETLE)))); 142 143 EXPECT_TRUE(sd_match(ICMP_EQ01, m_SetCC(m_Specific(Op0), m_Specific(Op1), 144 m_SpecificCondCode(ISD::SETEQ)))); 145 EXPECT_TRUE(sd_match(ICMP_EQ10, m_SetCC(m_Specific(Op1), m_Specific(Op0), 146 m_SpecificCondCode(ISD::SETEQ)))); 147 EXPECT_FALSE(sd_match(ICMP_EQ01, m_SetCC(m_Specific(Op1), m_Specific(Op0), 148 m_SpecificCondCode(ISD::SETEQ)))); 149 EXPECT_FALSE(sd_match(ICMP_EQ10, m_SetCC(m_Specific(Op0), m_Specific(Op1), 150 m_SpecificCondCode(ISD::SETEQ)))); 151 EXPECT_TRUE(sd_match(ICMP_EQ01, m_c_SetCC(m_Specific(Op1), m_Specific(Op0), 152 m_SpecificCondCode(ISD::SETEQ)))); 153 EXPECT_TRUE(sd_match(ICMP_EQ10, m_c_SetCC(m_Specific(Op0), m_Specific(Op1), 154 m_SpecificCondCode(ISD::SETEQ)))); 155 } 156 157 TEST_F(SelectionDAGPatternMatchTest, matchBinaryOp) { 158 SDLoc DL; 159 auto Int32VT = EVT::getIntegerVT(Context, 32); 160 auto Float32VT = EVT::getFloatingPointVT(32); 161 162 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT); 163 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT); 164 SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Float32VT); 165 166 SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1); 167 SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Add, Op0); 168 SDValue Mul = DAG->getNode(ISD::MUL, DL, Int32VT, Add, Sub); 169 SDValue And = DAG->getNode(ISD::AND, DL, Int32VT, Op0, Op1); 170 SDValue Xor = DAG->getNode(ISD::XOR, DL, Int32VT, Op1, Op0); 171 SDValue Or = DAG->getNode(ISD::OR, DL, Int32VT, Op0, Op1); 172 SDValue SMax = DAG->getNode(ISD::SMAX, DL, Int32VT, Op0, Op1); 173 SDValue SMin = DAG->getNode(ISD::SMIN, DL, Int32VT, Op1, Op0); 174 SDValue UMax = DAG->getNode(ISD::UMAX, DL, Int32VT, Op0, Op1); 175 SDValue UMin = DAG->getNode(ISD::UMIN, DL, Int32VT, Op1, Op0); 176 177 SDValue SFAdd = DAG->getNode(ISD::STRICT_FADD, DL, {Float32VT, MVT::Other}, 178 {DAG->getEntryNode(), Op2, Op2}); 179 180 using namespace SDPatternMatch; 181 EXPECT_TRUE(sd_match(Sub, m_BinOp(ISD::SUB, m_Value(), m_Value()))); 182 EXPECT_TRUE(sd_match(Sub, m_Sub(m_Value(), m_Value()))); 183 EXPECT_TRUE(sd_match(Add, m_c_BinOp(ISD::ADD, m_Value(), m_Value()))); 184 EXPECT_TRUE(sd_match(Add, m_Add(m_Value(), m_Value()))); 185 EXPECT_TRUE(sd_match( 186 Mul, m_Mul(m_OneUse(m_Opc(ISD::SUB)), m_NUses<2>(m_Specific(Add))))); 187 EXPECT_TRUE( 188 sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_SpecificVT(Float32VT), 189 m_SpecificVT(Float32VT)))); 190 191 EXPECT_TRUE(sd_match(And, m_c_BinOp(ISD::AND, m_Value(), m_Value()))); 192 EXPECT_TRUE(sd_match(And, m_And(m_Value(), m_Value()))); 193 EXPECT_TRUE(sd_match(Xor, m_c_BinOp(ISD::XOR, m_Value(), m_Value()))); 194 EXPECT_TRUE(sd_match(Xor, m_Xor(m_Value(), m_Value()))); 195 EXPECT_TRUE(sd_match(Or, m_c_BinOp(ISD::OR, m_Value(), m_Value()))); 196 EXPECT_TRUE(sd_match(Or, m_Or(m_Value(), m_Value()))); 197 198 EXPECT_TRUE(sd_match(SMax, m_c_BinOp(ISD::SMAX, m_Value(), m_Value()))); 199 EXPECT_TRUE(sd_match(SMax, m_SMax(m_Value(), m_Value()))); 200 EXPECT_TRUE(sd_match(SMin, m_c_BinOp(ISD::SMIN, m_Value(), m_Value()))); 201 EXPECT_TRUE(sd_match(SMin, m_SMin(m_Value(), m_Value()))); 202 EXPECT_TRUE(sd_match(UMax, m_c_BinOp(ISD::UMAX, m_Value(), m_Value()))); 203 EXPECT_TRUE(sd_match(UMax, m_UMax(m_Value(), m_Value()))); 204 EXPECT_TRUE(sd_match(UMin, m_c_BinOp(ISD::UMIN, m_Value(), m_Value()))); 205 EXPECT_TRUE(sd_match(UMin, m_UMin(m_Value(), m_Value()))); 206 207 SDValue BindVal; 208 EXPECT_TRUE(sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_Value(BindVal), 209 m_Deferred(BindVal)))); 210 EXPECT_FALSE(sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_OtherVT(), 211 m_SpecificVT(Float32VT)))); 212 } 213 214 TEST_F(SelectionDAGPatternMatchTest, matchUnaryOp) { 215 SDLoc DL; 216 auto Int32VT = EVT::getIntegerVT(Context, 32); 217 auto Int64VT = EVT::getIntegerVT(Context, 64); 218 219 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT); 220 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT); 221 222 SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op0); 223 SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op0); 224 SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op1); 225 226 SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Trunc, Op0); 227 SDValue Neg = DAG->getNegative(Op0, DL, Int32VT); 228 SDValue Not = DAG->getNOT(DL, Op0, Int32VT); 229 230 using namespace SDPatternMatch; 231 EXPECT_TRUE(sd_match(ZExt, m_UnaryOp(ISD::ZERO_EXTEND, m_Value()))); 232 EXPECT_TRUE(sd_match(SExt, m_SExt(m_Value()))); 233 EXPECT_TRUE(sd_match(Trunc, m_Trunc(m_Specific(Op1)))); 234 235 EXPECT_TRUE(sd_match(Neg, m_Neg(m_Value()))); 236 EXPECT_TRUE(sd_match(Not, m_Not(m_Value()))); 237 EXPECT_FALSE(sd_match(ZExt, m_Neg(m_Value()))); 238 EXPECT_FALSE(sd_match(Sub, m_Neg(m_Value()))); 239 EXPECT_FALSE(sd_match(Neg, m_Not(m_Value()))); 240 } 241 242 TEST_F(SelectionDAGPatternMatchTest, matchConstants) { 243 SDLoc DL; 244 auto Int32VT = EVT::getIntegerVT(Context, 32); 245 auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4); 246 247 SDValue Arg0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT); 248 249 SDValue Const3 = DAG->getConstant(3, DL, Int32VT); 250 SDValue Const87 = DAG->getConstant(87, DL, Int32VT); 251 SDValue Splat = DAG->getSplat(VInt32VT, DL, Arg0); 252 SDValue ConstSplat = DAG->getSplat(VInt32VT, DL, Const3); 253 SDValue Zero = DAG->getConstant(0, DL, Int32VT); 254 SDValue One = DAG->getConstant(1, DL, Int32VT); 255 SDValue AllOnes = DAG->getConstant(APInt::getAllOnes(32), DL, Int32VT); 256 SDValue SetCC = DAG->getSetCC(DL, Int32VT, Arg0, Const3, ISD::SETULT); 257 258 using namespace SDPatternMatch; 259 EXPECT_TRUE(sd_match(Const87, m_ConstInt())); 260 EXPECT_FALSE(sd_match(Arg0, m_ConstInt())); 261 APInt ConstVal; 262 EXPECT_TRUE(sd_match(ConstSplat, m_ConstInt(ConstVal))); 263 EXPECT_EQ(ConstVal, 3); 264 EXPECT_FALSE(sd_match(Splat, m_ConstInt())); 265 266 EXPECT_TRUE(sd_match(Const87, m_SpecificInt(87))); 267 EXPECT_TRUE(sd_match(Const3, m_SpecificInt(ConstVal))); 268 EXPECT_TRUE(sd_match(AllOnes, m_AllOnes())); 269 270 EXPECT_TRUE(sd_match(Zero, DAG.get(), m_False())); 271 EXPECT_TRUE(sd_match(One, DAG.get(), m_True())); 272 EXPECT_FALSE(sd_match(AllOnes, DAG.get(), m_True())); 273 274 ISD::CondCode CC; 275 EXPECT_TRUE(sd_match( 276 SetCC, m_Node(ISD::SETCC, m_Value(), m_Value(), m_CondCode(CC)))); 277 EXPECT_EQ(CC, ISD::SETULT); 278 EXPECT_TRUE(sd_match(SetCC, m_Node(ISD::SETCC, m_Value(), m_Value(), 279 m_SpecificCondCode(ISD::SETULT)))); 280 } 281 282 TEST_F(SelectionDAGPatternMatchTest, patternCombinators) { 283 SDLoc DL; 284 auto Int32VT = EVT::getIntegerVT(Context, 32); 285 286 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT); 287 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT); 288 289 SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1); 290 SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Add, Op0); 291 292 using namespace SDPatternMatch; 293 EXPECT_TRUE(sd_match( 294 Sub, m_AnyOf(m_Opc(ISD::ADD), m_Opc(ISD::SUB), m_Opc(ISD::MUL)))); 295 EXPECT_TRUE(sd_match(Add, m_AllOf(m_Opc(ISD::ADD), m_OneUse()))); 296 EXPECT_TRUE(sd_match(Add, m_NoneOf(m_Opc(ISD::SUB), m_Opc(ISD::MUL)))); 297 } 298 299 TEST_F(SelectionDAGPatternMatchTest, optionalResizing) { 300 SDLoc DL; 301 auto Int32VT = EVT::getIntegerVT(Context, 32); 302 auto Int64VT = EVT::getIntegerVT(Context, 64); 303 304 SDValue Op32 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT); 305 SDValue Op64 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT); 306 SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op32); 307 SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op32); 308 SDValue AExt = DAG->getNode(ISD::ANY_EXTEND, DL, Int64VT, Op32); 309 SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op64); 310 311 using namespace SDPatternMatch; 312 SDValue A; 313 EXPECT_TRUE(sd_match(Op32, m_ZExtOrSelf(m_Value(A)))); 314 EXPECT_TRUE(A == Op32); 315 EXPECT_TRUE(sd_match(ZExt, m_ZExtOrSelf(m_Value(A)))); 316 EXPECT_TRUE(A == Op32); 317 EXPECT_TRUE(sd_match(Op64, m_SExtOrSelf(m_Value(A)))); 318 EXPECT_TRUE(A == Op64); 319 EXPECT_TRUE(sd_match(SExt, m_SExtOrSelf(m_Value(A)))); 320 EXPECT_TRUE(A == Op32); 321 EXPECT_TRUE(sd_match(Op32, m_AExtOrSelf(m_Value(A)))); 322 EXPECT_TRUE(A == Op32); 323 EXPECT_TRUE(sd_match(AExt, m_AExtOrSelf(m_Value(A)))); 324 EXPECT_TRUE(A == Op32); 325 EXPECT_TRUE(sd_match(Op64, m_TruncOrSelf(m_Value(A)))); 326 EXPECT_TRUE(A == Op64); 327 EXPECT_TRUE(sd_match(Trunc, m_TruncOrSelf(m_Value(A)))); 328 EXPECT_TRUE(A == Op64); 329 } 330 331 TEST_F(SelectionDAGPatternMatchTest, matchNode) { 332 SDLoc DL; 333 auto Int32VT = EVT::getIntegerVT(Context, 32); 334 335 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT); 336 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT); 337 338 SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1); 339 340 using namespace SDPatternMatch; 341 EXPECT_TRUE(sd_match(Add, m_Node(ISD::ADD, m_Value(), m_Value()))); 342 EXPECT_FALSE(sd_match(Add, m_Node(ISD::SUB, m_Value(), m_Value()))); 343 EXPECT_FALSE(sd_match(Add, m_Node(ISD::ADD, m_Value()))); 344 EXPECT_FALSE( 345 sd_match(Add, m_Node(ISD::ADD, m_Value(), m_Value(), m_Value()))); 346 EXPECT_FALSE(sd_match(Add, m_Node(ISD::ADD, m_ConstInt(), m_Value()))); 347 } 348 349 namespace { 350 struct VPMatchContext : public SDPatternMatch::BasicMatchContext { 351 using SDPatternMatch::BasicMatchContext::BasicMatchContext; 352 353 bool match(SDValue OpVal, unsigned Opc) const { 354 if (!OpVal->isVPOpcode()) 355 return OpVal->getOpcode() == Opc; 356 357 auto BaseOpc = ISD::getBaseOpcodeForVP(OpVal->getOpcode(), false); 358 return BaseOpc.has_value() && *BaseOpc == Opc; 359 } 360 }; 361 } // anonymous namespace 362 TEST_F(SelectionDAGPatternMatchTest, matchContext) { 363 SDLoc DL; 364 auto BoolVT = EVT::getIntegerVT(Context, 1); 365 auto Int32VT = EVT::getIntegerVT(Context, 32); 366 auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4); 367 auto MaskVT = EVT::getVectorVT(Context, BoolVT, 4); 368 369 SDValue Scalar0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT); 370 SDValue Vector0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT); 371 SDValue Mask0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, MaskVT); 372 373 SDValue VPAdd = DAG->getNode(ISD::VP_ADD, DL, VInt32VT, 374 {Vector0, Vector0, Mask0, Scalar0}); 375 SDValue VPReduceAdd = DAG->getNode(ISD::VP_REDUCE_ADD, DL, Int32VT, 376 {Scalar0, VPAdd, Mask0, Scalar0}); 377 378 using namespace SDPatternMatch; 379 VPMatchContext VPCtx(DAG.get()); 380 EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_Opc(ISD::ADD))); 381 // VP_REDUCE_ADD doesn't have a based opcode, so we use a normal 382 // sd_match before switching to VPMatchContext when checking VPAdd. 383 EXPECT_TRUE(sd_match(VPReduceAdd, m_Node(ISD::VP_REDUCE_ADD, m_Value(), 384 m_Context(VPCtx, m_Opc(ISD::ADD)), 385 m_Value(), m_Value()))); 386 } 387 388 TEST_F(SelectionDAGPatternMatchTest, matchAdvancedProperties) { 389 SDLoc DL; 390 auto Int16VT = EVT::getIntegerVT(Context, 16); 391 auto Int64VT = EVT::getIntegerVT(Context, 64); 392 393 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT); 394 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int16VT); 395 396 SDValue Add = DAG->getNode(ISD::ADD, DL, Int64VT, Op0, Op0); 397 398 using namespace SDPatternMatch; 399 EXPECT_TRUE(sd_match(Op0, DAG.get(), m_LegalType(m_Value()))); 400 EXPECT_FALSE(sd_match(Op1, DAG.get(), m_LegalType(m_Value()))); 401 EXPECT_TRUE(sd_match(Add, DAG.get(), 402 m_LegalOp(m_IntegerVT(m_Add(m_Value(), m_Value()))))); 403 } 404