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