llvm-project
2294 строки · 87.6 Кб
1//===---- llvm/unittest/IR/PatternMatch.cpp - PatternMatch unit tests ----===//
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/IR/PatternMatch.h"10#include "llvm/ADT/APSInt.h"11#include "llvm/ADT/STLExtras.h"12#include "llvm/Analysis/ValueTracking.h"13#include "llvm/IR/BasicBlock.h"14#include "llvm/IR/Constants.h"15#include "llvm/IR/DataLayout.h"16#include "llvm/IR/DerivedTypes.h"17#include "llvm/IR/Function.h"18#include "llvm/IR/IRBuilder.h"19#include "llvm/IR/Instructions.h"20#include "llvm/IR/LLVMContext.h"21#include "llvm/IR/MDBuilder.h"22#include "llvm/IR/Module.h"23#include "llvm/IR/NoFolder.h"24#include "llvm/IR/Operator.h"25#include "llvm/IR/Type.h"26#include "gtest/gtest.h"27
28using namespace llvm;29using namespace llvm::PatternMatch;30
31namespace {32
33struct PatternMatchTest : ::testing::Test {34LLVMContext Ctx;35std::unique_ptr<Module> M;36Function *F;37BasicBlock *BB;38IRBuilder<NoFolder> IRB;39
40PatternMatchTest()41: M(new Module("PatternMatchTestModule", Ctx)),42F(Function::Create(43FunctionType::get(Type::getVoidTy(Ctx), /* IsVarArg */ false),44Function::ExternalLinkage, "f", M.get())),45BB(BasicBlock::Create(Ctx, "entry", F)), IRB(BB) {}46};47
48TEST_F(PatternMatchTest, OneUse) {49// Build up a little tree of values:50//51// One = (1 + 2) + 4252// Two = One + 4253// Leaf = (Two + 8) + (Two + 13)54Value *One = IRB.CreateAdd(IRB.CreateAdd(IRB.getInt32(1), IRB.getInt32(2)),55IRB.getInt32(42));56Value *Two = IRB.CreateAdd(One, IRB.getInt32(42));57Value *Leaf = IRB.CreateAdd(IRB.CreateAdd(Two, IRB.getInt32(8)),58IRB.CreateAdd(Two, IRB.getInt32(13)));59Value *V;60
61EXPECT_TRUE(m_OneUse(m_Value(V)).match(One));62EXPECT_EQ(One, V);63
64EXPECT_FALSE(m_OneUse(m_Value()).match(Two));65EXPECT_FALSE(m_OneUse(m_Value()).match(Leaf));66}
67
68TEST_F(PatternMatchTest, SpecificIntEQ) {69Type *IntTy = IRB.getInt32Ty();70unsigned BitWidth = IntTy->getScalarSizeInBits();71
72Value *Zero = ConstantInt::get(IntTy, 0);73Value *One = ConstantInt::get(IntTy, 1);74Value *NegOne = ConstantInt::get(IntTy, -1);75
76EXPECT_TRUE(77m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0))78.match(Zero));79EXPECT_FALSE(80m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0))81.match(One));82EXPECT_FALSE(83m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0))84.match(NegOne));85
86EXPECT_FALSE(87m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1))88.match(Zero));89EXPECT_TRUE(90m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1))91.match(One));92EXPECT_FALSE(93m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1))94.match(NegOne));95
96EXPECT_FALSE(97m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1))98.match(Zero));99EXPECT_FALSE(100m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1))101.match(One));102EXPECT_TRUE(103m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1))104.match(NegOne));105}
106
107TEST_F(PatternMatchTest, SpecificIntNE) {108Type *IntTy = IRB.getInt32Ty();109unsigned BitWidth = IntTy->getScalarSizeInBits();110
111Value *Zero = ConstantInt::get(IntTy, 0);112Value *One = ConstantInt::get(IntTy, 1);113Value *NegOne = ConstantInt::get(IntTy, -1);114
115EXPECT_FALSE(116m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0))117.match(Zero));118EXPECT_TRUE(119m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0))120.match(One));121EXPECT_TRUE(122m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0))123.match(NegOne));124
125EXPECT_TRUE(126m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1))127.match(Zero));128EXPECT_FALSE(129m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1))130.match(One));131EXPECT_TRUE(132m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1))133.match(NegOne));134
135EXPECT_TRUE(136m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1))137.match(Zero));138EXPECT_TRUE(139m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1))140.match(One));141EXPECT_FALSE(142m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1))143.match(NegOne));144}
145
146TEST_F(PatternMatchTest, SpecificIntUGT) {147Type *IntTy = IRB.getInt32Ty();148unsigned BitWidth = IntTy->getScalarSizeInBits();149
150Value *Zero = ConstantInt::get(IntTy, 0);151Value *One = ConstantInt::get(IntTy, 1);152Value *NegOne = ConstantInt::get(IntTy, -1);153
154EXPECT_FALSE(155m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0))156.match(Zero));157EXPECT_TRUE(158m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0))159.match(One));160EXPECT_TRUE(161m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0))162.match(NegOne));163
164EXPECT_FALSE(165m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1))166.match(Zero));167EXPECT_FALSE(168m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1))169.match(One));170EXPECT_TRUE(171m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1))172.match(NegOne));173
174EXPECT_FALSE(175m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1))176.match(Zero));177EXPECT_FALSE(178m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1))179.match(One));180EXPECT_FALSE(181m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1))182.match(NegOne));183}
184
185TEST_F(PatternMatchTest, SignbitZeroChecks) {186Type *IntTy = IRB.getInt32Ty();187
188Value *Zero = ConstantInt::get(IntTy, 0);189Value *One = ConstantInt::get(IntTy, 1);190Value *NegOne = ConstantInt::get(IntTy, -1);191
192EXPECT_TRUE(m_Negative().match(NegOne));193EXPECT_FALSE(m_NonNegative().match(NegOne));194EXPECT_FALSE(m_StrictlyPositive().match(NegOne));195EXPECT_TRUE(m_NonPositive().match(NegOne));196
197EXPECT_FALSE(m_Negative().match(Zero));198EXPECT_TRUE(m_NonNegative().match(Zero));199EXPECT_FALSE(m_StrictlyPositive().match(Zero));200EXPECT_TRUE(m_NonPositive().match(Zero));201
202EXPECT_FALSE(m_Negative().match(One));203EXPECT_TRUE(m_NonNegative().match(One));204EXPECT_TRUE(m_StrictlyPositive().match(One));205EXPECT_FALSE(m_NonPositive().match(One));206}
207
208TEST_F(PatternMatchTest, SpecificIntUGE) {209Type *IntTy = IRB.getInt32Ty();210unsigned BitWidth = IntTy->getScalarSizeInBits();211
212Value *Zero = ConstantInt::get(IntTy, 0);213Value *One = ConstantInt::get(IntTy, 1);214Value *NegOne = ConstantInt::get(IntTy, -1);215
216EXPECT_TRUE(217m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0))218.match(Zero));219EXPECT_TRUE(220m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0))221.match(One));222EXPECT_TRUE(223m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0))224.match(NegOne));225
226EXPECT_FALSE(227m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1))228.match(Zero));229EXPECT_TRUE(230m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1))231.match(One));232EXPECT_TRUE(233m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1))234.match(NegOne));235
236EXPECT_FALSE(237m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1))238.match(Zero));239EXPECT_FALSE(240m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1))241.match(One));242EXPECT_TRUE(243m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1))244.match(NegOne));245}
246
247TEST_F(PatternMatchTest, SpecificIntULT) {248Type *IntTy = IRB.getInt32Ty();249unsigned BitWidth = IntTy->getScalarSizeInBits();250
251Value *Zero = ConstantInt::get(IntTy, 0);252Value *One = ConstantInt::get(IntTy, 1);253Value *NegOne = ConstantInt::get(IntTy, -1);254
255EXPECT_FALSE(256m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0))257.match(Zero));258EXPECT_FALSE(259m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0))260.match(One));261EXPECT_FALSE(262m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0))263.match(NegOne));264
265EXPECT_TRUE(266m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1))267.match(Zero));268EXPECT_FALSE(269m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1))270.match(One));271EXPECT_FALSE(272m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1))273.match(NegOne));274
275EXPECT_TRUE(276m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1))277.match(Zero));278EXPECT_TRUE(279m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1))280.match(One));281EXPECT_FALSE(282m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1))283.match(NegOne));284}
285
286TEST_F(PatternMatchTest, SpecificIntULE) {287Type *IntTy = IRB.getInt32Ty();288unsigned BitWidth = IntTy->getScalarSizeInBits();289
290Value *Zero = ConstantInt::get(IntTy, 0);291Value *One = ConstantInt::get(IntTy, 1);292Value *NegOne = ConstantInt::get(IntTy, -1);293
294EXPECT_TRUE(295m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0))296.match(Zero));297EXPECT_FALSE(298m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0))299.match(One));300EXPECT_FALSE(301m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0))302.match(NegOne));303
304EXPECT_TRUE(305m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1))306.match(Zero));307EXPECT_TRUE(308m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1))309.match(One));310EXPECT_FALSE(311m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1))312.match(NegOne));313
314EXPECT_TRUE(315m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1))316.match(Zero));317EXPECT_TRUE(318m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1))319.match(One));320EXPECT_TRUE(321m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1))322.match(NegOne));323}
324
325TEST_F(PatternMatchTest, SpecificIntSGT) {326Type *IntTy = IRB.getInt32Ty();327unsigned BitWidth = IntTy->getScalarSizeInBits();328
329Value *Zero = ConstantInt::get(IntTy, 0);330Value *One = ConstantInt::get(IntTy, 1);331Value *NegOne = ConstantInt::get(IntTy, -1);332
333EXPECT_FALSE(334m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0))335.match(Zero));336EXPECT_TRUE(337m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0))338.match(One));339EXPECT_FALSE(340m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0))341.match(NegOne));342
343EXPECT_FALSE(344m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1))345.match(Zero));346EXPECT_FALSE(347m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1))348.match(One));349EXPECT_FALSE(350m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1))351.match(NegOne));352
353EXPECT_TRUE(354m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1))355.match(Zero));356EXPECT_TRUE(357m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1))358.match(One));359EXPECT_FALSE(360m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1))361.match(NegOne));362}
363
364TEST_F(PatternMatchTest, SpecificIntSGE) {365Type *IntTy = IRB.getInt32Ty();366unsigned BitWidth = IntTy->getScalarSizeInBits();367
368Value *Zero = ConstantInt::get(IntTy, 0);369Value *One = ConstantInt::get(IntTy, 1);370Value *NegOne = ConstantInt::get(IntTy, -1);371
372EXPECT_TRUE(373m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0))374.match(Zero));375EXPECT_TRUE(376m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0))377.match(One));378EXPECT_FALSE(379m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0))380.match(NegOne));381
382EXPECT_FALSE(383m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1))384.match(Zero));385EXPECT_TRUE(386m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1))387.match(One));388EXPECT_FALSE(389m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1))390.match(NegOne));391
392EXPECT_TRUE(393m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1))394.match(Zero));395EXPECT_TRUE(396m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1))397.match(One));398EXPECT_TRUE(399m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1))400.match(NegOne));401}
402
403TEST_F(PatternMatchTest, SpecificIntSLT) {404Type *IntTy = IRB.getInt32Ty();405unsigned BitWidth = IntTy->getScalarSizeInBits();406
407Value *Zero = ConstantInt::get(IntTy, 0);408Value *One = ConstantInt::get(IntTy, 1);409Value *NegOne = ConstantInt::get(IntTy, -1);410
411EXPECT_FALSE(412m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0))413.match(Zero));414EXPECT_FALSE(415m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0))416.match(One));417EXPECT_TRUE(418m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0))419.match(NegOne));420
421EXPECT_TRUE(422m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1))423.match(Zero));424EXPECT_FALSE(425m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1))426.match(One));427EXPECT_TRUE(428m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1))429.match(NegOne));430
431EXPECT_FALSE(432m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1))433.match(Zero));434EXPECT_FALSE(435m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1))436.match(One));437EXPECT_FALSE(438m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1))439.match(NegOne));440}
441
442TEST_F(PatternMatchTest, SpecificIntSLE) {443Type *IntTy = IRB.getInt32Ty();444unsigned BitWidth = IntTy->getScalarSizeInBits();445
446Value *Zero = ConstantInt::get(IntTy, 0);447Value *One = ConstantInt::get(IntTy, 1);448Value *NegOne = ConstantInt::get(IntTy, -1);449
450EXPECT_TRUE(451m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0))452.match(Zero));453EXPECT_FALSE(454m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0))455.match(One));456EXPECT_TRUE(457m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0))458.match(NegOne));459
460EXPECT_TRUE(461m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1))462.match(Zero));463EXPECT_TRUE(464m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1))465.match(One));466EXPECT_TRUE(467m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1))468.match(NegOne));469
470EXPECT_FALSE(471m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1))472.match(Zero));473EXPECT_FALSE(474m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1))475.match(One));476EXPECT_TRUE(477m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1))478.match(NegOne));479}
480
481TEST_F(PatternMatchTest, Unless) {482Value *X = IRB.CreateAdd(IRB.getInt32(1), IRB.getInt32(0));483
484EXPECT_TRUE(m_Add(m_One(), m_Zero()).match(X));485EXPECT_FALSE(m_Add(m_Zero(), m_One()).match(X));486
487EXPECT_FALSE(m_Unless(m_Add(m_One(), m_Zero())).match(X));488EXPECT_TRUE(m_Unless(m_Add(m_Zero(), m_One())).match(X));489
490EXPECT_TRUE(m_c_Add(m_One(), m_Zero()).match(X));491EXPECT_TRUE(m_c_Add(m_Zero(), m_One()).match(X));492
493EXPECT_FALSE(m_Unless(m_c_Add(m_One(), m_Zero())).match(X));494EXPECT_FALSE(m_Unless(m_c_Add(m_Zero(), m_One())).match(X));495}
496
497TEST_F(PatternMatchTest, BitWise) {498Value *Or = IRB.CreateOr(IRB.getInt32(1), IRB.getInt32(0));499Value *Xor = IRB.CreateXor(IRB.getInt32(1), IRB.getInt32(0));500Value *And = IRB.CreateXor(IRB.getInt32(1), IRB.getInt32(0));501Constant *T = IRB.getInt1(true);502Constant *F = IRB.getInt1(false);503Value *Alloca = IRB.CreateAlloca(IRB.getInt1Ty());504Value *X = IRB.CreateLoad(IRB.getInt1Ty(), Alloca);505Value *Y = IRB.CreateLoad(IRB.getInt1Ty(), Alloca);506Value *LAnd = IRB.CreateSelect(X, Y, F);507Value *LOr = IRB.CreateSelect(X, T, Y);508Value *Add = IRB.CreateAdd(IRB.getInt32(1), IRB.getInt32(0));509
510EXPECT_TRUE(m_BitwiseLogic(m_One(), m_Zero()).match(Or));511EXPECT_TRUE(m_BitwiseLogic(m_One(), m_Zero()).match(Xor));512EXPECT_TRUE(m_BitwiseLogic(m_One(), m_Zero()).match(And));513EXPECT_FALSE(m_BitwiseLogic(m_Value(), m_Value()).match(LAnd));514EXPECT_FALSE(m_BitwiseLogic(m_Value(), m_Value()).match(LOr));515EXPECT_FALSE(m_BitwiseLogic(m_Value(), m_Value()).match(Add));516
517EXPECT_FALSE(m_BitwiseLogic(m_Zero(), m_One()).match(Or));518EXPECT_FALSE(m_BitwiseLogic(m_Zero(), m_One()).match(Xor));519EXPECT_FALSE(m_BitwiseLogic(m_Zero(), m_One()).match(And));520
521EXPECT_TRUE(m_c_BitwiseLogic(m_One(), m_Zero()).match(Or));522EXPECT_TRUE(m_c_BitwiseLogic(m_One(), m_Zero()).match(Xor));523EXPECT_TRUE(m_c_BitwiseLogic(m_One(), m_Zero()).match(And));524EXPECT_FALSE(m_c_BitwiseLogic(m_Value(), m_Value()).match(LAnd));525EXPECT_FALSE(m_c_BitwiseLogic(m_Value(), m_Value()).match(LOr));526EXPECT_FALSE(m_c_BitwiseLogic(m_Value(), m_Value()).match(Add));527
528EXPECT_TRUE(m_c_BitwiseLogic(m_Zero(), m_One()).match(Or));529EXPECT_TRUE(m_c_BitwiseLogic(m_Zero(), m_One()).match(Xor));530EXPECT_TRUE(m_c_BitwiseLogic(m_Zero(), m_One()).match(And));531
532EXPECT_FALSE(m_c_BitwiseLogic(m_One(), m_One()).match(Or));533EXPECT_FALSE(m_c_BitwiseLogic(m_Zero(), m_Zero()).match(Xor));534}
535
536TEST_F(PatternMatchTest, ZExtSExtSelf) {537LLVMContext &Ctx = IRB.getContext();538
539Value *One32 = IRB.getInt32(1);540Value *One64Z = IRB.CreateZExt(One32, IntegerType::getInt64Ty(Ctx));541Value *One64S = IRB.CreateSExt(One32, IntegerType::getInt64Ty(Ctx));542
543EXPECT_TRUE(m_One().match(One32));544EXPECT_FALSE(m_One().match(One64Z));545EXPECT_FALSE(m_One().match(One64S));546
547EXPECT_FALSE(m_ZExt(m_One()).match(One32));548EXPECT_TRUE(m_ZExt(m_One()).match(One64Z));549EXPECT_FALSE(m_ZExt(m_One()).match(One64S));550
551EXPECT_FALSE(m_SExt(m_One()).match(One32));552EXPECT_FALSE(m_SExt(m_One()).match(One64Z));553EXPECT_TRUE(m_SExt(m_One()).match(One64S));554
555EXPECT_TRUE(m_ZExtOrSelf(m_One()).match(One32));556EXPECT_TRUE(m_ZExtOrSelf(m_One()).match(One64Z));557EXPECT_FALSE(m_ZExtOrSelf(m_One()).match(One64S));558
559EXPECT_TRUE(m_SExtOrSelf(m_One()).match(One32));560EXPECT_FALSE(m_SExtOrSelf(m_One()).match(One64Z));561EXPECT_TRUE(m_SExtOrSelf(m_One()).match(One64S));562
563EXPECT_FALSE(m_ZExtOrSExt(m_One()).match(One32));564EXPECT_TRUE(m_ZExtOrSExt(m_One()).match(One64Z));565EXPECT_TRUE(m_ZExtOrSExt(m_One()).match(One64S));566
567EXPECT_TRUE(m_ZExtOrSExtOrSelf(m_One()).match(One32));568EXPECT_TRUE(m_ZExtOrSExtOrSelf(m_One()).match(One64Z));569EXPECT_TRUE(m_ZExtOrSExtOrSelf(m_One()).match(One64S));570}
571
572TEST_F(PatternMatchTest, BitCast) {573Value *OneDouble = ConstantFP::get(IRB.getDoubleTy(), APFloat(1.0));574Value *ScalableDouble = ConstantFP::get(575VectorType::get(IRB.getDoubleTy(), 2, /*Scalable=*/true), APFloat(1.0));576// scalar -> scalar577Value *DoubleToI64 = IRB.CreateBitCast(OneDouble, IRB.getInt64Ty());578// scalar -> vector579Value *DoubleToV2I32 = IRB.CreateBitCast(580OneDouble, VectorType::get(IRB.getInt32Ty(), 2, /*Scalable=*/false));581// vector -> scalar582Value *V2I32ToDouble = IRB.CreateBitCast(DoubleToV2I32, IRB.getDoubleTy());583// vector -> vector (same count)584Value *V2I32ToV2Float = IRB.CreateBitCast(585DoubleToV2I32, VectorType::get(IRB.getFloatTy(), 2, /*Scalable=*/false));586// vector -> vector (different count)587Value *V2I32TOV4I16 = IRB.CreateBitCast(588DoubleToV2I32, VectorType::get(IRB.getInt16Ty(), 4, /*Scalable=*/false));589// scalable vector -> scalable vector (same count)590Value *NXV2DoubleToNXV2I64 = IRB.CreateBitCast(591ScalableDouble, VectorType::get(IRB.getInt64Ty(), 2, /*Scalable=*/true));592// scalable vector -> scalable vector (different count)593Value *NXV2I64ToNXV4I32 = IRB.CreateBitCast(594NXV2DoubleToNXV2I64,595VectorType::get(IRB.getInt32Ty(), 4, /*Scalable=*/true));596
597EXPECT_TRUE(m_BitCast(m_Value()).match(DoubleToI64));598EXPECT_TRUE(m_BitCast(m_Value()).match(DoubleToV2I32));599EXPECT_TRUE(m_BitCast(m_Value()).match(V2I32ToDouble));600EXPECT_TRUE(m_BitCast(m_Value()).match(V2I32ToV2Float));601EXPECT_TRUE(m_BitCast(m_Value()).match(V2I32TOV4I16));602EXPECT_TRUE(m_BitCast(m_Value()).match(NXV2DoubleToNXV2I64));603EXPECT_TRUE(m_BitCast(m_Value()).match(NXV2I64ToNXV4I32));604
605EXPECT_TRUE(m_ElementWiseBitCast(m_Value()).match(DoubleToI64));606EXPECT_FALSE(m_ElementWiseBitCast(m_Value()).match(DoubleToV2I32));607EXPECT_FALSE(m_ElementWiseBitCast(m_Value()).match(V2I32ToDouble));608EXPECT_TRUE(m_ElementWiseBitCast(m_Value()).match(V2I32ToV2Float));609EXPECT_FALSE(m_ElementWiseBitCast(m_Value()).match(V2I32TOV4I16));610EXPECT_TRUE(m_ElementWiseBitCast(m_Value()).match(NXV2DoubleToNXV2I64));611EXPECT_FALSE(m_ElementWiseBitCast(m_Value()).match(NXV2I64ToNXV4I32));612}
613
614TEST_F(PatternMatchTest, CheckedInt) {615Type *I8Ty = IRB.getInt8Ty();616const Constant * CRes = nullptr;617auto CheckUgt1 = [](const APInt &C) { return C.ugt(1); };618auto CheckTrue = [](const APInt &) { return true; };619auto CheckFalse = [](const APInt &) { return false; };620auto CheckNonZero = [](const APInt &C) { return !C.isZero(); };621auto CheckPow2 = [](const APInt &C) { return C.isPowerOf2(); };622
623auto DoScalarCheck = [&](int8_t Val) {624APInt APVal(8, Val);625Constant *C = ConstantInt::get(I8Ty, Val);626
627CRes = nullptr;628EXPECT_TRUE(m_CheckedInt(CheckTrue).match(C));629EXPECT_TRUE(m_CheckedInt(CRes, CheckTrue).match(C));630EXPECT_EQ(CRes, C);631
632CRes = nullptr;633EXPECT_FALSE(m_CheckedInt(CheckFalse).match(C));634EXPECT_FALSE(m_CheckedInt(CRes, CheckFalse).match(C));635EXPECT_EQ(CRes, nullptr);636
637CRes = nullptr;638EXPECT_EQ(CheckUgt1(APVal), m_CheckedInt(CheckUgt1).match(C));639EXPECT_EQ(CheckUgt1(APVal), m_CheckedInt(CRes, CheckUgt1).match(C));640if (CheckUgt1(APVal))641EXPECT_EQ(CRes, C);642
643CRes = nullptr;644EXPECT_EQ(CheckNonZero(APVal), m_CheckedInt(CheckNonZero).match(C));645EXPECT_EQ(CheckNonZero(APVal), m_CheckedInt(CRes, CheckNonZero).match(C));646if (CheckNonZero(APVal))647EXPECT_EQ(CRes, C);648
649CRes = nullptr;650EXPECT_EQ(CheckPow2(APVal), m_CheckedInt(CheckPow2).match(C));651EXPECT_EQ(CheckPow2(APVal), m_CheckedInt(CRes, CheckPow2).match(C));652if (CheckPow2(APVal))653EXPECT_EQ(CRes, C);654
655};656
657DoScalarCheck(0);658DoScalarCheck(1);659DoScalarCheck(2);660DoScalarCheck(3);661
662EXPECT_FALSE(m_CheckedInt(CheckTrue).match(UndefValue::get(I8Ty)));663EXPECT_FALSE(m_CheckedInt(CRes, CheckTrue).match(UndefValue::get(I8Ty)));664EXPECT_EQ(CRes, nullptr);665
666EXPECT_FALSE(m_CheckedInt(CheckFalse).match(UndefValue::get(I8Ty)));667EXPECT_FALSE(m_CheckedInt(CRes, CheckFalse).match(UndefValue::get(I8Ty)));668EXPECT_EQ(CRes, nullptr);669
670EXPECT_FALSE(m_CheckedInt(CheckTrue).match(PoisonValue::get(I8Ty)));671EXPECT_FALSE(m_CheckedInt(CRes, CheckTrue).match(PoisonValue::get(I8Ty)));672EXPECT_EQ(CRes, nullptr);673
674EXPECT_FALSE(m_CheckedInt(CheckFalse).match(PoisonValue::get(I8Ty)));675EXPECT_FALSE(m_CheckedInt(CRes, CheckFalse).match(PoisonValue::get(I8Ty)));676EXPECT_EQ(CRes, nullptr);677
678auto DoVecCheckImpl = [&](ArrayRef<std::optional<int8_t>> Vals,679function_ref<bool(const APInt &)> CheckFn,680bool UndefAsPoison) {681SmallVector<Constant *> VecElems;682std::optional<bool> Okay;683bool AllSame = true;684bool HasUndef = false;685std::optional<APInt> First;686for (const std::optional<int8_t> &Val : Vals) {687if (!Val.has_value()) {688VecElems.push_back(UndefAsPoison ? PoisonValue::get(I8Ty)689: UndefValue::get(I8Ty));690HasUndef = true;691} else {692if (!Okay.has_value())693Okay = true;694APInt APVal(8, *Val);695if (!First.has_value())696First = APVal;697else698AllSame &= First->eq(APVal);699Okay = *Okay && CheckFn(APVal);700VecElems.push_back(ConstantInt::get(I8Ty, *Val));701}702}703
704Constant *C = ConstantVector::get(VecElems);705EXPECT_EQ(!(HasUndef && !UndefAsPoison) && Okay.value_or(false),706m_CheckedInt(CheckFn).match(C));707
708CRes = nullptr;709bool Expec = !(HasUndef && !UndefAsPoison) && Okay.value_or(false);710EXPECT_EQ(Expec, m_CheckedInt(CRes, CheckFn).match(C));711if (Expec) {712EXPECT_NE(CRes, nullptr);713if (AllSame)714EXPECT_EQ(CRes, C);715}716};717auto DoVecCheck = [&](ArrayRef<std::optional<int8_t>> Vals) {718DoVecCheckImpl(Vals, CheckTrue, /*UndefAsPoison=*/false);719DoVecCheckImpl(Vals, CheckFalse, /*UndefAsPoison=*/false);720DoVecCheckImpl(Vals, CheckTrue, /*UndefAsPoison=*/true);721DoVecCheckImpl(Vals, CheckFalse, /*UndefAsPoison=*/true);722DoVecCheckImpl(Vals, CheckUgt1, /*UndefAsPoison=*/false);723DoVecCheckImpl(Vals, CheckNonZero, /*UndefAsPoison=*/false);724DoVecCheckImpl(Vals, CheckPow2, /*UndefAsPoison=*/false);725};726
727DoVecCheck({0, 1});728DoVecCheck({1, 1});729DoVecCheck({1, 2});730DoVecCheck({1, std::nullopt});731DoVecCheck({1, std::nullopt, 1});732DoVecCheck({1, std::nullopt, 2});733DoVecCheck({std::nullopt, std::nullopt, std::nullopt});734}
735
736TEST_F(PatternMatchTest, Power2) {737Value *C128 = IRB.getInt32(128);738Value *CNeg128 = ConstantExpr::getNeg(cast<Constant>(C128));739
740EXPECT_TRUE(m_Power2().match(C128));741EXPECT_FALSE(m_Power2().match(CNeg128));742
743EXPECT_TRUE(m_Power2OrZero().match(C128));744EXPECT_FALSE(m_Power2OrZero().match(CNeg128));745
746EXPECT_FALSE(m_NegatedPower2().match(C128));747EXPECT_TRUE(m_NegatedPower2().match(CNeg128));748
749EXPECT_FALSE(m_NegatedPower2OrZero().match(C128));750EXPECT_TRUE(m_NegatedPower2OrZero().match(CNeg128));751
752Value *CIntMin = IRB.getInt64(APSInt::getSignedMinValue(64).getSExtValue());753Value *CNegIntMin = ConstantExpr::getNeg(cast<Constant>(CIntMin));754
755EXPECT_TRUE(m_Power2().match(CIntMin));756EXPECT_TRUE(m_Power2().match(CNegIntMin));757
758EXPECT_TRUE(m_Power2OrZero().match(CIntMin));759EXPECT_TRUE(m_Power2OrZero().match(CNegIntMin));760
761EXPECT_TRUE(m_NegatedPower2().match(CIntMin));762EXPECT_TRUE(m_NegatedPower2().match(CNegIntMin));763
764EXPECT_TRUE(m_NegatedPower2OrZero().match(CIntMin));765EXPECT_TRUE(m_NegatedPower2OrZero().match(CNegIntMin));766
767Value *CZero = IRB.getInt64(0);768
769EXPECT_FALSE(m_Power2().match(CZero));770
771EXPECT_TRUE(m_Power2OrZero().match(CZero));772
773EXPECT_FALSE(m_NegatedPower2().match(CZero));774
775EXPECT_TRUE(m_NegatedPower2OrZero().match(CZero));776}
777
778TEST_F(PatternMatchTest, Not) {779Value *C1 = IRB.getInt32(1);780Value *C2 = IRB.getInt32(2);781Value *C3 = IRB.getInt32(3);782Instruction *Not = BinaryOperator::CreateXor(C1, C2);783
784// When `m_Not` does not match the `not` itself,785// it should not try to apply the inner matcher.786Value *Val = C3;787EXPECT_FALSE(m_Not(m_Value(Val)).match(Not));788EXPECT_EQ(Val, C3);789Not->deleteValue();790}
791
792TEST_F(PatternMatchTest, CommutativeDeferredValue) {793Value *X = IRB.getInt32(1);794Value *Y = IRB.getInt32(2);795
796{797Value *tX = X;798EXPECT_TRUE(match(X, m_Deferred(tX)));799EXPECT_FALSE(match(Y, m_Deferred(tX)));800}801{802const Value *tX = X;803EXPECT_TRUE(match(X, m_Deferred(tX)));804EXPECT_FALSE(match(Y, m_Deferred(tX)));805}806{807Value *const tX = X;808EXPECT_TRUE(match(X, m_Deferred(tX)));809EXPECT_FALSE(match(Y, m_Deferred(tX)));810}811{812const Value *const tX = X;813EXPECT_TRUE(match(X, m_Deferred(tX)));814EXPECT_FALSE(match(Y, m_Deferred(tX)));815}816
817{818Value *tX = nullptr;819EXPECT_TRUE(match(IRB.CreateAnd(X, X), m_And(m_Value(tX), m_Deferred(tX))));820EXPECT_EQ(tX, X);821}822{823Value *tX = nullptr;824EXPECT_FALSE(825match(IRB.CreateAnd(X, Y), m_c_And(m_Value(tX), m_Deferred(tX))));826}827
828auto checkMatch = [X, Y](Value *Pattern) {829Value *tX = nullptr, *tY = nullptr;830EXPECT_TRUE(match(831Pattern, m_c_And(m_Value(tX), m_c_And(m_Deferred(tX), m_Value(tY)))));832EXPECT_EQ(tX, X);833EXPECT_EQ(tY, Y);834};835
836checkMatch(IRB.CreateAnd(X, IRB.CreateAnd(X, Y)));837checkMatch(IRB.CreateAnd(X, IRB.CreateAnd(Y, X)));838checkMatch(IRB.CreateAnd(IRB.CreateAnd(X, Y), X));839checkMatch(IRB.CreateAnd(IRB.CreateAnd(Y, X), X));840}
841
842TEST_F(PatternMatchTest, FloatingPointOrderedMin) {843Type *FltTy = IRB.getFloatTy();844Value *L = ConstantFP::get(FltTy, 1.0);845Value *R = ConstantFP::get(FltTy, 2.0);846Value *MatchL, *MatchR;847
848// Test OLT.849EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))850.match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R)));851EXPECT_EQ(L, MatchL);852EXPECT_EQ(R, MatchR);853
854// Test OLE.855EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))856.match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R)));857EXPECT_EQ(L, MatchL);858EXPECT_EQ(R, MatchR);859
860// Test no match on OGE.861EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))862.match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R)));863
864// Test no match on OGT.865EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))866.match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R)));867
868// Test inverted selects. Note, that this "inverts" the ordering, e.g.:869// %cmp = fcmp oge L, R870// %min = select %cmp R, L871// Given L == NaN872// the above is expanded to %cmp == false ==> %min = L873// which is true for UnordFMin, not OrdFMin, so test that:874
875// [OU]GE with inverted select.876EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))877.match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), R, L)));878EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))879.match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), R, L)));880EXPECT_EQ(L, MatchL);881EXPECT_EQ(R, MatchR);882
883// [OU]GT with inverted select.884EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))885.match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), R, L)));886EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))887.match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), R, L)));888EXPECT_EQ(L, MatchL);889EXPECT_EQ(R, MatchR);890}
891
892TEST_F(PatternMatchTest, FloatingPointOrderedMax) {893Type *FltTy = IRB.getFloatTy();894Value *L = ConstantFP::get(FltTy, 1.0);895Value *R = ConstantFP::get(FltTy, 2.0);896Value *MatchL, *MatchR;897
898// Test OGT.899EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))900.match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R)));901EXPECT_EQ(L, MatchL);902EXPECT_EQ(R, MatchR);903
904// Test OGE.905EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))906.match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R)));907EXPECT_EQ(L, MatchL);908EXPECT_EQ(R, MatchR);909
910// Test no match on OLE.911EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))912.match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R)));913
914// Test no match on OLT.915EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))916.match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R)));917
918
919// Test inverted selects. Note, that this "inverts" the ordering, e.g.:920// %cmp = fcmp ole L, R921// %max = select %cmp, R, L922// Given L == NaN,923// the above is expanded to %cmp == false ==> %max == L924// which is true for UnordFMax, not OrdFMax, so test that:925
926// [OU]LE with inverted select.927EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))928.match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), R, L)));929EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))930.match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), R, L)));931EXPECT_EQ(L, MatchL);932EXPECT_EQ(R, MatchR);933
934// [OUT]LT with inverted select.935EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))936.match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), R, L)));937EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))938.match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), R, L)));939EXPECT_EQ(L, MatchL);940EXPECT_EQ(R, MatchR);941}
942
943TEST_F(PatternMatchTest, FloatingPointUnorderedMin) {944Type *FltTy = IRB.getFloatTy();945Value *L = ConstantFP::get(FltTy, 1.0);946Value *R = ConstantFP::get(FltTy, 2.0);947Value *MatchL, *MatchR;948
949// Test ULT.950EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))951.match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R)));952EXPECT_EQ(L, MatchL);953EXPECT_EQ(R, MatchR);954
955// Test ULE.956EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))957.match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R)));958EXPECT_EQ(L, MatchL);959EXPECT_EQ(R, MatchR);960
961// Test no match on UGE.962EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))963.match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R)));964
965// Test no match on UGT.966EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))967.match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R)));968
969// Test inverted selects. Note, that this "inverts" the ordering, e.g.:970// %cmp = fcmp uge L, R971// %min = select %cmp R, L972// Given L == NaN973// the above is expanded to %cmp == true ==> %min = R974// which is true for OrdFMin, not UnordFMin, so test that:975
976// [UO]GE with inverted select.977EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))978.match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), R, L)));979EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))980.match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), R, L)));981EXPECT_EQ(L, MatchL);982EXPECT_EQ(R, MatchR);983
984// [UO]GT with inverted select.985EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))986.match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), R, L)));987EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))988.match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), R, L)));989EXPECT_EQ(L, MatchL);990EXPECT_EQ(R, MatchR);991}
992
993TEST_F(PatternMatchTest, FloatingPointUnorderedMax) {994Type *FltTy = IRB.getFloatTy();995Value *L = ConstantFP::get(FltTy, 1.0);996Value *R = ConstantFP::get(FltTy, 2.0);997Value *MatchL, *MatchR;998
999// Test UGT.1000EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))1001.match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R)));1002EXPECT_EQ(L, MatchL);1003EXPECT_EQ(R, MatchR);1004
1005// Test UGE.1006EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))1007.match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R)));1008EXPECT_EQ(L, MatchL);1009EXPECT_EQ(R, MatchR);1010
1011// Test no match on ULE.1012EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))1013.match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R)));1014
1015// Test no match on ULT.1016EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))1017.match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R)));1018
1019// Test inverted selects. Note, that this "inverts" the ordering, e.g.:1020// %cmp = fcmp ule L, R1021// %max = select %cmp R, L1022// Given L == NaN1023// the above is expanded to %cmp == true ==> %max = R1024// which is true for OrdFMax, not UnordFMax, so test that:1025
1026// [UO]LE with inverted select.1027EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))1028.match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), R, L)));1029EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))1030.match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), R, L)));1031EXPECT_EQ(L, MatchL);1032EXPECT_EQ(R, MatchR);1033
1034// [UO]LT with inverted select.1035EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))1036.match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), R, L)));1037EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))1038.match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), R, L)));1039EXPECT_EQ(L, MatchL);1040EXPECT_EQ(R, MatchR);1041}
1042
1043TEST_F(PatternMatchTest, OverflowingBinOps) {1044Value *L = IRB.getInt32(1);1045Value *R = IRB.getInt32(2);1046Value *MatchL, *MatchR;1047
1048EXPECT_TRUE(1049m_NSWAdd(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWAdd(L, R)));1050EXPECT_EQ(L, MatchL);1051EXPECT_EQ(R, MatchR);1052MatchL = MatchR = nullptr;1053EXPECT_TRUE(1054m_NSWSub(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWSub(L, R)));1055EXPECT_EQ(L, MatchL);1056EXPECT_EQ(R, MatchR);1057MatchL = MatchR = nullptr;1058EXPECT_TRUE(1059m_NSWMul(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWMul(L, R)));1060EXPECT_EQ(L, MatchL);1061EXPECT_EQ(R, MatchR);1062MatchL = MatchR = nullptr;1063EXPECT_TRUE(m_NSWShl(m_Value(MatchL), m_Value(MatchR)).match(1064IRB.CreateShl(L, R, "", /* NUW */ false, /* NSW */ true)));1065EXPECT_EQ(L, MatchL);1066EXPECT_EQ(R, MatchR);1067
1068EXPECT_TRUE(1069m_NUWAdd(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWAdd(L, R)));1070EXPECT_EQ(L, MatchL);1071EXPECT_EQ(R, MatchR);1072MatchL = MatchR = nullptr;1073
1074EXPECT_TRUE(1075m_c_NUWAdd(m_Specific(L), m_Specific(R)).match(IRB.CreateNUWAdd(L, R)));1076EXPECT_TRUE(1077m_c_NUWAdd(m_Specific(R), m_Specific(L)).match(IRB.CreateNUWAdd(L, R)));1078EXPECT_FALSE(1079m_c_NUWAdd(m_Specific(R), m_ZeroInt()).match(IRB.CreateNUWAdd(L, R)));1080EXPECT_FALSE(1081m_NUWAdd(m_Specific(R), m_Specific(L)).match(IRB.CreateNUWAdd(L, R)));1082
1083EXPECT_TRUE(1084m_NUWSub(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWSub(L, R)));1085EXPECT_EQ(L, MatchL);1086EXPECT_EQ(R, MatchR);1087MatchL = MatchR = nullptr;1088EXPECT_TRUE(1089m_NUWMul(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWMul(L, R)));1090EXPECT_EQ(L, MatchL);1091EXPECT_EQ(R, MatchR);1092MatchL = MatchR = nullptr;1093EXPECT_TRUE(m_NUWShl(m_Value(MatchL), m_Value(MatchR)).match(1094IRB.CreateShl(L, R, "", /* NUW */ true, /* NSW */ false)));1095EXPECT_EQ(L, MatchL);1096EXPECT_EQ(R, MatchR);1097
1098EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateAdd(L, R)));1099EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));1100EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateNSWSub(L, R)));1101EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateSub(L, R)));1102EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateNUWSub(L, R)));1103EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));1104EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateMul(L, R)));1105EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateNUWMul(L, R)));1106EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));1107EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(IRB.CreateShl(L, R)));1108EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(1109IRB.CreateShl(L, R, "", /* NUW */ true, /* NSW */ false)));1110EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));1111
1112EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateAdd(L, R)));1113EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));1114EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateNUWSub(L, R)));1115EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateSub(L, R)));1116EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateNSWSub(L, R)));1117EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));1118EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateMul(L, R)));1119EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateNSWMul(L, R)));1120EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));1121EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(IRB.CreateShl(L, R)));1122EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(1123IRB.CreateShl(L, R, "", /* NUW */ false, /* NSW */ true)));1124EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));1125}
1126
1127TEST_F(PatternMatchTest, LoadStoreOps) {1128// Create this load/store sequence:1129//1130// %p = alloca i32*1131// %0 = load i32*, i32** %p1132// store i32 42, i32* %01133
1134Value *Alloca = IRB.CreateAlloca(IRB.getInt32Ty());1135Value *LoadInst = IRB.CreateLoad(IRB.getInt32Ty(), Alloca);1136Value *FourtyTwo = IRB.getInt32(42);1137Value *StoreInst = IRB.CreateStore(FourtyTwo, Alloca);1138Value *MatchLoad, *MatchStoreVal, *MatchStorePointer;1139
1140EXPECT_TRUE(m_Load(m_Value(MatchLoad)).match(LoadInst));1141EXPECT_EQ(Alloca, MatchLoad);1142
1143EXPECT_TRUE(m_Load(m_Specific(Alloca)).match(LoadInst));1144
1145EXPECT_FALSE(m_Load(m_Value(MatchLoad)).match(Alloca));1146
1147EXPECT_TRUE(m_Store(m_Value(MatchStoreVal), m_Value(MatchStorePointer))1148.match(StoreInst));1149EXPECT_EQ(FourtyTwo, MatchStoreVal);1150EXPECT_EQ(Alloca, MatchStorePointer);1151
1152EXPECT_FALSE(m_Store(m_Value(MatchStoreVal), m_Value(MatchStorePointer))1153.match(Alloca));1154
1155EXPECT_TRUE(m_Store(m_SpecificInt(42), m_Specific(Alloca))1156.match(StoreInst));1157EXPECT_FALSE(m_Store(m_SpecificInt(42), m_Specific(FourtyTwo))1158.match(StoreInst));1159EXPECT_FALSE(m_Store(m_SpecificInt(43), m_Specific(Alloca))1160.match(StoreInst));1161}
1162
1163TEST_F(PatternMatchTest, VectorOps) {1164// Build up small tree of vector operations1165//1166// Val = 0 + 11167// Val2 = Val + 31168// VI1 = insertelement <2 x i8> undef, i8 1, i32 0 = <1, undef>1169// VI2 = insertelement <2 x i8> %VI1, i8 %Val2, i8 %Val = <1, 4>1170// VI3 = insertelement <2 x i8> %VI1, i8 %Val2, i32 1 = <1, 4>1171// VI4 = insertelement <2 x i8> %VI1, i8 2, i8 %Val = <1, 2>1172//1173// SI1 = shufflevector <2 x i8> %VI1, <2 x i8> undef, zeroinitializer1174// SI2 = shufflevector <2 x i8> %VI3, <2 x i8> %VI4, <2 x i8> <i8 0, i8 2>1175// SI3 = shufflevector <2 x i8> %VI3, <2 x i8> undef, zeroinitializer1176// SI4 = shufflevector <2 x i8> %VI4, <2 x i8> undef, zeroinitializer1177//1178// SP1 = VectorSplat(2, i8 2)1179// SP2 = VectorSplat(2, i8 %Val)1180Type *VecTy = FixedVectorType::get(IRB.getInt8Ty(), 2);1181Type *i32 = IRB.getInt32Ty();1182Type *i32VecTy = FixedVectorType::get(i32, 2);1183
1184Value *Val = IRB.CreateAdd(IRB.getInt8(0), IRB.getInt8(1));1185Value *Val2 = IRB.CreateAdd(Val, IRB.getInt8(3));1186
1187SmallVector<Constant *, 2> VecElemIdxs;1188VecElemIdxs.push_back(ConstantInt::get(i32, 0));1189VecElemIdxs.push_back(ConstantInt::get(i32, 2));1190auto *IdxVec = ConstantVector::get(VecElemIdxs);1191
1192Value *VI1 = IRB.CreateInsertElement(VecTy, IRB.getInt8(1), (uint64_t)0);1193Value *VI2 = IRB.CreateInsertElement(VI1, Val2, Val);1194Value *VI3 = IRB.CreateInsertElement(VI1, Val2, (uint64_t)1);1195Value *VI4 = IRB.CreateInsertElement(VI1, IRB.getInt8(2), Val);1196
1197Value *EX1 = IRB.CreateExtractElement(VI4, Val);1198Value *EX2 = IRB.CreateExtractElement(VI4, (uint64_t)0);1199Value *EX3 = IRB.CreateExtractElement(IdxVec, (uint64_t)1);1200
1201Constant *Zero = ConstantAggregateZero::get(i32VecTy);1202SmallVector<int, 16> ZeroMask;1203ShuffleVectorInst::getShuffleMask(Zero, ZeroMask);1204
1205Value *SI1 = IRB.CreateShuffleVector(VI1, ZeroMask);1206Value *SI2 = IRB.CreateShuffleVector(VI3, VI4, IdxVec);1207Value *SI3 = IRB.CreateShuffleVector(VI3, ZeroMask);1208Value *SI4 = IRB.CreateShuffleVector(VI4, ZeroMask);1209
1210Value *SP1 = IRB.CreateVectorSplat(2, IRB.getInt8(2));1211Value *SP2 = IRB.CreateVectorSplat(2, Val);1212
1213Value *A = nullptr, *B = nullptr, *C = nullptr;1214
1215// Test matching insertelement1216EXPECT_TRUE(match(VI1, m_InsertElt(m_Value(), m_Value(), m_Value())));1217EXPECT_TRUE(1218match(VI1, m_InsertElt(m_Undef(), m_ConstantInt(), m_ConstantInt())));1219EXPECT_TRUE(1220match(VI1, m_InsertElt(m_Undef(), m_ConstantInt(), m_Zero())));1221EXPECT_TRUE(1222match(VI1, m_InsertElt(m_Undef(), m_SpecificInt(1), m_Zero())));1223EXPECT_TRUE(match(VI2, m_InsertElt(m_Value(), m_Value(), m_Value())));1224EXPECT_FALSE(1225match(VI2, m_InsertElt(m_Value(), m_Value(), m_ConstantInt())));1226EXPECT_FALSE(1227match(VI2, m_InsertElt(m_Value(), m_ConstantInt(), m_Value())));1228EXPECT_FALSE(match(VI2, m_InsertElt(m_Constant(), m_Value(), m_Value())));1229EXPECT_TRUE(match(VI3, m_InsertElt(m_Value(A), m_Value(B), m_Value(C))));1230EXPECT_TRUE(A == VI1);1231EXPECT_TRUE(B == Val2);1232EXPECT_TRUE(isa<ConstantInt>(C));1233A = B = C = nullptr; // reset1234
1235// Test matching extractelement1236EXPECT_TRUE(match(EX1, m_ExtractElt(m_Value(A), m_Value(B))));1237EXPECT_TRUE(A == VI4);1238EXPECT_TRUE(B == Val);1239A = B = C = nullptr; // reset1240EXPECT_FALSE(match(EX1, m_ExtractElt(m_Value(), m_ConstantInt())));1241EXPECT_TRUE(match(EX2, m_ExtractElt(m_Value(), m_ConstantInt())));1242EXPECT_TRUE(match(EX3, m_ExtractElt(m_Constant(), m_ConstantInt())));1243
1244// Test matching shufflevector1245ArrayRef<int> Mask;1246EXPECT_TRUE(match(SI1, m_Shuffle(m_Value(), m_Undef(), m_ZeroMask())));1247EXPECT_TRUE(match(SI2, m_Shuffle(m_Value(A), m_Value(B), m_Mask(Mask))));1248EXPECT_TRUE(A == VI3);1249EXPECT_TRUE(B == VI4);1250A = B = C = nullptr; // reset1251
1252// Test matching the vector splat pattern1253EXPECT_TRUE(match(1254SI1,1255m_Shuffle(m_InsertElt(m_Undef(), m_SpecificInt(1), m_Zero()),1256m_Undef(), m_ZeroMask())));1257EXPECT_FALSE(match(1258SI3, m_Shuffle(m_InsertElt(m_Undef(), m_Value(), m_Zero()),1259m_Undef(), m_ZeroMask())));1260EXPECT_FALSE(match(1261SI4, m_Shuffle(m_InsertElt(m_Undef(), m_Value(), m_Zero()),1262m_Undef(), m_ZeroMask())));1263EXPECT_TRUE(match(1264SP1,1265m_Shuffle(m_InsertElt(m_Undef(), m_SpecificInt(2), m_Zero()),1266m_Undef(), m_ZeroMask())));1267EXPECT_TRUE(match(1268SP2, m_Shuffle(m_InsertElt(m_Undef(), m_Value(A), m_Zero()),1269m_Undef(), m_ZeroMask())));1270EXPECT_TRUE(A == Val);1271}
1272
1273TEST_F(PatternMatchTest, UndefPoisonMix) {1274Type *ScalarTy = IRB.getInt8Ty();1275ArrayType *ArrTy = ArrayType::get(ScalarTy, 2);1276StructType *StTy = StructType::get(ScalarTy, ScalarTy);1277StructType *StTy2 = StructType::get(ScalarTy, StTy);1278StructType *StTy3 = StructType::get(StTy, ScalarTy);1279Constant *Zero = ConstantInt::getNullValue(ScalarTy);1280UndefValue *U = UndefValue::get(ScalarTy);1281UndefValue *P = PoisonValue::get(ScalarTy);1282
1283EXPECT_TRUE(match(ConstantVector::get({U, P}), m_Undef()));1284EXPECT_TRUE(match(ConstantVector::get({P, U}), m_Undef()));1285
1286EXPECT_TRUE(match(ConstantArray::get(ArrTy, {U, P}), m_Undef()));1287EXPECT_TRUE(match(ConstantArray::get(ArrTy, {P, U}), m_Undef()));1288
1289auto *UP = ConstantStruct::get(StTy, {U, P});1290EXPECT_TRUE(match(ConstantStruct::get(StTy2, {U, UP}), m_Undef()));1291EXPECT_TRUE(match(ConstantStruct::get(StTy2, {P, UP}), m_Undef()));1292EXPECT_TRUE(match(ConstantStruct::get(StTy3, {UP, U}), m_Undef()));1293EXPECT_TRUE(match(ConstantStruct::get(StTy3, {UP, P}), m_Undef()));1294
1295EXPECT_FALSE(match(ConstantStruct::get(StTy, {U, Zero}), m_Undef()));1296EXPECT_FALSE(match(ConstantStruct::get(StTy, {Zero, U}), m_Undef()));1297EXPECT_FALSE(match(ConstantStruct::get(StTy, {P, Zero}), m_Undef()));1298EXPECT_FALSE(match(ConstantStruct::get(StTy, {Zero, P}), m_Undef()));1299
1300EXPECT_FALSE(match(ConstantStruct::get(StTy2, {Zero, UP}), m_Undef()));1301EXPECT_FALSE(match(ConstantStruct::get(StTy3, {UP, Zero}), m_Undef()));1302}
1303
1304TEST_F(PatternMatchTest, VectorUndefInt) {1305Type *ScalarTy = IRB.getInt8Ty();1306Type *VectorTy = FixedVectorType::get(ScalarTy, 4);1307Constant *ScalarUndef = UndefValue::get(ScalarTy);1308Constant *VectorUndef = UndefValue::get(VectorTy);1309Constant *ScalarPoison = PoisonValue::get(ScalarTy);1310Constant *VectorPoison = PoisonValue::get(VectorTy);1311Constant *ScalarZero = Constant::getNullValue(ScalarTy);1312Constant *VectorZero = Constant::getNullValue(VectorTy);1313
1314SmallVector<Constant *, 4> Elems;1315Elems.push_back(ScalarUndef);1316Elems.push_back(ScalarZero);1317Elems.push_back(ScalarUndef);1318Elems.push_back(ScalarZero);1319Constant *VectorZeroUndef = ConstantVector::get(Elems);1320
1321SmallVector<Constant *, 4> Elems2;1322Elems2.push_back(ScalarPoison);1323Elems2.push_back(ScalarZero);1324Elems2.push_back(ScalarPoison);1325Elems2.push_back(ScalarZero);1326Constant *VectorZeroPoison = ConstantVector::get(Elems2);1327
1328EXPECT_TRUE(match(ScalarUndef, m_Undef()));1329EXPECT_TRUE(match(ScalarPoison, m_Undef()));1330EXPECT_TRUE(match(VectorUndef, m_Undef()));1331EXPECT_TRUE(match(VectorPoison, m_Undef()));1332EXPECT_FALSE(match(ScalarZero, m_Undef()));1333EXPECT_FALSE(match(VectorZero, m_Undef()));1334EXPECT_FALSE(match(VectorZeroUndef, m_Undef()));1335EXPECT_FALSE(match(VectorZeroPoison, m_Undef()));1336
1337EXPECT_FALSE(match(ScalarUndef, m_Zero()));1338EXPECT_FALSE(match(ScalarPoison, m_Zero()));1339EXPECT_FALSE(match(VectorUndef, m_Zero()));1340EXPECT_FALSE(match(VectorPoison, m_Zero()));1341EXPECT_FALSE(match(VectorZeroUndef, m_Zero()));1342EXPECT_TRUE(match(ScalarZero, m_Zero()));1343EXPECT_TRUE(match(VectorZero, m_Zero()));1344EXPECT_TRUE(match(VectorZeroPoison, m_Zero()));1345
1346const APInt *C;1347// Regardless of whether poison is allowed,1348// a fully undef/poison constant does not match.1349EXPECT_FALSE(match(ScalarUndef, m_APInt(C)));1350EXPECT_FALSE(match(ScalarUndef, m_APIntForbidPoison(C)));1351EXPECT_FALSE(match(ScalarUndef, m_APIntAllowPoison(C)));1352EXPECT_FALSE(match(VectorUndef, m_APInt(C)));1353EXPECT_FALSE(match(VectorUndef, m_APIntForbidPoison(C)));1354EXPECT_FALSE(match(VectorUndef, m_APIntAllowPoison(C)));1355EXPECT_FALSE(match(ScalarPoison, m_APInt(C)));1356EXPECT_FALSE(match(ScalarPoison, m_APIntForbidPoison(C)));1357EXPECT_FALSE(match(ScalarPoison, m_APIntAllowPoison(C)));1358EXPECT_FALSE(match(VectorPoison, m_APInt(C)));1359EXPECT_FALSE(match(VectorPoison, m_APIntForbidPoison(C)));1360EXPECT_FALSE(match(VectorPoison, m_APIntAllowPoison(C)));1361
1362// We can always match simple constants and simple splats.1363C = nullptr;1364EXPECT_TRUE(match(ScalarZero, m_APInt(C)));1365EXPECT_TRUE(C->isZero());1366C = nullptr;1367EXPECT_TRUE(match(ScalarZero, m_APIntForbidPoison(C)));1368EXPECT_TRUE(C->isZero());1369C = nullptr;1370EXPECT_TRUE(match(ScalarZero, m_APIntAllowPoison(C)));1371EXPECT_TRUE(C->isZero());1372C = nullptr;1373EXPECT_TRUE(match(VectorZero, m_APInt(C)));1374EXPECT_TRUE(C->isZero());1375C = nullptr;1376EXPECT_TRUE(match(VectorZero, m_APIntForbidPoison(C)));1377EXPECT_TRUE(C->isZero());1378C = nullptr;1379EXPECT_TRUE(match(VectorZero, m_APIntAllowPoison(C)));1380EXPECT_TRUE(C->isZero());1381
1382// Splats with undef are never allowed.1383// Whether splats with poison can be matched depends on the matcher.1384EXPECT_FALSE(match(VectorZeroUndef, m_APInt(C)));1385EXPECT_FALSE(match(VectorZeroUndef, m_APIntForbidPoison(C)));1386EXPECT_FALSE(match(VectorZeroUndef, m_APIntAllowPoison(C)));1387
1388EXPECT_FALSE(match(VectorZeroPoison, m_APInt(C)));1389EXPECT_FALSE(match(VectorZeroPoison, m_APIntForbidPoison(C)));1390C = nullptr;1391EXPECT_TRUE(match(VectorZeroPoison, m_APIntAllowPoison(C)));1392EXPECT_TRUE(C->isZero());1393}
1394
1395TEST_F(PatternMatchTest, VectorUndefFloat) {1396Type *ScalarTy = IRB.getFloatTy();1397Type *VectorTy = FixedVectorType::get(ScalarTy, 4);1398Constant *ScalarUndef = UndefValue::get(ScalarTy);1399Constant *VectorUndef = UndefValue::get(VectorTy);1400Constant *ScalarPoison = PoisonValue::get(ScalarTy);1401Constant *VectorPoison = PoisonValue::get(VectorTy);1402Constant *ScalarZero = Constant::getNullValue(ScalarTy);1403Constant *VectorZero = Constant::getNullValue(VectorTy);1404Constant *ScalarPosInf = ConstantFP::getInfinity(ScalarTy, false);1405Constant *ScalarNegInf = ConstantFP::getInfinity(ScalarTy, true);1406Constant *ScalarNaN = ConstantFP::getNaN(ScalarTy, true);1407
1408Constant *VectorZeroUndef =1409ConstantVector::get({ScalarUndef, ScalarZero, ScalarUndef, ScalarZero});1410
1411Constant *VectorZeroPoison =1412ConstantVector::get({ScalarPoison, ScalarZero, ScalarPoison, ScalarZero});1413
1414Constant *VectorInfUndef = ConstantVector::get(1415{ScalarPosInf, ScalarNegInf, ScalarUndef, ScalarPosInf});1416
1417Constant *VectorInfPoison = ConstantVector::get(1418{ScalarPosInf, ScalarNegInf, ScalarPoison, ScalarPosInf});1419
1420Constant *VectorNaNUndef =1421ConstantVector::get({ScalarUndef, ScalarNaN, ScalarNaN, ScalarNaN});1422
1423Constant *VectorNaNPoison =1424ConstantVector::get({ScalarPoison, ScalarNaN, ScalarNaN, ScalarNaN});1425
1426EXPECT_TRUE(match(ScalarUndef, m_Undef()));1427EXPECT_TRUE(match(VectorUndef, m_Undef()));1428EXPECT_TRUE(match(ScalarPoison, m_Undef()));1429EXPECT_TRUE(match(VectorPoison, m_Undef()));1430EXPECT_FALSE(match(ScalarZero, m_Undef()));1431EXPECT_FALSE(match(VectorZero, m_Undef()));1432EXPECT_FALSE(match(VectorZeroUndef, m_Undef()));1433EXPECT_FALSE(match(VectorInfUndef, m_Undef()));1434EXPECT_FALSE(match(VectorNaNUndef, m_Undef()));1435EXPECT_FALSE(match(VectorZeroPoison, m_Undef()));1436EXPECT_FALSE(match(VectorInfPoison, m_Undef()));1437EXPECT_FALSE(match(VectorNaNPoison, m_Undef()));1438
1439EXPECT_FALSE(match(ScalarUndef, m_AnyZeroFP()));1440EXPECT_FALSE(match(VectorUndef, m_AnyZeroFP()));1441EXPECT_FALSE(match(ScalarPoison, m_AnyZeroFP()));1442EXPECT_FALSE(match(VectorPoison, m_AnyZeroFP()));1443EXPECT_TRUE(match(ScalarZero, m_AnyZeroFP()));1444EXPECT_TRUE(match(VectorZero, m_AnyZeroFP()));1445EXPECT_FALSE(match(VectorZeroUndef, m_AnyZeroFP()));1446EXPECT_FALSE(match(VectorInfUndef, m_AnyZeroFP()));1447EXPECT_FALSE(match(VectorNaNUndef, m_AnyZeroFP()));1448EXPECT_TRUE(match(VectorZeroPoison, m_AnyZeroFP()));1449EXPECT_FALSE(match(VectorInfPoison, m_AnyZeroFP()));1450EXPECT_FALSE(match(VectorNaNPoison, m_AnyZeroFP()));1451
1452EXPECT_FALSE(match(ScalarUndef, m_NaN()));1453EXPECT_FALSE(match(VectorUndef, m_NaN()));1454EXPECT_FALSE(match(VectorZeroUndef, m_NaN()));1455EXPECT_FALSE(match(ScalarPoison, m_NaN()));1456EXPECT_FALSE(match(VectorPoison, m_NaN()));1457EXPECT_FALSE(match(VectorZeroPoison, m_NaN()));1458EXPECT_FALSE(match(ScalarPosInf, m_NaN()));1459EXPECT_FALSE(match(ScalarNegInf, m_NaN()));1460EXPECT_TRUE(match(ScalarNaN, m_NaN()));1461EXPECT_FALSE(match(VectorInfUndef, m_NaN()));1462EXPECT_FALSE(match(VectorNaNUndef, m_NaN()));1463EXPECT_FALSE(match(VectorInfPoison, m_NaN()));1464EXPECT_TRUE(match(VectorNaNPoison, m_NaN()));1465
1466EXPECT_FALSE(match(ScalarUndef, m_NonNaN()));1467EXPECT_FALSE(match(VectorUndef, m_NonNaN()));1468EXPECT_FALSE(match(VectorZeroUndef, m_NonNaN()));1469EXPECT_FALSE(match(ScalarPoison, m_NonNaN()));1470EXPECT_FALSE(match(VectorPoison, m_NonNaN()));1471EXPECT_TRUE(match(VectorZeroPoison, m_NonNaN()));1472EXPECT_TRUE(match(ScalarPosInf, m_NonNaN()));1473EXPECT_TRUE(match(ScalarNegInf, m_NonNaN()));1474EXPECT_FALSE(match(ScalarNaN, m_NonNaN()));1475EXPECT_FALSE(match(VectorInfUndef, m_NonNaN()));1476EXPECT_FALSE(match(VectorNaNUndef, m_NonNaN()));1477EXPECT_TRUE(match(VectorInfPoison, m_NonNaN()));1478EXPECT_FALSE(match(VectorNaNPoison, m_NonNaN()));1479
1480EXPECT_FALSE(match(ScalarUndef, m_Inf()));1481EXPECT_FALSE(match(VectorUndef, m_Inf()));1482EXPECT_FALSE(match(VectorZeroUndef, m_Inf()));1483EXPECT_FALSE(match(ScalarPoison, m_Inf()));1484EXPECT_FALSE(match(VectorPoison, m_Inf()));1485EXPECT_FALSE(match(VectorZeroPoison, m_Inf()));1486EXPECT_TRUE(match(ScalarPosInf, m_Inf()));1487EXPECT_TRUE(match(ScalarNegInf, m_Inf()));1488EXPECT_FALSE(match(ScalarNaN, m_Inf()));1489EXPECT_FALSE(match(VectorInfUndef, m_Inf()));1490EXPECT_FALSE(match(VectorNaNUndef, m_Inf()));1491EXPECT_TRUE(match(VectorInfPoison, m_Inf()));1492EXPECT_FALSE(match(VectorNaNPoison, m_Inf()));1493
1494EXPECT_FALSE(match(ScalarUndef, m_NonInf()));1495EXPECT_FALSE(match(VectorUndef, m_NonInf()));1496EXPECT_FALSE(match(VectorZeroUndef, m_NonInf()));1497EXPECT_FALSE(match(ScalarPoison, m_NonInf()));1498EXPECT_FALSE(match(VectorPoison, m_NonInf()));1499EXPECT_TRUE(match(VectorZeroPoison, m_NonInf()));1500EXPECT_FALSE(match(ScalarPosInf, m_NonInf()));1501EXPECT_FALSE(match(ScalarNegInf, m_NonInf()));1502EXPECT_TRUE(match(ScalarNaN, m_NonInf()));1503EXPECT_FALSE(match(VectorInfUndef, m_NonInf()));1504EXPECT_FALSE(match(VectorNaNUndef, m_NonInf()));1505EXPECT_FALSE(match(VectorInfPoison, m_NonInf()));1506EXPECT_TRUE(match(VectorNaNPoison, m_NonInf()));1507
1508EXPECT_FALSE(match(ScalarUndef, m_Finite()));1509EXPECT_FALSE(match(VectorUndef, m_Finite()));1510EXPECT_FALSE(match(VectorZeroUndef, m_Finite()));1511EXPECT_FALSE(match(ScalarPoison, m_Finite()));1512EXPECT_FALSE(match(VectorPoison, m_Finite()));1513EXPECT_TRUE(match(VectorZeroPoison, m_Finite()));1514EXPECT_FALSE(match(ScalarPosInf, m_Finite()));1515EXPECT_FALSE(match(ScalarNegInf, m_Finite()));1516EXPECT_FALSE(match(ScalarNaN, m_Finite()));1517EXPECT_FALSE(match(VectorInfUndef, m_Finite()));1518EXPECT_FALSE(match(VectorNaNUndef, m_Finite()));1519EXPECT_FALSE(match(VectorInfPoison, m_Finite()));1520EXPECT_FALSE(match(VectorNaNPoison, m_Finite()));1521
1522auto CheckTrue = [](const APFloat &) { return true; };1523EXPECT_FALSE(match(VectorZeroUndef, m_CheckedFp(CheckTrue)));1524EXPECT_TRUE(match(VectorZeroPoison, m_CheckedFp(CheckTrue)));1525EXPECT_TRUE(match(ScalarPosInf, m_CheckedFp(CheckTrue)));1526EXPECT_TRUE(match(ScalarNegInf, m_CheckedFp(CheckTrue)));1527EXPECT_TRUE(match(ScalarNaN, m_CheckedFp(CheckTrue)));1528EXPECT_FALSE(match(VectorInfUndef, m_CheckedFp(CheckTrue)));1529EXPECT_TRUE(match(VectorInfPoison, m_CheckedFp(CheckTrue)));1530EXPECT_FALSE(match(VectorNaNUndef, m_CheckedFp(CheckTrue)));1531EXPECT_TRUE(match(VectorNaNPoison, m_CheckedFp(CheckTrue)));1532
1533auto CheckFalse = [](const APFloat &) { return false; };1534EXPECT_FALSE(match(VectorZeroUndef, m_CheckedFp(CheckFalse)));1535EXPECT_FALSE(match(VectorZeroPoison, m_CheckedFp(CheckFalse)));1536EXPECT_FALSE(match(ScalarPosInf, m_CheckedFp(CheckFalse)));1537EXPECT_FALSE(match(ScalarNegInf, m_CheckedFp(CheckFalse)));1538EXPECT_FALSE(match(ScalarNaN, m_CheckedFp(CheckFalse)));1539EXPECT_FALSE(match(VectorInfUndef, m_CheckedFp(CheckFalse)));1540EXPECT_FALSE(match(VectorInfPoison, m_CheckedFp(CheckFalse)));1541EXPECT_FALSE(match(VectorNaNUndef, m_CheckedFp(CheckFalse)));1542EXPECT_FALSE(match(VectorNaNPoison, m_CheckedFp(CheckFalse)));1543
1544auto CheckNonNaN = [](const APFloat &C) { return !C.isNaN(); };1545EXPECT_FALSE(match(VectorZeroUndef, m_CheckedFp(CheckNonNaN)));1546EXPECT_TRUE(match(VectorZeroPoison, m_CheckedFp(CheckNonNaN)));1547EXPECT_TRUE(match(ScalarPosInf, m_CheckedFp(CheckNonNaN)));1548EXPECT_TRUE(match(ScalarNegInf, m_CheckedFp(CheckNonNaN)));1549EXPECT_FALSE(match(ScalarNaN, m_CheckedFp(CheckNonNaN)));1550EXPECT_FALSE(match(VectorInfUndef, m_CheckedFp(CheckNonNaN)));1551EXPECT_TRUE(match(VectorInfPoison, m_CheckedFp(CheckNonNaN)));1552EXPECT_FALSE(match(VectorNaNUndef, m_CheckedFp(CheckNonNaN)));1553EXPECT_FALSE(match(VectorNaNPoison, m_CheckedFp(CheckNonNaN)));1554
1555const APFloat *C;1556const Constant *CC;1557// Regardless of whether poison is allowed,1558// a fully undef/poison constant does not match.1559EXPECT_FALSE(match(ScalarUndef, m_APFloat(C)));1560EXPECT_FALSE(match(ScalarUndef, m_APFloatForbidPoison(C)));1561EXPECT_FALSE(match(ScalarUndef, m_APFloatAllowPoison(C)));1562EXPECT_FALSE(match(ScalarUndef, m_CheckedFp(CC, CheckTrue)));1563EXPECT_FALSE(match(VectorUndef, m_APFloat(C)));1564EXPECT_FALSE(match(VectorUndef, m_APFloatForbidPoison(C)));1565EXPECT_FALSE(match(VectorUndef, m_APFloatAllowPoison(C)));1566EXPECT_FALSE(match(VectorUndef, m_CheckedFp(CC, CheckTrue)));1567EXPECT_FALSE(match(ScalarPoison, m_APFloat(C)));1568EXPECT_FALSE(match(ScalarPoison, m_APFloatForbidPoison(C)));1569EXPECT_FALSE(match(ScalarPoison, m_APFloatAllowPoison(C)));1570EXPECT_FALSE(match(ScalarPoison, m_CheckedFp(CC, CheckTrue)));1571EXPECT_FALSE(match(VectorPoison, m_APFloat(C)));1572EXPECT_FALSE(match(VectorPoison, m_APFloatForbidPoison(C)));1573EXPECT_FALSE(match(VectorPoison, m_APFloatAllowPoison(C)));1574EXPECT_FALSE(match(VectorPoison, m_CheckedFp(CC, CheckTrue)));1575
1576// We can always match simple constants and simple splats.1577C = nullptr;1578EXPECT_TRUE(match(ScalarZero, m_APFloat(C)));1579EXPECT_TRUE(C->isZero());1580C = nullptr;1581EXPECT_TRUE(match(ScalarZero, m_APFloatForbidPoison(C)));1582EXPECT_TRUE(C->isZero());1583C = nullptr;1584EXPECT_TRUE(match(ScalarZero, m_APFloatAllowPoison(C)));1585EXPECT_TRUE(C->isZero());1586C = nullptr;1587EXPECT_TRUE(match(VectorZero, m_APFloat(C)));1588EXPECT_TRUE(C->isZero());1589C = nullptr;1590EXPECT_TRUE(match(VectorZero, m_APFloatForbidPoison(C)));1591EXPECT_TRUE(C->isZero());1592C = nullptr;1593EXPECT_TRUE(match(VectorZero, m_APFloatAllowPoison(C)));1594EXPECT_TRUE(C->isZero());1595
1596CC = nullptr;1597EXPECT_TRUE(match(VectorZero, m_CheckedFp(CC, CheckTrue)));1598EXPECT_TRUE(CC->isNullValue());1599CC = nullptr;1600EXPECT_TRUE(match(VectorZero, m_CheckedFp(CC, CheckNonNaN)));1601EXPECT_TRUE(CC->isNullValue());1602
1603// Splats with undef are never allowed.1604// Whether splats with poison can be matched depends on the matcher.1605EXPECT_FALSE(match(VectorZeroUndef, m_APFloat(C)));1606EXPECT_FALSE(match(VectorZeroUndef, m_APFloatForbidPoison(C)));1607EXPECT_FALSE(match(VectorZeroUndef, m_APFloatAllowPoison(C)));1608EXPECT_FALSE(match(VectorZeroUndef, m_Finite(C)));1609
1610EXPECT_FALSE(match(VectorZeroPoison, m_APFloat(C)));1611EXPECT_FALSE(match(VectorZeroPoison, m_APFloatForbidPoison(C)));1612C = nullptr;1613EXPECT_TRUE(match(VectorZeroPoison, m_APFloatAllowPoison(C)));1614EXPECT_TRUE(C->isZero());1615C = nullptr;1616EXPECT_TRUE(match(VectorZeroPoison, m_Finite(C)));1617EXPECT_TRUE(C->isZero());1618EXPECT_FALSE(match(VectorZeroPoison, m_APFloat(C)));1619EXPECT_FALSE(match(VectorZeroPoison, m_APFloatForbidPoison(C)));1620C = nullptr;1621EXPECT_TRUE(match(VectorZeroPoison, m_APFloatAllowPoison(C)));1622EXPECT_TRUE(C->isZero());1623C = nullptr;1624EXPECT_TRUE(match(VectorZeroPoison, m_Finite(C)));1625EXPECT_TRUE(C->isZero());1626CC = nullptr;1627C = nullptr;1628EXPECT_TRUE(match(VectorZeroPoison, m_CheckedFp(CC, CheckTrue)));1629EXPECT_NE(CC, nullptr);1630EXPECT_TRUE(match(CC, m_APFloatAllowPoison(C)));1631EXPECT_TRUE(C->isZero());1632CC = nullptr;1633C = nullptr;1634EXPECT_TRUE(match(VectorZeroPoison, m_CheckedFp(CC, CheckNonNaN)));1635EXPECT_NE(CC, nullptr);1636EXPECT_TRUE(match(CC, m_APFloatAllowPoison(C)));1637EXPECT_TRUE(C->isZero());1638}
1639
1640TEST_F(PatternMatchTest, FloatingPointFNeg) {1641Type *FltTy = IRB.getFloatTy();1642Value *One = ConstantFP::get(FltTy, 1.0);1643Value *Z = ConstantFP::get(FltTy, 0.0);1644Value *NZ = ConstantFP::get(FltTy, -0.0);1645Value *V = IRB.CreateFNeg(One);1646Value *V1 = IRB.CreateFSub(NZ, One);1647Value *V2 = IRB.CreateFSub(Z, One);1648Value *V3 = IRB.CreateFAdd(NZ, One);1649Value *Match;1650
1651// Test FNeg(1.0)1652EXPECT_TRUE(match(V, m_FNeg(m_Value(Match))));1653EXPECT_EQ(One, Match);1654
1655// Test FSub(-0.0, 1.0)1656EXPECT_TRUE(match(V1, m_FNeg(m_Value(Match))));1657EXPECT_EQ(One, Match);1658
1659// Test FSub(0.0, 1.0)1660EXPECT_FALSE(match(V2, m_FNeg(m_Value(Match))));1661cast<Instruction>(V2)->setHasNoSignedZeros(true);1662EXPECT_TRUE(match(V2, m_FNeg(m_Value(Match))));1663EXPECT_EQ(One, Match);1664
1665// Test FAdd(-0.0, 1.0)1666EXPECT_FALSE(match(V3, m_FNeg(m_Value(Match))));1667}
1668
1669TEST_F(PatternMatchTest, CondBranchTest) {1670BasicBlock *TrueBB = BasicBlock::Create(Ctx, "TrueBB", F);1671BasicBlock *FalseBB = BasicBlock::Create(Ctx, "FalseBB", F);1672Value *Br1 = IRB.CreateCondBr(IRB.getTrue(), TrueBB, FalseBB);1673
1674EXPECT_TRUE(match(Br1, m_Br(m_Value(), m_BasicBlock(), m_BasicBlock())));1675
1676BasicBlock *A, *B;1677EXPECT_TRUE(match(Br1, m_Br(m_Value(), m_BasicBlock(A), m_BasicBlock(B))));1678EXPECT_EQ(TrueBB, A);1679EXPECT_EQ(FalseBB, B);1680
1681EXPECT_FALSE(1682match(Br1, m_Br(m_Value(), m_SpecificBB(FalseBB), m_BasicBlock())));1683EXPECT_FALSE(1684match(Br1, m_Br(m_Value(), m_BasicBlock(), m_SpecificBB(TrueBB))));1685EXPECT_FALSE(1686match(Br1, m_Br(m_Value(), m_SpecificBB(FalseBB), m_BasicBlock(TrueBB))));1687EXPECT_TRUE(1688match(Br1, m_Br(m_Value(), m_SpecificBB(TrueBB), m_BasicBlock(FalseBB))));1689
1690// Check we can use m_Deferred with branches.1691EXPECT_FALSE(match(Br1, m_Br(m_Value(), m_BasicBlock(A), m_Deferred(A))));1692Value *Br2 = IRB.CreateCondBr(IRB.getTrue(), TrueBB, TrueBB);1693A = nullptr;1694EXPECT_TRUE(match(Br2, m_Br(m_Value(), m_BasicBlock(A), m_Deferred(A))));1695}
1696
1697TEST_F(PatternMatchTest, WithOverflowInst) {1698Value *Add = IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow,1699IRB.getInt32(0), IRB.getInt32(0));1700Value *Add0 = IRB.CreateExtractValue(Add, 0);1701Value *Add1 = IRB.CreateExtractValue(Add, 1);1702
1703EXPECT_TRUE(match(Add0, m_ExtractValue<0>(m_Value())));1704EXPECT_FALSE(match(Add0, m_ExtractValue<1>(m_Value())));1705EXPECT_FALSE(match(Add1, m_ExtractValue<0>(m_Value())));1706EXPECT_TRUE(match(Add1, m_ExtractValue<1>(m_Value())));1707EXPECT_FALSE(match(Add, m_ExtractValue<1>(m_Value())));1708EXPECT_FALSE(match(Add, m_ExtractValue<1>(m_Value())));1709
1710WithOverflowInst *WOI;1711EXPECT_FALSE(match(Add0, m_WithOverflowInst(WOI)));1712EXPECT_FALSE(match(Add1, m_WithOverflowInst(WOI)));1713EXPECT_TRUE(match(Add, m_WithOverflowInst(WOI)));1714
1715EXPECT_TRUE(match(Add0, m_ExtractValue<0>(m_WithOverflowInst(WOI))));1716EXPECT_EQ(Add, WOI);1717EXPECT_TRUE(match(Add1, m_ExtractValue<1>(m_WithOverflowInst(WOI))));1718EXPECT_EQ(Add, WOI);1719}
1720
1721TEST_F(PatternMatchTest, MinMaxIntrinsics) {1722Type *Ty = IRB.getInt32Ty();1723Value *L = ConstantInt::get(Ty, 1);1724Value *R = ConstantInt::get(Ty, 2);1725Value *MatchL, *MatchR;1726
1727// Check for intrinsic ID match and capture of operands.1728EXPECT_TRUE(m_SMax(m_Value(MatchL), m_Value(MatchR))1729.match(IRB.CreateBinaryIntrinsic(Intrinsic::smax, L, R)));1730EXPECT_EQ(L, MatchL);1731EXPECT_EQ(R, MatchR);1732
1733EXPECT_TRUE(m_SMin(m_Value(MatchL), m_Value(MatchR))1734.match(IRB.CreateBinaryIntrinsic(Intrinsic::smin, L, R)));1735EXPECT_EQ(L, MatchL);1736EXPECT_EQ(R, MatchR);1737
1738EXPECT_TRUE(m_UMax(m_Value(MatchL), m_Value(MatchR))1739.match(IRB.CreateBinaryIntrinsic(Intrinsic::umax, L, R)));1740EXPECT_EQ(L, MatchL);1741EXPECT_EQ(R, MatchR);1742
1743EXPECT_TRUE(m_UMin(m_Value(MatchL), m_Value(MatchR))1744.match(IRB.CreateBinaryIntrinsic(Intrinsic::umin, L, R)));1745EXPECT_EQ(L, MatchL);1746EXPECT_EQ(R, MatchR);1747
1748// Check for intrinsic ID mismatch.1749EXPECT_FALSE(m_SMax(m_Value(MatchL), m_Value(MatchR))1750.match(IRB.CreateBinaryIntrinsic(Intrinsic::smin, L, R)));1751EXPECT_FALSE(m_SMin(m_Value(MatchL), m_Value(MatchR))1752.match(IRB.CreateBinaryIntrinsic(Intrinsic::umax, L, R)));1753EXPECT_FALSE(m_UMax(m_Value(MatchL), m_Value(MatchR))1754.match(IRB.CreateBinaryIntrinsic(Intrinsic::umin, L, R)));1755EXPECT_FALSE(m_UMin(m_Value(MatchL), m_Value(MatchR))1756.match(IRB.CreateBinaryIntrinsic(Intrinsic::smax, L, R)));1757}
1758
1759TEST_F(PatternMatchTest, IntrinsicMatcher) {1760Value *Name = IRB.CreateAlloca(IRB.getInt8Ty());1761Value *Hash = IRB.getInt64(0);1762Value *Num = IRB.getInt32(1);1763Value *Index = IRB.getInt32(2);1764Value *Step = IRB.getInt64(3);1765
1766Value *Ops[] = {Name, Hash, Num, Index, Step};1767Module *M = BB->getParent()->getParent();1768Function *TheFn =1769Intrinsic::getDeclaration(M, Intrinsic::instrprof_increment_step);1770
1771Value *Intrinsic5 = CallInst::Create(TheFn, Ops, "", BB);1772
1773// Match without capturing.1774EXPECT_TRUE(match(1775Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>(1776m_Value(), m_Value(), m_Value(), m_Value(), m_Value())));1777EXPECT_FALSE(match(1778Intrinsic5, m_Intrinsic<Intrinsic::memmove>(1779m_Value(), m_Value(), m_Value(), m_Value(), m_Value())));1780
1781// Match with capturing.1782Value *Arg1 = nullptr;1783Value *Arg2 = nullptr;1784Value *Arg3 = nullptr;1785Value *Arg4 = nullptr;1786Value *Arg5 = nullptr;1787EXPECT_TRUE(1788match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>(1789m_Value(Arg1), m_Value(Arg2), m_Value(Arg3),1790m_Value(Arg4), m_Value(Arg5))));1791EXPECT_EQ(Arg1, Name);1792EXPECT_EQ(Arg2, Hash);1793EXPECT_EQ(Arg3, Num);1794EXPECT_EQ(Arg4, Index);1795EXPECT_EQ(Arg5, Step);1796
1797// Match specific second argument.1798EXPECT_TRUE(1799match(Intrinsic5,1800m_Intrinsic<Intrinsic::instrprof_increment_step>(1801m_Value(), m_SpecificInt(0), m_Value(), m_Value(), m_Value())));1802EXPECT_FALSE(1803match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>(1804m_Value(), m_SpecificInt(10), m_Value(), m_Value(),1805m_Value())));1806
1807// Match specific third argument.1808EXPECT_TRUE(1809match(Intrinsic5,1810m_Intrinsic<Intrinsic::instrprof_increment_step>(1811m_Value(), m_Value(), m_SpecificInt(1), m_Value(), m_Value())));1812EXPECT_FALSE(1813match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>(1814m_Value(), m_Value(), m_SpecificInt(10), m_Value(),1815m_Value())));1816
1817// Match specific fourth argument.1818EXPECT_TRUE(1819match(Intrinsic5,1820m_Intrinsic<Intrinsic::instrprof_increment_step>(1821m_Value(), m_Value(), m_Value(), m_SpecificInt(2), m_Value())));1822EXPECT_FALSE(1823match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>(1824m_Value(), m_Value(), m_Value(), m_SpecificInt(10),1825m_Value())));1826
1827// Match specific fifth argument.1828EXPECT_TRUE(1829match(Intrinsic5,1830m_Intrinsic<Intrinsic::instrprof_increment_step>(1831m_Value(), m_Value(), m_Value(), m_Value(), m_SpecificInt(3))));1832EXPECT_FALSE(1833match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>(1834m_Value(), m_Value(), m_Value(), m_Value(),1835m_SpecificInt(10))));1836}
1837
1838namespace {1839
1840struct is_unsigned_zero_pred {1841bool isValue(const APInt &C) { return C.isZero(); }1842};1843
1844struct is_float_zero_pred {1845bool isValue(const APFloat &C) { return C.isZero(); }1846};1847
1848template <typename T> struct always_true_pred {1849bool isValue(const T &) { return true; }1850};1851
1852template <typename T> struct always_false_pred {1853bool isValue(const T &) { return false; }1854};1855
1856struct is_unsigned_max_pred {1857bool isValue(const APInt &C) { return C.isMaxValue(); }1858};1859
1860struct is_float_nan_pred {1861bool isValue(const APFloat &C) { return C.isNaN(); }1862};1863
1864} // namespace1865
1866TEST_F(PatternMatchTest, ConstantPredicateType) {1867
1868// Scalar integer1869APInt U32Max = APInt::getAllOnes(32);1870APInt U32Zero = APInt::getZero(32);1871APInt U32DeadBeef(32, 0xDEADBEEF);1872
1873Type *U32Ty = Type::getInt32Ty(Ctx);1874
1875Constant *CU32Max = Constant::getIntegerValue(U32Ty, U32Max);1876Constant *CU32Zero = Constant::getIntegerValue(U32Ty, U32Zero);1877Constant *CU32DeadBeef = Constant::getIntegerValue(U32Ty, U32DeadBeef);1878
1879EXPECT_TRUE(match(CU32Max, cst_pred_ty<is_unsigned_max_pred>()));1880EXPECT_FALSE(match(CU32Max, cst_pred_ty<is_unsigned_zero_pred>()));1881EXPECT_TRUE(match(CU32Max, cst_pred_ty<always_true_pred<APInt>>()));1882EXPECT_FALSE(match(CU32Max, cst_pred_ty<always_false_pred<APInt>>()));1883
1884EXPECT_FALSE(match(CU32Zero, cst_pred_ty<is_unsigned_max_pred>()));1885EXPECT_TRUE(match(CU32Zero, cst_pred_ty<is_unsigned_zero_pred>()));1886EXPECT_TRUE(match(CU32Zero, cst_pred_ty<always_true_pred<APInt>>()));1887EXPECT_FALSE(match(CU32Zero, cst_pred_ty<always_false_pred<APInt>>()));1888
1889EXPECT_FALSE(match(CU32DeadBeef, cst_pred_ty<is_unsigned_max_pred>()));1890EXPECT_FALSE(match(CU32DeadBeef, cst_pred_ty<is_unsigned_zero_pred>()));1891EXPECT_TRUE(match(CU32DeadBeef, cst_pred_ty<always_true_pred<APInt>>()));1892EXPECT_FALSE(match(CU32DeadBeef, cst_pred_ty<always_false_pred<APInt>>()));1893
1894// Scalar float1895APFloat F32NaN = APFloat::getNaN(APFloat::IEEEsingle());1896APFloat F32Zero = APFloat::getZero(APFloat::IEEEsingle());1897APFloat F32Pi(3.14f);1898
1899Type *F32Ty = Type::getFloatTy(Ctx);1900
1901Constant *CF32NaN = ConstantFP::get(F32Ty, F32NaN);1902Constant *CF32Zero = ConstantFP::get(F32Ty, F32Zero);1903Constant *CF32Pi = ConstantFP::get(F32Ty, F32Pi);1904
1905EXPECT_TRUE(match(CF32NaN, cstfp_pred_ty<is_float_nan_pred>()));1906EXPECT_FALSE(match(CF32NaN, cstfp_pred_ty<is_float_zero_pred>()));1907EXPECT_TRUE(match(CF32NaN, cstfp_pred_ty<always_true_pred<APFloat>>()));1908EXPECT_FALSE(match(CF32NaN, cstfp_pred_ty<always_false_pred<APFloat>>()));1909
1910EXPECT_FALSE(match(CF32Zero, cstfp_pred_ty<is_float_nan_pred>()));1911EXPECT_TRUE(match(CF32Zero, cstfp_pred_ty<is_float_zero_pred>()));1912EXPECT_TRUE(match(CF32Zero, cstfp_pred_ty<always_true_pred<APFloat>>()));1913EXPECT_FALSE(match(CF32Zero, cstfp_pred_ty<always_false_pred<APFloat>>()));1914
1915EXPECT_FALSE(match(CF32Pi, cstfp_pred_ty<is_float_nan_pred>()));1916EXPECT_FALSE(match(CF32Pi, cstfp_pred_ty<is_float_zero_pred>()));1917EXPECT_TRUE(match(CF32Pi, cstfp_pred_ty<always_true_pred<APFloat>>()));1918EXPECT_FALSE(match(CF32Pi, cstfp_pred_ty<always_false_pred<APFloat>>()));1919
1920auto FixedEC = ElementCount::getFixed(4);1921auto ScalableEC = ElementCount::getScalable(4);1922
1923// Vector splat1924
1925for (auto EC : {FixedEC, ScalableEC}) {1926// integer1927
1928Constant *CSplatU32Max = ConstantVector::getSplat(EC, CU32Max);1929Constant *CSplatU32Zero = ConstantVector::getSplat(EC, CU32Zero);1930Constant *CSplatU32DeadBeef = ConstantVector::getSplat(EC, CU32DeadBeef);1931
1932EXPECT_TRUE(match(CSplatU32Max, cst_pred_ty<is_unsigned_max_pred>()));1933EXPECT_FALSE(match(CSplatU32Max, cst_pred_ty<is_unsigned_zero_pred>()));1934EXPECT_TRUE(match(CSplatU32Max, cst_pred_ty<always_true_pred<APInt>>()));1935EXPECT_FALSE(match(CSplatU32Max, cst_pred_ty<always_false_pred<APInt>>()));1936
1937EXPECT_FALSE(match(CSplatU32Zero, cst_pred_ty<is_unsigned_max_pred>()));1938EXPECT_TRUE(match(CSplatU32Zero, cst_pred_ty<is_unsigned_zero_pred>()));1939EXPECT_TRUE(match(CSplatU32Zero, cst_pred_ty<always_true_pred<APInt>>()));1940EXPECT_FALSE(match(CSplatU32Zero, cst_pred_ty<always_false_pred<APInt>>()));1941
1942EXPECT_FALSE(match(CSplatU32DeadBeef, cst_pred_ty<is_unsigned_max_pred>()));1943EXPECT_FALSE(1944match(CSplatU32DeadBeef, cst_pred_ty<is_unsigned_zero_pred>()));1945EXPECT_TRUE(1946match(CSplatU32DeadBeef, cst_pred_ty<always_true_pred<APInt>>()));1947EXPECT_FALSE(1948match(CSplatU32DeadBeef, cst_pred_ty<always_false_pred<APInt>>()));1949
1950// float1951
1952Constant *CSplatF32NaN = ConstantVector::getSplat(EC, CF32NaN);1953Constant *CSplatF32Zero = ConstantVector::getSplat(EC, CF32Zero);1954Constant *CSplatF32Pi = ConstantVector::getSplat(EC, CF32Pi);1955
1956EXPECT_TRUE(match(CSplatF32NaN, cstfp_pred_ty<is_float_nan_pred>()));1957EXPECT_FALSE(match(CSplatF32NaN, cstfp_pred_ty<is_float_zero_pred>()));1958EXPECT_TRUE(1959match(CSplatF32NaN, cstfp_pred_ty<always_true_pred<APFloat>>()));1960EXPECT_FALSE(1961match(CSplatF32NaN, cstfp_pred_ty<always_false_pred<APFloat>>()));1962
1963EXPECT_FALSE(match(CSplatF32Zero, cstfp_pred_ty<is_float_nan_pred>()));1964EXPECT_TRUE(match(CSplatF32Zero, cstfp_pred_ty<is_float_zero_pred>()));1965EXPECT_TRUE(1966match(CSplatF32Zero, cstfp_pred_ty<always_true_pred<APFloat>>()));1967EXPECT_FALSE(1968match(CSplatF32Zero, cstfp_pred_ty<always_false_pred<APFloat>>()));1969
1970EXPECT_FALSE(match(CSplatF32Pi, cstfp_pred_ty<is_float_nan_pred>()));1971EXPECT_FALSE(match(CSplatF32Pi, cstfp_pred_ty<is_float_zero_pred>()));1972EXPECT_TRUE(match(CSplatF32Pi, cstfp_pred_ty<always_true_pred<APFloat>>()));1973EXPECT_FALSE(1974match(CSplatF32Pi, cstfp_pred_ty<always_false_pred<APFloat>>()));1975}1976
1977// Int arbitrary vector1978
1979Constant *CMixedU32 = ConstantVector::get({CU32Max, CU32Zero, CU32DeadBeef});1980Constant *CU32Undef = UndefValue::get(U32Ty);1981Constant *CU32Poison = PoisonValue::get(U32Ty);1982Constant *CU32MaxWithUndef =1983ConstantVector::get({CU32Undef, CU32Max, CU32Undef});1984Constant *CU32MaxWithPoison =1985ConstantVector::get({CU32Poison, CU32Max, CU32Poison});1986
1987EXPECT_FALSE(match(CMixedU32, cst_pred_ty<is_unsigned_max_pred>()));1988EXPECT_FALSE(match(CMixedU32, cst_pred_ty<is_unsigned_zero_pred>()));1989EXPECT_TRUE(match(CMixedU32, cst_pred_ty<always_true_pred<APInt>>()));1990EXPECT_FALSE(match(CMixedU32, cst_pred_ty<always_false_pred<APInt>>()));1991
1992EXPECT_FALSE(match(CU32MaxWithUndef, cst_pred_ty<is_unsigned_max_pred>()));1993EXPECT_FALSE(match(CU32MaxWithUndef, cst_pred_ty<is_unsigned_zero_pred>()));1994EXPECT_FALSE(match(CU32MaxWithUndef, cst_pred_ty<always_true_pred<APInt>>()));1995EXPECT_FALSE(1996match(CU32MaxWithUndef, cst_pred_ty<always_false_pred<APInt>>()));1997
1998EXPECT_TRUE(match(CU32MaxWithPoison, cst_pred_ty<is_unsigned_max_pred>()));1999EXPECT_FALSE(match(CU32MaxWithPoison, cst_pred_ty<is_unsigned_zero_pred>()));2000EXPECT_TRUE(match(CU32MaxWithPoison, cst_pred_ty<always_true_pred<APInt>>()));2001EXPECT_FALSE(2002match(CU32MaxWithPoison, cst_pred_ty<always_false_pred<APInt>>()));2003
2004// Float arbitrary vector2005
2006Constant *CMixedF32 = ConstantVector::get({CF32NaN, CF32Zero, CF32Pi});2007Constant *CF32Undef = UndefValue::get(F32Ty);2008Constant *CF32Poison = PoisonValue::get(F32Ty);2009Constant *CF32NaNWithUndef =2010ConstantVector::get({CF32Undef, CF32NaN, CF32Undef});2011Constant *CF32NaNWithPoison =2012ConstantVector::get({CF32Poison, CF32NaN, CF32Poison});2013
2014EXPECT_FALSE(match(CMixedF32, cstfp_pred_ty<is_float_nan_pred>()));2015EXPECT_FALSE(match(CMixedF32, cstfp_pred_ty<is_float_zero_pred>()));2016EXPECT_TRUE(match(CMixedF32, cstfp_pred_ty<always_true_pred<APFloat>>()));2017EXPECT_FALSE(match(CMixedF32, cstfp_pred_ty<always_false_pred<APFloat>>()));2018
2019EXPECT_FALSE(match(CF32NaNWithUndef, cstfp_pred_ty<is_float_nan_pred>()));2020EXPECT_FALSE(match(CF32NaNWithUndef, cstfp_pred_ty<is_float_zero_pred>()));2021EXPECT_FALSE(2022match(CF32NaNWithUndef, cstfp_pred_ty<always_true_pred<APFloat>>()));2023EXPECT_FALSE(2024match(CF32NaNWithUndef, cstfp_pred_ty<always_false_pred<APFloat>>()));2025
2026EXPECT_TRUE(match(CF32NaNWithPoison, cstfp_pred_ty<is_float_nan_pred>()));2027EXPECT_FALSE(match(CF32NaNWithPoison, cstfp_pred_ty<is_float_zero_pred>()));2028EXPECT_TRUE(2029match(CF32NaNWithPoison, cstfp_pred_ty<always_true_pred<APFloat>>()));2030EXPECT_FALSE(2031match(CF32NaNWithPoison, cstfp_pred_ty<always_false_pred<APFloat>>()));2032}
2033
2034TEST_F(PatternMatchTest, InsertValue) {2035Type *StructTy = StructType::create(IRB.getContext(),2036{IRB.getInt32Ty(), IRB.getInt64Ty()});2037Value *Ins0 =2038IRB.CreateInsertValue(UndefValue::get(StructTy), IRB.getInt32(20), 0);2039Value *Ins1 = IRB.CreateInsertValue(Ins0, IRB.getInt64(90), 1);2040
2041EXPECT_TRUE(match(Ins0, m_InsertValue<0>(m_Value(), m_Value())));2042EXPECT_FALSE(match(Ins0, m_InsertValue<1>(m_Value(), m_Value())));2043EXPECT_FALSE(match(Ins1, m_InsertValue<0>(m_Value(), m_Value())));2044EXPECT_TRUE(match(Ins1, m_InsertValue<1>(m_Value(), m_Value())));2045
2046EXPECT_TRUE(match(Ins0, m_InsertValue<0>(m_Undef(), m_SpecificInt(20))));2047EXPECT_FALSE(match(Ins0, m_InsertValue<0>(m_Undef(), m_SpecificInt(0))));2048
2049EXPECT_TRUE(2050match(Ins1, m_InsertValue<1>(m_InsertValue<0>(m_Value(), m_Value()),2051m_SpecificInt(90))));2052EXPECT_FALSE(match(IRB.getInt64(99), m_InsertValue<0>(m_Value(), m_Value())));2053}
2054
2055TEST_F(PatternMatchTest, LogicalSelects) {2056Value *Alloca = IRB.CreateAlloca(IRB.getInt1Ty());2057Value *X = IRB.CreateLoad(IRB.getInt1Ty(), Alloca);2058Value *Y = IRB.CreateLoad(IRB.getInt1Ty(), Alloca);2059Constant *T = IRB.getInt1(true);2060Constant *F = IRB.getInt1(false);2061Value *And = IRB.CreateSelect(X, Y, F);2062Value *Or = IRB.CreateSelect(X, T, Y);2063
2064// Logical and:2065// Check basic no-capture logic - opcode and constant must match.2066EXPECT_TRUE(match(And, m_LogicalAnd(m_Value(), m_Value())));2067EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Value(), m_Value())));2068EXPECT_FALSE(match(And, m_LogicalOr(m_Value(), m_Value())));2069EXPECT_FALSE(match(And, m_c_LogicalOr(m_Value(), m_Value())));2070
2071// Check with captures.2072EXPECT_TRUE(match(And, m_LogicalAnd(m_Specific(X), m_Value())));2073EXPECT_TRUE(match(And, m_LogicalAnd(m_Value(), m_Specific(Y))));2074EXPECT_TRUE(match(And, m_LogicalAnd(m_Specific(X), m_Specific(Y))));2075
2076EXPECT_FALSE(match(And, m_LogicalAnd(m_Specific(Y), m_Value())));2077EXPECT_FALSE(match(And, m_LogicalAnd(m_Value(), m_Specific(X))));2078EXPECT_FALSE(match(And, m_LogicalAnd(m_Specific(Y), m_Specific(X))));2079
2080EXPECT_FALSE(match(And, m_LogicalAnd(m_Specific(X), m_Specific(X))));2081EXPECT_FALSE(match(And, m_LogicalAnd(m_Specific(Y), m_Specific(Y))));2082
2083// Check captures for commutative match.2084EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Specific(X), m_Value())));2085EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Value(), m_Specific(Y))));2086EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Specific(X), m_Specific(Y))));2087
2088EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Specific(Y), m_Value())));2089EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Value(), m_Specific(X))));2090EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Specific(Y), m_Specific(X))));2091
2092EXPECT_FALSE(match(And, m_c_LogicalAnd(m_Specific(X), m_Specific(X))));2093EXPECT_FALSE(match(And, m_c_LogicalAnd(m_Specific(Y), m_Specific(Y))));2094
2095// Logical or:2096// Check basic no-capture logic - opcode and constant must match.2097EXPECT_TRUE(match(Or, m_LogicalOr(m_Value(), m_Value())));2098EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Value(), m_Value())));2099EXPECT_FALSE(match(Or, m_LogicalAnd(m_Value(), m_Value())));2100EXPECT_FALSE(match(Or, m_c_LogicalAnd(m_Value(), m_Value())));2101
2102// Check with captures.2103EXPECT_TRUE(match(Or, m_LogicalOr(m_Specific(X), m_Value())));2104EXPECT_TRUE(match(Or, m_LogicalOr(m_Value(), m_Specific(Y))));2105EXPECT_TRUE(match(Or, m_LogicalOr(m_Specific(X), m_Specific(Y))));2106
2107EXPECT_FALSE(match(Or, m_LogicalOr(m_Specific(Y), m_Value())));2108EXPECT_FALSE(match(Or, m_LogicalOr(m_Value(), m_Specific(X))));2109EXPECT_FALSE(match(Or, m_LogicalOr(m_Specific(Y), m_Specific(X))));2110
2111EXPECT_FALSE(match(Or, m_LogicalOr(m_Specific(X), m_Specific(X))));2112EXPECT_FALSE(match(Or, m_LogicalOr(m_Specific(Y), m_Specific(Y))));2113
2114// Check captures for commutative match.2115EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Specific(X), m_Value())));2116EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Value(), m_Specific(Y))));2117EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Specific(X), m_Specific(Y))));2118
2119EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Specific(Y), m_Value())));2120EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Value(), m_Specific(X))));2121EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Specific(Y), m_Specific(X))));2122
2123EXPECT_FALSE(match(Or, m_c_LogicalOr(m_Specific(X), m_Specific(X))));2124EXPECT_FALSE(match(Or, m_c_LogicalOr(m_Specific(Y), m_Specific(Y))));2125}
2126
2127TEST_F(PatternMatchTest, VectorLogicalSelects) {2128Type *i1 = IRB.getInt1Ty();2129Type *v3i1 = FixedVectorType::get(i1, 3);2130
2131Value *Alloca = IRB.CreateAlloca(i1);2132Value *AllocaVec = IRB.CreateAlloca(v3i1);2133Value *Scalar = IRB.CreateLoad(i1, Alloca);2134Value *Vector = IRB.CreateLoad(v3i1, AllocaVec);2135Constant *F = Constant::getNullValue(v3i1);2136Constant *T = Constant::getAllOnesValue(v3i1);2137
2138// select <3 x i1> Vector, <3 x i1> Vector, <3 x i1> <i1 0, i1 0, i1 0>2139Value *VecAnd = IRB.CreateSelect(Vector, Vector, F);2140
2141// select i1 Scalar, <3 x i1> Vector, <3 x i1> <i1 0, i1 0, i1 0>2142Value *MixedTypeAnd = IRB.CreateSelect(Scalar, Vector, F);2143
2144// select <3 x i1> Vector, <3 x i1> <i1 1, i1 1, i1 1>, <3 x i1> Vector2145Value *VecOr = IRB.CreateSelect(Vector, T, Vector);2146
2147// select i1 Scalar, <3 x i1> <i1 1, i1 1, i1 1>, <3 x i1> Vector2148Value *MixedTypeOr = IRB.CreateSelect(Scalar, T, Vector);2149
2150// We allow matching a real vector logical select,2151// but not a scalar select of vector bools.2152EXPECT_TRUE(match(VecAnd, m_LogicalAnd(m_Value(), m_Value())));2153EXPECT_FALSE(match(MixedTypeAnd, m_LogicalAnd(m_Value(), m_Value())));2154EXPECT_TRUE(match(VecOr, m_LogicalOr(m_Value(), m_Value())));2155EXPECT_FALSE(match(MixedTypeOr, m_LogicalOr(m_Value(), m_Value())));2156}
2157
2158TEST_F(PatternMatchTest, VScale) {2159DataLayout DL = M->getDataLayout();2160
2161Type *VecTy = ScalableVectorType::get(IRB.getInt8Ty(), 1);2162Value *NullPtrVec =2163Constant::getNullValue(PointerType::getUnqual(VecTy->getContext()));2164Value *GEP = IRB.CreateGEP(VecTy, NullPtrVec, IRB.getInt64(1));2165Value *PtrToInt = IRB.CreatePtrToInt(GEP, DL.getIntPtrType(GEP->getType()));2166EXPECT_TRUE(match(PtrToInt, m_VScale()));2167
2168Type *VecTy2 = ScalableVectorType::get(IRB.getInt8Ty(), 2);2169Value *NullPtrVec2 =2170Constant::getNullValue(PointerType::getUnqual(VecTy2->getContext()));2171Value *GEP2 = IRB.CreateGEP(VecTy, NullPtrVec2, IRB.getInt64(1));2172Value *PtrToInt2 =2173IRB.CreatePtrToInt(GEP2, DL.getIntPtrType(GEP2->getType()));2174EXPECT_TRUE(match(PtrToInt2, m_VScale()));2175}
2176
2177TEST_F(PatternMatchTest, NotForbidPoison) {2178Type *ScalarTy = IRB.getInt8Ty();2179Type *VectorTy = FixedVectorType::get(ScalarTy, 3);2180Constant *ScalarUndef = UndefValue::get(ScalarTy);2181Constant *ScalarPoison = PoisonValue::get(ScalarTy);2182Constant *ScalarOnes = Constant::getAllOnesValue(ScalarTy);2183Constant *VectorZero = Constant::getNullValue(VectorTy);2184Constant *VectorOnes = Constant::getAllOnesValue(VectorTy);2185
2186SmallVector<Constant *, 3> MixedElemsUndef;2187MixedElemsUndef.push_back(ScalarOnes);2188MixedElemsUndef.push_back(ScalarOnes);2189MixedElemsUndef.push_back(ScalarUndef);2190Constant *VectorMixedUndef = ConstantVector::get(MixedElemsUndef);2191
2192SmallVector<Constant *, 3> MixedElemsPoison;2193MixedElemsPoison.push_back(ScalarOnes);2194MixedElemsPoison.push_back(ScalarOnes);2195MixedElemsPoison.push_back(ScalarPoison);2196Constant *VectorMixedPoison = ConstantVector::get(MixedElemsPoison);2197
2198Value *Not = IRB.CreateXor(VectorZero, VectorOnes);2199Value *X;2200EXPECT_TRUE(match(Not, m_Not(m_Value(X))));2201EXPECT_TRUE(match(X, m_Zero()));2202X = nullptr;2203EXPECT_TRUE(match(Not, m_NotForbidPoison(m_Value(X))));2204EXPECT_TRUE(match(X, m_Zero()));2205
2206Value *NotCommute = IRB.CreateXor(VectorOnes, VectorZero);2207Value *Y;2208EXPECT_TRUE(match(NotCommute, m_Not(m_Value(Y))));2209EXPECT_TRUE(match(Y, m_Zero()));2210Y = nullptr;2211EXPECT_TRUE(match(NotCommute, m_NotForbidPoison(m_Value(Y))));2212EXPECT_TRUE(match(Y, m_Zero()));2213
2214Value *NotWithUndefs = IRB.CreateXor(VectorZero, VectorMixedUndef);2215EXPECT_FALSE(match(NotWithUndefs, m_Not(m_Value())));2216EXPECT_FALSE(match(NotWithUndefs, m_NotForbidPoison(m_Value())));2217
2218Value *NotWithPoisons = IRB.CreateXor(VectorZero, VectorMixedPoison);2219EXPECT_TRUE(match(NotWithPoisons, m_Not(m_Value())));2220EXPECT_FALSE(match(NotWithPoisons, m_NotForbidPoison(m_Value())));2221
2222Value *NotWithUndefsCommute = IRB.CreateXor(VectorMixedUndef, VectorZero);2223EXPECT_FALSE(match(NotWithUndefsCommute, m_Not(m_Value())));2224EXPECT_FALSE(match(NotWithUndefsCommute, m_NotForbidPoison(m_Value())));2225
2226Value *NotWithPoisonsCommute = IRB.CreateXor(VectorMixedPoison, VectorZero);2227EXPECT_TRUE(match(NotWithPoisonsCommute, m_Not(m_Value())));2228EXPECT_FALSE(match(NotWithPoisonsCommute, m_NotForbidPoison(m_Value())));2229}
2230
2231template <typename T> struct MutableConstTest : PatternMatchTest { };2232
2233typedef ::testing::Types<std::tuple<Value*, Instruction*>,2234std::tuple<const Value*, const Instruction *>>2235MutableConstTestTypes;2236TYPED_TEST_SUITE(MutableConstTest, MutableConstTestTypes, );2237
2238TYPED_TEST(MutableConstTest, ICmp) {2239auto &IRB = PatternMatchTest::IRB;2240
2241typedef std::tuple_element_t<0, TypeParam> ValueType;2242typedef std::tuple_element_t<1, TypeParam> InstructionType;2243
2244Value *L = IRB.getInt32(1);2245Value *R = IRB.getInt32(2);2246ICmpInst::Predicate Pred = ICmpInst::ICMP_UGT;2247
2248ValueType MatchL;2249ValueType MatchR;2250ICmpInst::Predicate MatchPred;2251
2252EXPECT_TRUE(m_ICmp(MatchPred, m_Value(MatchL), m_Value(MatchR))2253.match((InstructionType)IRB.CreateICmp(Pred, L, R)));2254EXPECT_EQ(L, MatchL);2255EXPECT_EQ(R, MatchR);2256}
2257
2258TEST_F(PatternMatchTest, ConstExpr) {2259Constant *G =2260M->getOrInsertGlobal("dummy", PointerType::getUnqual(IRB.getInt32Ty()));2261Constant *S = ConstantExpr::getPtrToInt(G, IRB.getInt32Ty());2262Type *VecTy = FixedVectorType::get(IRB.getInt32Ty(), 2);2263PoisonValue *P = PoisonValue::get(VecTy);2264Constant *V = ConstantExpr::getInsertElement(P, S, IRB.getInt32(0));2265
2266// The match succeeds on a constant that is a constant expression itself2267// or a constant that contains a constant expression.2268EXPECT_TRUE(match(S, m_ConstantExpr()));2269EXPECT_TRUE(match(V, m_ConstantExpr()));2270}
2271
2272TEST_F(PatternMatchTest, PtrAdd) {2273Type *PtrTy = PointerType::getUnqual(Ctx);2274Type *IdxTy = Type::getInt64Ty(Ctx);2275Constant *Null = Constant::getNullValue(PtrTy);2276Constant *Offset = ConstantInt::get(IdxTy, 42);2277Value *PtrAdd = IRB.CreatePtrAdd(Null, Offset);2278Value *OtherGEP = IRB.CreateGEP(IdxTy, Null, Offset);2279Value *PtrAddConst =2280ConstantExpr::getGetElementPtr(Type::getInt8Ty(Ctx), Null, Offset);2281
2282Value *A, *B;2283EXPECT_TRUE(match(PtrAdd, m_PtrAdd(m_Value(A), m_Value(B))));2284EXPECT_EQ(A, Null);2285EXPECT_EQ(B, Offset);2286
2287EXPECT_TRUE(match(PtrAddConst, m_PtrAdd(m_Value(A), m_Value(B))));2288EXPECT_EQ(A, Null);2289EXPECT_EQ(B, Offset);2290
2291EXPECT_FALSE(match(OtherGEP, m_PtrAdd(m_Value(A), m_Value(B))));2292}
2293
2294} // anonymous namespace.2295